>サイトトップへ >このカテゴリの一覧へ

X 3012 : 1998(ISO/IES 13816 : 1997

(1) 

まえがき

この規格は,工業標準化法に基づいて,日本工業標準調査会の審議を経て,通商産業大臣が制定した日

本工業規格である。


X 3012 : 1998(ISO/IES 13816 : 1997

(1) 

目次

ページ

序文

1

1.  適用範囲,表記法及び適合性

1

1.1  適用範囲

1

1.2  引用規格

1

1.3  表記法

1

1.4  字句要素

3

1.4.1  分離記号

4

1.4.2  注釈

4

1.5  テキスト表現

4

1.6  予約語

5

1.7  定義

5

1.8  エラー

7

1.8.1  エラー指定

7

1.8.2  広範囲に使われるエラー

8

1.9  ISLISP プロセッサ及び ISLISP テキストの適合性

8

2.  クラス

8

2.1  メタクラス

9

2.2  定義済みクラス

10

2.3  標準クラス

11

2.3.1  スロット

11

2.3.2  クラスのインスタンスの生成

12

3.  有効範囲及び存在期間

12

3.1  静的原理

12

3.2  識別子の有効範囲

13

3.3  個別の有効範囲規則

13

3.4  存在期間

13

4.  評価形式及び評価

14

4.1  評価形式

14

4.2  関数適用形式

15

4.3  特殊形式

15

4.4  定義形式

15

4.5  マクロ形式

16

4.6  評価モデル

16

4.7  関数

16

4.8  定義演算子

19


X 3012 : 1998 (ISO/IEC 13816 : 1997)

目次

(2) 

5.  述語

20

5.1  真偽値

20

5.2  クラス述語

21

5.3  等価性

21

5.4  論理演算

23

6.  制御構造

25

6.1  定数

25

6.2  変数

25

6.3  動的変数

28

6.4  条件式

29

6.5  評価形式の逐次実行

31

6.6  繰返し

31

6.7  非局所的脱出

32

6.7.1  非局所的脱出の設定及び起動

32

6.7.2  非局所的脱出におけるデータ整合性の保証

36

7.  オブジェクト指向機能

37

7.1  クラスの定義

37

7.1.1  クラス優先度リストの決定

40

7.1.2  スロットのアクセス

40

7.1.3  スロット及びスロット任意機能の継承

41

7.2  包括関数

41

7.2.1  包括関数の定義

42

7.2.2  包括関数に対するメソッド定義

43

7.2.2.1  パラメタ特殊化指定及び修飾子に関する合致44 
7.2.2.2  包括関数のラムダリストとメソッドのパラメタ記述との合同44 
7.2.3  メソッドの継承

44

7.3  包括関数の呼出し

44

7.3.1  適用可能なメソッドの選択

44

7.3.2  適用可能メソッドの優先順位

45

7.3.3  メソッドの適用

45

7.3.3.1  単純メソッド組合せ 45

7.3.3.2  標準メソッド組合せ 45 
7.3.4  次メソッド及びその呼出し

47

7.4  オブジェクトの生成及び初期化

47

7.4.1  インスタンスの初期化

47

7.5  クラスに関する問合せ

48

8.  マクロ

49

9.  宣言及び型変換

50

10.  記号クラス

51

10.1  記号名

52


X 3012 : 1998 (ISO/IEC 13816 : 1997)

目次

(3) 

10.1.1  記号の表記

52

10.1.2  記号名における大小文字

52

10.1.3  nil 及び()

53

10.2  記号属性

53

10.3  名前なしの記号

53

11.  数値クラス

54

11.1  数値クラス

54

11.2  浮動小数点数クラス

60

11.3  整数クラス

62

12.  文字クラス

64

13.  リストクラス

66

13.1  コンス

66

13.2  空リストクラス

67

13.3  リスト操作

68

14.  配列

71

14.1  配列のクラス

71

14.2  一般配列

72

14.3  配列操作

72

15.  ベクタ

74

16.  文字列クラス

75

17.  列

77

18.  ストリームクラス

79

18.1  ファイルへのストリーム

81

18.2  その他のストリーム

82

19.  入出力

83

19.1  入力関数の引数についての共通事項

83

19.2  文字入出力

83

19.3  2 進入出力

87

20.  ファイル

88

21.  例外処理機能

89

21.1  例外状態

89

21.2  例外状態の通知及び扱い

89

21.2.1  例外通知に関する操作

90

21.2.2  例外処理に関する操作

91

21.3  例外オブジェクトに付随するデータ

91

21.3.1  算術エラー

91

21.3.2  定義域エラー

92

21.3.3  構文解析エラー

92

21.3.4  単純なエラー

92

21.3.5  ストリームエラー

92


X 3012 : 1998 (ISO/IEC 13816 : 1997)

目次

(4) 

21.3.6  未定義実体のエラー

93

21.4  エラー名

93

22.  その他の機能

95


日本工業規格

JIS

 X

3012

: 1998

 (

13816

: 1997

)

プログラム言語 ISLISP

Information technology

−Programming languages, their

environments and system software interfaces

Programming language ISLISP

序文  この規格は,1997 年に第 1 版として発行された ISO/IEC 13816, Information technology−Programming

languages, their environments and system software interfaces−Programming language ISLISP を翻訳し,技術的内

容を変更することなく作成した日本工業規格である。

なお,この規格で側線を施してある“参考”は,原国際規格にはない事項である。

1.

適用範囲,表記法及び適合性

1.1

適用範囲

a)

適用事項  この規格は,ISLISP プロセッサ及び ISLISP テキストに対する適合性要件を規定し,プロ

グラム言語 ISLISP の構文及び意味を規定する。

b)

適用外事項  この規格は,次の事項を規定しない。

1)

特定のデータ処理システムの能力又はプロセッサの能力を超える ISLISP テキストの大きさ又は複

雑さ,及び能力を超えた場合にとる動作。

2) ISLISP

プロセッサを実装できるデータ処理システムの最小要件。

3) ISLISP

テキストを実行準備する方法,及び実行のために準備された ISLISP テキストを起動する方

法。

4)

人が読むために刊行される ISLISP テキストの印刷上の表示。

5)

処理系が提供するかもしれない又は提供しないかもしれない拡張機能。

備考  この規格の対応国際規格を,次に示す。

ISO/IEC 13816 : 1997, Information technology

−Programming languages, their environments and

system software interfaces−Programming language ISLISP

1.2

引用規格  次に掲げる規格は,この規格に引用されることによって,この規格の一部を構成する。

この規格の制定時点では,次の規格が最新規格であるが,改正されることもあるので,この規格を使う当

事者は,最新版を適用できるかどうかを検討するのが望ましい。

ISO/IEC TR 10034 : 1990, Guidelines for the preparation of conformity clauses in programming

language standards

IEEE standard 754-1985, Standard for binary floating-point arithmetic

1.3

表記法  構文の概念及び意味の概念を明確に定義し,かつ,これらの概念を区別するために,この

規格では複数の記述抽象化のレベルを用いる。


2

X 3012 : 1998 (ISO/IEC 13816 : 1997)

ISLISP テキストの構成単位から,ISLISP データ構造の表現への対応が存在する。この規格では,テキス

トと,それに対応する ISLISP オブジェクト(データ構造)とを,同時に取り扱う。ISLISP のテキストは,

ISLISP のデータ構造の外部仕様とみなすことができる。これらの二つの表現を区別するために,異なる概

念を使用する。テキスト表現の場合は,テキストの構成要素(識別子,リテラル,複合形式など)を使用

する。一方,ISLISP のオブジェクトの場合は,オブジェクト(記号,リストなど)を使用する。

ISLISP テキストの構成要素を評価形式 (evaluation form) 又は単に形式 (form) と呼ぶ。評価形式は,識

別子,リテラル又は複合形式とする。複合形式は,関数適用形式,マクロ形式,特殊形式又は定義形式と

する。

識別子は,記号によって表現する。複合形式は,空でないリストによって表現する。リテラルは,記号

及びリストのいずれでも表現できない。したがって,リテラルは,識別子及び複合形式のいずれでもない。

例えば,数値はリテラルである。

オブジェクトは,

実行のために準備される  (prepared for execution)。これは,プログラム変換又はコンパ

イルを意味し,マクロ展開を含む。この規格は,検出しなければならない違反を定義するが,実行準備の

方法及びその結果は定義しない。実行準備が成功した場合は,その結果は,

実行 (execution) 可能な状態

となる。実行準備及びそれに続く評価が ISLISP の

評価モデル (evaluation model) を実装する。ここで,

“評

価”という用語を用いる理由は,ISLISP が式言語であるためである。すなわち,各評価形式は値をもち,

その評価形式を含む評価形式の値を計算するために使われる。この規格では,ある実体が実行のために準

備された結果を,

“実行準備された実体”と表すことがある。例えば,

“実行準備された評価形式”,“実行

準備された特殊形式”などと表す。

例  “cond 特殊形式”は,実行のために準備されて“実行準備された cond”となる。

実行例におけるメタ記号“⇒”は,実際の評価の結果を示す。例えば,

(+ 3 4)  ⇒7

メタ記号“→”は,与えられたパターンをもつ評価形式を評価した際の,結果のクラスを示す。例えば,

(+ i

1

 i

2

)  →<integer>

評価形式のパターン

(通常は,

関数名又は特殊演算子である定数部分によって定義される。

に対しては,

そのパターンに一致するすべての評価形式を評価した結果が属するクラスを“→”で示す。

同値な評価形式のパターン又は評価形式を,

“≡”によって関係付ける。

評価形式のパターンに関しては,次の表記法を使用する。

(f-name argument*)  →結果のクラス

f kind

この表記法では,イタリック体の単語は,非終端記号(パターン変数)を表す。f-name は,常に終端記

号であり,特定の関数名,特殊演算子,定義演算子又は包括関数名のいずれかとする。

この表記法で下線を付けた用語(例えば,定義形式における name)は,評価されない式であることを意

味する。評価形式が評価される場合とされない場合があるとき(例えば,if における then-form 及び eles- 

form

)は,そのことを規定に明記する。

クラス名は,一律に<class-name>と表記する。例えば,<list>は,通常“リストクラス”と呼ばれるクラ

スの名前である。

パターン変数に関しては,次の表記法を用いる。

term

  term が一つ以上現れることを意味する。

term*  term

が 0 個以上現れることを意味する。


3

X 3012 : 1998 (ISO/IEC 13816 : 1997)

[term]  term が高々一つしか現れないことを意味する。すなわち,term が省略可能で

あることを意味する。

{term

1

 term

2

...}  各 term をまとめることを意味する。

term

1

|term

2

|...  いずれかの term が一つだけ現れることを意味する。

評価形式の引数がクラスの制約をもつ場合は,その評価形式を規定するために次の名前を使用する。

arrayarray

1

,...array

j

,... <basic-array>

conscons

1

,...cons

j

,... <cons>

listlist

1

,...list

j

,... <list>

objobj

1

,...obj

j

,... <object>

sequencesequence

1

,...sequence

j

,... <basic-vector>又は<list>(17.参照)

streamstream

1

,...stream

j

,... <stream>

stringstring

1

,...string

j

,... <string>

charchar

1

char

j

,... <character>

functionfunction

1

,...function

j

,... <function>

classclass

1

,...class

j

,... <class>

symbolsymbol

1

,...symbol

j

,... <symbol>

xx

1

,...x

j

,... <number>

zz

1

,...z

j

,... <integer>

この規格では,特にことわらない限り,次の方式を使用する。

-p

述語(

“真偽値関数”と呼ばれることがある)の名前は,通常-p で終わる。通常,すべて

のクラス<name>は特性関数をもつ。特性関数の名前は,name がハイフンを含む場合は

name-p

(例えば,generic-function-p)とし,ハイフンを含まない場合は namep(例えば,

symbolp)とする。ただし,名前が “p” で終わる関数のすべてが述語とは限らない。

create-

通常,組込みクラス<name>は生成関数をもち,その名前は create-name とする。

def

これは,定義演算子の接頭語として使用する。

set-

この規格では,set-nameという名前の関数はすべて,場所に対する書込み関数であり,name

という名前の,対応する読出し関数が存在する。

この言語におけるどのような実体に対しても,名詞句  “entity-kind name”  は,name によって表される

entity-kind

という種類の実体を意味する。例えば,名詞句“関数 name

“定数 name”及び“クラス name

は,name によって表される関数,定数及びクラスをそれぞれ意味する。

1.4

字句要素  ISLISP テキストは,字句要素によって構成する。字句要素は,次の文字によって構成す

る(12.参照)

      A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

      a b c d e f g h i j k l m n o p q r s t u v w x y z

      0 1 2 3 4 5 6 7 8 9 + - < > / * & = . ? _ ! $ % : @ [ ] ^ { }

 #

これ以外の文字は,処理系定義とする。

次の文字は,それ自体で字句要素とする(8.及び 13.1 参照)

(  )  ‘  ,  ’

次の文字の組は,それ自体で字句要素とする(4.78.及び 14.1 参照)

。ここで,は 10 進数の並びとす

る。


4

X 3012 : 1998 (ISO/IEC 13816 : 1997)

#’ #( , @ #B #b #O #o #X #x #nA #na

記号(10.参照)

,数値(11.参照)

,文字(12.参照)及び文字列(16.参照)は,字句要素とする。

\(単一エスケープ)及び|(多重エスケープ)は,特殊文字とする。これらは,ある種の字句要素(識

別子,文字列リテラルなど)の中に現れてもよい。

これ以外の字句要素は,区切り記号によって分離する。区切り記号は,分離記号及び次の文字とする。

(  )  ‘  ,  ’

区切り記号が文字列(16.参照)の中,一対の多重エスケープ文字(10.参照)で囲まれた部分,又は#\

の直後の文字として現れた場合には,区切り記号としての効果は無効とする。

参考  JIS X 0201 では,文字

はオーバライン (7/14) に対応し,文字\は円記号 (5/12) に対応してい

る。

1.4.1

分離記号  分離記号は,空白,コメント,復帰改行及び処理系定義の文字(例えば,タブ)とする。

分離記号は意味をもたず,別の分離記号で置き換えても,ISLISP テキストの意味を変えることはない。

1.4.2

注釈  セミコロン (;) は,注釈開始 (comment begin) のための文字とする。すなわち,セミコロン

と,それに続く行末までの文字が注釈となる。

#|で始まり,|#で終わる文字の並びは注釈とする。これらの注釈を入れ子にしてもよい。

注釈は,分離記号であり,字句要素の中に現れることはできない。

1.5

テキスト表現  オブジェクトのテキスト表現は,機械独立とする。ISLISP オブジェクトのテキスト

表現の幾つかを次に示す。これらの表現は,read 関数によって読み込むことができる。字句要素について

は,1.4 に示す。

a)

空リスト  (null)    オブジェクト nil は,クラス<null>に属する唯一のオブジェクトとする。入力の際に

は,nil 又は()と表記する。nil 又は()のいずれが出力されるかは,処理系定義とする。

b)

リスト  (list)    リストは,通常,nil で終わり,  (obj

1

  obj

2

...obj

n

)  と表記する。ドットリスト(すなわ

ち,末尾が nil でないリスト)は,  (obj

1

 obj

2

obj

n

obj

n

1

)  と表記する。

c)

文字 (character)   <character>クラスのインスタンスは,#\?と表記する。“?”は,この表記が表現す

る文字とする。この記法で表記されない特別な標準文字が二つある。これらは,復帰改行文字及び空

白文字であり,それぞれ#\newline 及び#\space と表記する。

d)

コンス  (cons)    コンスは,  (car 

cdr)

と表記する。ここで,car 及び cdr は,オブジェクトとする。

e)

整数 (integer)     整数(10 進)は,10 進数の並びで表現し,正符号 (+) 又は負符号 (-) で始めても

よい。2 進数,8 進数及び 16 進数は,テキスト表現をそれぞれ#b, #o 及び#x で始める。

f)

浮動小数点数  (float)    浮動小数点数は,次のいずれかの形で表記する。

[sdd...d.dd...d

[sdd...d.dd...dE[s]dd...d

[sdd...d.dd...de[s]dd...d

[sdd...dE[s]dd...d

[sdd...de[s]dd...d

ここで,は “+” 又は “-” であり,は “0” ∼ “9” のいずれかとする。例えば,987.12,+12.5E-13,

-1.5E12,1E32(

1

)

(

1

)

この数値は自然数ではあるが,その表記のために,浮動小数点数とみなす。

g)

ベクタ  (vector)    クラス <general-vector> に属するベクタは,#(obj

1

...obj

n

)  と表記する。

h)

配列  (array)    クラス<general-array*>又はクラス<general-vector>に属する配列は,入力の際には#ra(r


5

X 3012 : 1998 (ISO/IEC 13816 : 1997)

は配列の次元数を表す整数)に続けて,その配列の内容を表す並びを入れ子構造にして表記する。そ

の構造は,次のように定義する。r=1 のとき,配列構造は単純に  (obj

1

...obj

n

)  とする。r>1 のとき,

各次元の大きさを n

1

n

2

,..., n

r

とすると,配列構造は  (str

1

...str

n1

)  となる。ここで,str

i

は r−1 次元の部

分配列構造であり,個々の部分配列の各次元の大きさは n

2

,..., n

r

とする。例えば,  (create-array ’(2 3 4)

5)  が生成する配列は,次のように表記する。

#3a(((5 5 5 5) (5 5 5 5) (5 5 5 5)) ((5 5 5 5) (5 5 5 5) (5 5 5 5)))

出力(format 参照)に際しては,クラス<general-vector>に属する配列は,#(...)  の形で出力する。

i)

文字列 (string)   文字列は一対の”で囲まれた文字の並びによって表記する。例えば, “abc”。特殊

文字の前には,逆斜線をエスケープ文字として使用する。

j)

記号 (symbol)   名前付きの記号は,その印字名で表記する。印字名が特殊文字(10.参照)を含む場

合は,印字名を囲む縦線 (|) が必要となるときがある。名前なしの記号の表記は,処理系定義とする。

オブジェクトの中には,テキスト表現をもたないものがある。例えば,クラス及び<function>クラスのイ

ンスタンスは,テキスト表現をもたない。

1.6

予約語  名前にコロン (:) 及び/又はアンパサンド (&) を含む記号は予約されており,識別子とし

て使用してはならない。名前がコロン (:) で始まる記号を,

キーワード (keyword) と呼ぶ。

1.7

定義  この規格では,次の定義を用いる。

1.7.1

抽象クラス (abstract class)   定義によって,直接インスタンスをもつことが許されないクラス。

1.7.2

活動 (activation)   関数の計算。個々の活動は,起動時点,活動期間及び活動終了時点をもってい

る。活動は,関数適用形式によって起動される。

1.7.3

アクセス関数 (accessor)   インスタンスのスロットに対する読出し関数と書込み関数との総称。

1.7.4

束縛 (binding)   束縛には,構文的側面と意味論的側面とがある。

構文的には,

“束縛”は,識別子と,束縛する ISLISP 評価形式との関係を規定する。束縛されているか

どうかは,識別子が定義されている位置とそれが参照されている位置とを関係付けることによって,検査

できる。

意味論的には,

“束縛”は,変数,変数名及びオブジェクトの間の関係(又は変数とその場所との関係)

を規定する。この関係は,束縛という実体によって具現化されていると考えることができる。そのような

束縛の実体は,実行時に構築され,後で破壊される。ただし,束縛によっては,無制限の存在期間をもつ

場合がある。

1.7.5

クラス (class)   オブジェクトであって,インスタンスと呼ばれる一群のオブジェクトの構造及び

振る舞いを決定する。振る舞いとは,一つのインスタンスに対して実行できる操作の集合である。

1.7.6

例外状態 (condition)   実行中のプログラムによって検出される(又は検出される可能性のある)

状況を表現するオブジェクト。

1.7.7

定義位置 (definition point)    ISLISP テキストのテキスト上の位置であり,その位置以降では,定

義されたオブジェクトは識別子によって表現される。

1.7.8

直接インスタンス (direct instance)    ISLISP オブジェクトは,唯一のクラスの直接インスタンスで

ある。その唯一のクラスを,

“そのオブジェクトのクラス”と呼ぶ。直接インスタンスは振る舞いをともな

い,直接インスタンスのすべての集合が,一つのクラスを構成する。

1.7.9

動的 (dynamic)   プログラムの実行によって初めて決定でき,一般に,静的に決定することが不

可能な影響をもつ。


6

X 3012 : 1998 (ISO/IEC 13816 : 1997)

1.7.10

動的変数 (dynamic variable)   最も最近に束縛を設定した活性ブロックによって,その束縛が決定

される変数。静的原理によって,静的に自明なブロックによって束縛が決定されるものではない。

1.7.11

評価 (evaluation)   実行のために準備された評価形式の計算。その結果は,値及び/又は副作用

となる。

1.7.12

実行 (execution)   活動の並び。活動は入れ子になることもある。

1.7.13

拡張 (extension)   この規格の要求に対する処理系定義の追加事項であり,次の条件をすべて満た

すもの。

・  特定の識別子の使用を禁止することを除き,この規格に適合する ISLISP テキストの正当性を損なわ

ない。

・  エラーを通知するようこの規格が要求している動作の集合を変更しない。

・  処理系依存と指定されている機能の状態を変更しない。

1.7.14

評価形式 (evaluation form)   プログラムテキスト中の,構文的に正しい単位であり,実行のため

に準備することが可能であるもの。

1.7.15

関数 (function)    ISLISP オブジェクトであり,引数を伴って呼び出され,計算(副作用を伴って

もよい。

)を行い,値を返すもの。

1.7.16

包括関数 (generic function)   関数であり,その呼出しの際の振る舞いが引数の値の属するクラス

によって決定され,一般的には複数のメソッドによって構成されるもの。

1.7.17

識別子 (identifier)    ISLISP オブジェクトを指定する静的構成要素(字句要素)。ISLISP テキスト

をデータ構造で表現する場合,識別子は記号で表現する。

1.7.18

変更不可能な束縛 (immutable binding)   束縛が変更不可能であるとは,識別子とそれが表現する

オブジェクトとの関係が変更できないことを意味する。変更不可能な束縛を変更しようと試みた場合は,

違反とする(エラー名 immutable-binding

1.7.19

変更不可能なオブジェクト (immutable object)   オブジェクトが変更不可能であるとは,それが

変更できないことを意味する。変更するための演算子が用意されていない場合,及び変更を行う演算子の

使用を禁止する何らかの制約がある場合に,変更不可能となる。特にことわらない限り,適合するプロセ

ッサは,変更不可能なオブジェクトを変更する試みを検出しなくてもよい。変更不可能なオブジェクトを

変更する試みが行われた場合は,結果は未定義とする。

1.7.20

処理系定義 (implementation defined)    ISLISP プロセッサごとに異なるかも知れない機能である

が,個々のプロセッサごとに完全に定義されているもの。

1.7.21

処理系依存 (implementation dependent)    ISLISP プロセッサごとに異なるかも知れない機能であ

るが,個々のプロセッサによっては必ずしも定義されていないもの。

備考  適合する ISLISP テキストは,処理系依存の機能に依存してはならない。

1.7.22

継承 (inheritance)   クラスとその(直接又は間接の)上位クラスとの関係であり,上位クラスの

構造及び振る舞いをそのクラスに写像する関係。ISLISP は,制限された多重継承を可能とする。すなわち,

クラスは,直接の上位クラスを同時に複数もつことが可能である。

1.7.23

(クラスの)インスタンス (instance)   クラスの直接インスタンス又はその下位クラスのインス

タンス。

1.7.24

リテラル (literal)   プログラム中に,表現が定数として直接現れているオブジェクト。

1.7.25

メタクラス (metaclass)   インスタンスがクラスであるクラス。


7

X 3012 : 1998 (ISO/IEC 13816 : 1997)

1.7.26

メソッド (method)   特定のパラメタ記述に対応して,包括関数の,クラスに固有な振る舞い及び

操作を定義する実体。

1.7.27

オブジェクト (object)    ISLISP プロセッサが生成,破壊,操作,比較,格納,入力又は出力する

ことができるものは,すべてオブジェクトである。特に,関数は ISLISP オブジェクトである。関数に引数

として渡され,値として返され,変数に束縛され,構造体の一部となり得るオブジェクトを

第 級オブジ

ェクト (first-class object) と呼ぶ。

1.7.28

演算子 (operator)   複合形式の第 1 要素であり,その評価形式が特殊形式であることを示す予約

された名前,マクロの名前,ラムダ式又は関数の名前空間に属する識別子。

1.7.29

パラメタ記述 (parameter profile)   メソッドのパラメタリストであり,それぞれのパラメタには,

そのクラス名が付随する。パラメタにクラス名が付随しない場合,そのパラメタは,最も一般的なクラス

に属する。

1.7.30

場所 (place)   オブジェクトは場所に格納して,後で取り出すことができる。場所は,評価形式に

よって指定され,setf の第 1 引数となり得る。このように使われた場合,オブジェクトは,その場所に格

納される。評価形式が setf の第 1 引数以外として使用された場合は,格納されているオブジェクトが取り

出される。場所として許される評価形式の一覧を,setf の規定で示す。

1.7.31

位置 (position) 

a)

引数位置  評価形式の第 1 要素以外の要素が現れる位置。

b)

演算子位置  評価形式の第 1 要素が現れる位置。

1.7.32

処理 (process)   実行準備された ISLISP テキストの実行。

1.7.33

プロセッサ (processor)    ISLISP テキスト(又はそれと等価なデータ構造)を入力として受け入れ,

それを実行のために準備し,結果を実行して値と副作用とを生成するシステム又は機構。

1.7.34

プログラム (program)   評価する式の集合体であり,その特性は文脈に依存する。この規格では,

“プログラム”という用語は,抽象的にだけ使用する。すなわち,プログラムに対する特定の構文は存在

しない。

1.7.35

有効範囲 (scope)   識別子の有効範囲とは,その識別子の意味が定義されているテキスト部分。す

なわち,その識別子が指し示す ISLISP オブジェクトが存在するテキスト部分。

1.7.36

スロット (slot)   インスタンスの名前付きの構成要素であり,スロットアクセスメソッドを使っ

てアクセスできるもの。インスタンスの構造は,そのスロットの集合によって定義される。

1.7.37

テキスト (text)   この規格の要求に適合する(すなわち,ISLISP の構文及び静的意味を有する)

テキスト。ISLISP テキストは,最上位形式の並びによって構成する。

1.7.38

最上位形式 (toplevel form)   他の評価形式の中に入れ子になっていない評価形式又は progn 形式

の中にだけ入れ子になっている評価形式。

1.7.39

最上位有効範囲 (toplevel scope)   完全な ISLISP テキストの単位が処理される有効範囲。

1.7.40

書込み関数 (writer)   クラスのインスタンスのスロットに値を束縛する役割を担う包括関数。

1.8

エラー  エラー (error) とは,実行中に起きる状況であり,この規格が定義する意味に従ってプロセ

ッサが正しい実行を続けることが不可能な状況とする。このようなエラーを検出して報告する行動を,エ

ラーを

通知する (signal) と呼ぶ。

違反 (violation) とは,実行準備の際に起こる状況であり,この規格が規定するテキスト上の要求が満た

されなかった状況とする。違反は,実行準備の際に検出される。

1.8.1

エラー指定  この規格におけるエラー指定の用語を次に示す。


8

X 3012 : 1998 (ISO/IEC 13816 : 1997)

a)

エラーが発生する  処理系は,この種のエラーを,そのエラーを含む評価形式の実行完了以前,でき

る限り早期(例えば,そのコードが実行のために準備されるとき)に検出しなければならない。

処理系は,現在の評価形式の評価を停止しなければならない。実行中の処理全体を終了するのか,

デバッガに入るのか,又は制御をその処理の他の場所に移行するのかは,処理系定義とする。ただし,

利用者がハンドラを設定している場合は,この限りではない。

b)

結果は未定義とする  これは,結果が予測不能であることを意味する。結果は,無害なものから,致

命的なものまでさまざまである。適合する ISLISP テキストは,その結果及び影響に依存してはならな

い。適合する ISLISP テキストは,その結果を予測不能として取り扱わなければならない。この規格で

結果を明示していない要求事項又は禁止事項に反した場合,結果は未定義とする。処理系は,この場

合にエラーを通知してもよい。

索引及び相互参照を簡単にするために,この規格におけるエラーには,エラー名を付け,

“(エラー

名 sample

”と表記する。これらのエラー名は,ISLISP テキスト及び ISLISP プロセッサに対して,意

味論的な重要性をもたない。処理系がエラーを表現するためのオブジェクトのクラス,及び表示する

エラーメッセージの文章は処理系依存とする。

1.8.2

広範囲に使われるエラー  大多数のエラーについては,それらが現れる文脈で詳細に規定する。幾

つかのエラーは,広範囲に使われるものであり,ここで規定する。

a)

定義域エラー  クラスの制約を有する標準関数の引数として与えられたオブジェクトが,関数が要求

するクラスのインスタンスでない場合は,エラーが発生する(エラー名 domain-error

b)

パラメタ数エラー  関数が要求するパラメタの個数と異なる個数の引数を伴って,その関数が起動さ

れた場合は,エラーが発生する(エラー名 arity-error

c)

未定義エラー  識別子によって指し示される実体が,その実体を参照するときに未定義である場合は,

エ ラ ー が 発 生 す る ( エ ラ ー 名 undefined-entity )。 こ の 種 類 の エ ラ ー で 頻 度 の 高 い も の に ,

undefined-function

及び unbound-variable がある。

これらが,すべての種類のエラーではない。より完全な一覧を,21.4 に示す。

1.9  ISLISP

プロセッサ及び ISLISP テキストの適合性  この規格の要求に適合する ISLISP プロセッサは,

次の項目を満たさなければならない。

a)

この規格が規定するすべての機能を受け入れ,実装する。

b)

違反(1.8 参照)であるとこの規格が明記する事項を含むテキストを拒絶する。

c)

この規格で処理系定義と規定した機能をすべて定義する文書を備えている。

d)

プロセッサが受け入れる機能で,この規格が規定していないものを定めた文書を備えている。これら

の拡張は,

JIS X 3012 : 1998 が規定する ISLISP の拡張である”と明記しなければならない。

適合する ISLISP テキストは,処理系依存機能に依存してはならない。しかし,適合する ISLISP テキス

トは,この規格が要求する処理系定義機能に依存してもよい。

適合する ISLISP テキストは,この規格が定義する名前付き定数に対する局所的な変数束縛を行ってはな

らない。そのような試みが行われた場合は,違反とする。

2.

クラス  ISLISP において,データ型は,クラスシステムとして実現する。クラス (class) は,それ自

身一つのオブジェクトであり,他のオブジェクトの集合の構造及び振る舞いを決定する。この集合の個々

のオブジェクトを,

インスタンス  (instance)  と呼ぶ。どの ISLISP オブジェクトも,あるクラスのインスタ

ンスとする。振る舞いとは,インスタンスに対して行い得る操作の集合とする。


9

X 3012 : 1998 (ISO/IEC 13816 : 1997)

クラスは,他のクラスから構造及び振る舞いを継承できる。他のクラスからの継承を目的に,クラス定

義の中でそれらのクラスを参照するクラスを,それらのクラスの

下位クラス (subclass) と呼ぶ。継承の目

的で指定したクラスを,継承しているクラスの

上位クラス (superclass) と呼ぶ。

一つのクラスは一つの識別子を名前としてもつ。この識別子は,例えば,メソッドの定義において,パ

ラメタ特殊化指定として使うことができる。ある名前に対応するクラスオブジェクトを参照するには,特

殊形式の class を使用する。

C

2

というクラスの定義の中で,明示的に C

1

を上位クラスとして指定している場合,又はこの規格の中

で指定している場合(例えば,

図 において,C

2

が C

1

から矢印で結ばれている場合)

,クラス C

1

は,クラ

ス C

2

直接の上位クラス (direct superclass) という。このとき,C

2

は C

1

直接の下位クラス (direct subclass)

という。クラスの並び C

1

, ..., C

n

が存在し,1<iであるすべての に対して,C

i

が C

i

1

の直接の上位ク

ラスである場合,クラス C

1

を C

n

上位クラス (superclass) という。この場合,C

n

は C

1

下位クラス

(subclass)  という。どのクラスも,自分自身の上位クラスではなく,自分自身の下位クラスでもない。すな

わち,C

1

が C

2

の上位クラスの場合,C

1

と C

2

とは同じクラスではない。あるクラス 及び のすべての上

位クラスからなる集合を,

及びその上位クラス”という。

利用者定義のクラス が二つのクラス C

1

及び C

2

を継承している場合,C

1

及び C

2

に共通の上位クラス

は,<standard-object>及び<object>に限る。これによって,制限された多重継承が許される。

どの ISLISP オブジェクトも,唯一のクラスの直接インスタンスとする。その唯一のクラスを,

“そのオ

ブジェクトのクラス”と呼ぶ。

クラスのインスタンスとは,そのクラスの直接インスタンスであるか,又はそのクラスの下位クラスの

インスタンスとする。

クラスは,上位下位の関係によって

循環のない有向グラフ  (directed acyclic graph)  を構成する。このグラ

フの節はクラスを表し,C

2

が C

1

の直接の下位クラスであるときにだけ,C

1

から C

2

に有向辺が存在する。

このグラフを

継承グラフ (inheritance graph) と呼ぶ。継承グラフは<object>というクラスを根とし,これは,

上位クラスをもたない唯一のクラスとする。それゆえ,<object>は,自分以外のすべてのクラスの上位ク

ラスとなる。<standard-object>という名前のクラスは,<standard-class>というクラスのインスタンスとする。

<standard-object>は,<standard-class>のインスタンスであるすべてのクラス(ただし,<standard-object>

自身は除く。

)の上位クラスとする。

それぞれのクラスには,

クラス優先度リスト (class precedence list) がある。これは,与えられたクラス

及びそのすべての上位クラスの間の全順序関係を表す。

この全順序関係は,

最も優先度の高いクラスから,

最も優先度の低いクラスへの順にクラスを並べたものとする。クラス優先度リストは,幾つかの方法で利

用する。一般に,クラスはその上位クラスの特性を継承するが,より優先度の高いクラスは,それらの特

性を

遮へいする (shadow),すなわち上書きすることができる。また,メソッドを選択したり結合する処理

においては,メソッド間の優先順序を決定するために,クラス優先度リストが利用される。

2.1

メタクラス  クラスは,それ自身があるクラスのインスタンスであるオブジェクトとして表現され

る。あるオブジェクトのクラスのクラスを,そのオブジェクトの

メタクラス (metaclass) と呼ぶ。メタク

ラスという用語は,クラスをインスタンスとしてもつクラスを指すために使用する。

メタクラスは,そのインスタンスであるクラスに関する継承の方法を決定し,そのクラスのインスタン

スの表現を決定する。

ISLISP のオブジェクトシステムでは,次のものを定義済みのメタクラスとする。

・ <standard-class>は,特に指定のないとき,defclass で定義されるクラスのクラスとする。


10

X 3012 : 1998 (ISO/IEC 13816 : 1997)

・ <built-in-class>は,特別な実装をもつか,又は機能に制限をもつクラスをインスタンスとするクラスと

する。例えば,<built-in-class>のインスタンスであるクラスに対しては,下位クラスを定義してはなら

ない。

2.2

定義済みクラス  次のクラスは,クラスシステムにおける基本クラス(すなわち,メタクラス以外

の定義済みのクラス)とする。

<arithmetic-error> <floating-point-underflow>

<simple-error>

<basic-array> <function>

<standard-generic-function>

<basic-array*> <general-array*>  <standard-object>

<basic-vector> <general-vector>  <storage-exhausted>

<character> <generic-function>

<stream>

<cons> <integer> <stream-error>

<control-error> <list>

<string>

<division-by-zero> <null>

<symbol>

<domain-error> <number>

<unbound-variable>

<end-of-stream> <object>

<undefined-entity>

<error> <parse-error>

<undefined-function>

<float> <program-error>

<floating-point-overflow> <serious-condition>

<standard-class>及び<built-in-class>は,定義済みのメタクラスとする。

利用者が defclass で定義したクラスは,<standard-class>のインスタンスとなる。定義済みのクラスは,

あ た か も defclass で 定 義 さ れ た か の よ う に <standard-class> の イ ン ス タ ン ス と し て 実 装 す る か 又 は

<built-in-class>のインスタンスとして実装するかのいずれかとする。

図 に,ISLISP で定義されるクラス間に定められた継承関係を示す。図の中で,クラス C

1

からクラス

C

2

が矢印で直接結ばれている場合,

C

1

は C

2

の直接の上位クラスとし,

C

2

は C

1

の直接の下位クラスとする。

これ以外の関係が追加されてもよいが,次の制約に従うこととする。

a) <standard-generic-function>

が<standard-object>の下位クラスであるかどうかは,処理系定義とする。

b)

上の<standard-generic-function>に関する制約及び

図 で規定することを除いては,この規格で定義され

るクラス間には,上位下位の関係は存在しない。しかし,処理系が定める追加のクラスと,この規格

で定義するクラスとの間には,処理系が定める上位下位の関係が存在してよい。

c) <null>

のクラス優先度リストには,<null>,<symbol>,<list>及び<object>が,この順序で現れる。

d)

利用者は,defclass を用いて,追加のクラスを定義できる。

組込みクラス (built-in class) とは,そのインスタンスの機能が制限されているか又は特別な表現をもつ

クラスとする。defclass 定義形式を,組込みクラスの下位クラスを定義するために使用してはならない。包

括関数 create が組込みクラスのインスタンスを生成するために使われた場合は,エラーが発生する。

標準クラス (standard class) は,<standard-class>のインスタンスとする。組込みクラスは,<built-in-class>

のインスタンスとする。

直接の上位クラスを指定しないで定義した標準クラスは,<standard-object>及び<object>という名前のク

ラスを除けば,

図 に現れるどのクラスとも重複しないことが保証される。

<function>は,すべての関数のクラスとする。<standard-generic-function>は,クラス指定(7.2.1 参照)な

しに定義されたすべての包括関数のクラスとする。


11

X 3012 : 1998 (ISO/IEC 13816 : 1997)

図 1  クラス継承

2.3

標準クラス

2.3.1

スロット  <standard-class>をメタクラスとするオブジェクトは,0 個以上の名前付きスロットをも

つ。オブジェクトのスロットは,そのオブジェクトのクラスによって決定される。各スロットは,その値

として一つのオブジェクトを保持できる。スロットの名前は,識別子とする。

あるスロットが値をもたないとき,そのスロットは

未束縛 (unbound) であるという。未束縛のスロット


12

X 3012 : 1998 (ISO/IEC 13816 : 1997)

の値を取り出そうとした場合は,結果は未定義とする。

スロットの値を格納したり取り出したりすることは,defclass 定義形式で定義される包括関数によって行

う。

すべてのスロットは局所的とする。すなわち,複数のインスタンスからアクセスできる共通のスロット

は存在しない。

あるクラスの defclass 定義形式に,ある名前のスロット指定が含まれるとき,そのクラスはその名前の

スロットを

定義する (define) という。スロットを定義することは,直ちにスロットを生成することを意味

するのではなく,そのクラスのインスタンスが生成されるごとにスロットが生成されることを意味する。

あるスロットがそのインスタンスの属するクラスによって定義されているか又はそのクラスの上位クラ

スから継承されているとき,そのスロットは,

アクセス可能 (accessible) であるという。一つのインスタ

ンスに対しては,ある名前のスロットは,高々一つだけがアクセス可能とする。スロットの継承の詳細は,

7.1.3

による。

2.3.2

クラスのインスタンスの生成  包括関数 create は,クラスのインスタンスを生成し,それを値とし

て返す。ISLISP は,インスタンスを初期化する方法を指定するために,幾つかの機構を用意している。例

えば,省略時初期値形式を与えることによって,新しく生成されるインスタンスのスロット初期値を指定

することができる。更に,初期化のための包括関数に対してメソッドを追加することによって,柔軟な初

期化が行える。

3.

有効範囲及び存在期間  ISLISP を定める上で,有効範囲及び存在期間の概念は重要となる。前者は構

文の概念とし,後者は意味の概念とする。構文上の構造,特に識別子は,実行時の実体(実行中に生成さ

れるオブジェクト)を参照するために使うが,一つの実体が同時に有効範囲及び存在期間の両方をもつこ

とはできない。有効範囲は,識別子の属性であり,識別子が一意的な意味をもつ ISLISP テキストの一部分

を指す。存在期間は,あるオブジェクトが存在する期間を指す。

名前空間 (namespace) は,識別子から意味への対応を決定する。ISLISP には,六つの名前空間(変数,

動的変数,関数,クラス,ブロック及びタグ本体のタグ)がある。プログラムの文脈に応じて,一つの識

別子が,最大で六つの意味をもつことができる。例えば,関数適用形式において,演算子位置に識別子が

現れた場合,関数の名前空間がその識別子の意味を決定する。一方,同じ評価形式の引数位置に同じ識別

子が現れた場合,変数の名前空間がその識別子の意味を決定する。

3.1

静的原理  ISLISP は,静的可視性 (lexical visibility) の原理に従って設計されている。この原理は,

ISLISP テキストが,正しく入れ子構造になった静的可視性のブロックから構成されることを意味する。あ

るブロックの中では,そのブロックで定義されたすべての識別子及びそのブロックを包含する外側のブロ

ックで定義されたすべての識別子が可視とする。ある名前空間の識別子は,それを定義する最も内側のブ

ロックによって意味が決まる。

ISLISP は動的束縛 (dynamic binding) の機能も提供する。動的束縛の設定及びアクセスは,専用の機構

(すなわち,defdynamic,dynamic-let 及び dynamic)によって行なわれる。動的束縛の値は,時間的に最も

近い時点で実行された

活性ブロック (active block) が設定した束縛の値とする。ここで活性ブロックとは,

実行が開始され,その実行がまだ終了していないブロックとする。専用の機構が使われるので,一つの識

別子に,

静的な意味及び動的束縛の値の両方が定義されている場所では,

それらを同時にアクセスできる。


13

X 3012 : 1998 (ISO/IEC 13816 : 1997)

3.2

識別子の有効範囲  識別子の有効範囲 (scope) とは,その識別子の意味が定義されている ISLISP テ

キストの一部分とする。有効範囲は,定義位置から始まる。定義位置は,識別子の束縛を設定する評価形

式ごとに定める。識別子だけが有効範囲をもつことができる。

ある名前空間において,ある識別子が s

a

という有効範囲をもち,同じ名前空間における同じ識別子が s

a

の内側に有効範囲 s

b

をもつ場合,s

b

は s

a

の一部ではない。このとき,内側の有効範囲は,外側の有効範囲

遮へいする (shadow) という。

参考  個々の評価形式の記述の中で有効範囲を規定する場合,遮へいされる部分も含んだ範囲を記す

ことにする。

ISLISP テキスト全体は,最上位有効範囲 (toplevel scope) と呼ばれる有効範囲で処理される。

(let ((a1 f-a1)

        …

       (x  f-x)

        …

       (z1  f-z1))

;ここで,a1,…,x,…,z1 が使用でき,それらの有効範囲はここから始まる。

    (let((a2 f-a2) ;a1,…,x,…,z1 は,新しく定義されるかもしれない。しかし,

          …

;依然,外側の a1,…,x,….

,z1 は使用でき,

          (x f-x2)  ;内側の a2,…,x,…,z2 はまだ使用できない。

          …

          (z2 f-z2))

;外側の x の有効範囲が,遮へいされる。

;内側の a2,…,x,…,z2 の有効範囲が始まる。

      …

;ここで,外側の a1,z1 及び内側の a2,…,x,…,z2 が使用できる。

    )

;ここで,a2,…,x,…,z2 の有効範囲が終わる。

    …

;外側の x の有効範囲が復活する。

)

;ここで,a1,…,x,…,z1 の有効範囲が終わる。

図 2  有効範囲の例

3.3

個別の有効範囲規則  組込み関数及び組込み定数に対応する識別子の有効範囲は,最上位有効範囲

とする。予約語(1.6 参照)は識別子ではないので,静的原理に従わない。予約語は定義できないし,束縛

もできない。

3.4

存在期間  構文の概念である有効範囲に対して,意味の概念である存在期間 (extent) がある。これ

は,実体が生存する期間を表わす。

オブジェクトは,実行中のある時点で生成される。ほとんどの場合,オブジェクトの存在が終わる時点

は決定できない。オブジェクトの存在期間は,オブジェクトが生成された時点に始まり,それへの参照が

不可能になった時点で終了する。この場合,そのオブジェクトは,

無制限の存在期間 (indefinite extent) を

もつという。

その他に,実行準備されたテキストに付随する実体を,処理系が生成する場合がある。そのようなオブ

ジェクトの存在期間は,それを定義する構文の起動時点に始まり,活動が終了した時点で終了する。この

とき,そのオブジェクトは,

動的存在期間 (dynamic extent) をもつという。


14

X 3012 : 1998 (ISO/IEC 13816 : 1997)

プログラムの実行中に,定義形式及び次の束縛形式は,起動された時点に束縛を行う。

block let

with-open-io-file

dynamic-let let*

with-open-output-file

flet tagbody

with-standard-input

for with-error-output

with-standard-output

labels with-open-input-file

定義形式が設定する束縛は,無制限の存在期間をもつ。局所的な束縛を設定する特殊形式においても,

実行終了時点で束縛が消滅するとは限らない。そのブロックの実行中にそれらの束縛をアクセスする関数

オブジェクトが生成された場合,束縛は,それらの関数オブジェクトのうち,存在期間が最大のものと同

じ存在期間をもつ。

例  (defun copy-cell (x) (cons (car x) (cdr x)))

識別子 x の有効範囲は,本体,すなわち,  (cons (car x) (cdr x))  となる。x の意味は,本体の全

体で定義される。識別子としての x は,存在期間をもたない。この defun 形式が実行準備され,

copy-cell が実行準備された関数となる。プログラム実行中,実行準備された関数 copy-cell が起動

されるかもしれない。この起動によって,x という名前の変数と,引数として使われるオブジェ

クトとの間に,束縛が生成される。X の束縛の存在期間は,関数の起動時点に始まり,関数の終

了時点に終わる(一般には,束縛は関数の活動終了後も存在し続ける可能性があるが,この単純

な例では,そのようなことは起こらない。

。x の束縛は関数起動時点に

設定 (establish) されると

いい,活動終了時点に

解除 (disestablish) されるという。

4.

評価形式及び評価

4.1

評価形式  ISLISP テキストの実行準備が成功していることを前提として,実行が行われる。実行と

は,実行準備された評価形式の活動であり,その結果,値を生成し,副作用を生じることもある。

ISLISP テキストとは,評価形式の並びとする。

この規格では,評価形式が返す値を定めているが,評価形式の部分形式が非局所的脱出(6.7.1 参照)を

実行する場合には,戻らないこともある。それゆえ,すべての値の記述は,戻るという条件が存在するこ

とを暗黙の前提とする。

次のものを,ISLISP の正しい評価形式とする。

・  複合形式 (compound form)

−  特殊形式 (special form)

−  定義形式 (defining form)

−  関数適用形式  (function application form)

−  マクロ形式 (macro form)

・  識別子 (identifier)

・  リテラル (literal)

評価形式は,評価されると,一つのオブジェクトをその値として返す。ただし,戻らない評価形式(例

えば,return-from)もある。

複合形式は,  (operator argument*)  と記述される。operator は,特殊演算子,定義演算子,識別子又はラ

ムダ式でなければならない。識別子は,関数(包括関数を含む。

)又はマクロの名前でなければならない。


15

X 3012 : 1998 (ISO/IEC 13816 : 1997)

operator

がリテラルの場合は,違反とする。

最上位形式 (toplevel form) とは,他の評価形式に構文上含まれることがないか,又は一つ以上の progn

形式の中にだけ入れ子になった評価形式とする。最上位に現れる特殊形式及び関数適用形式を,

初期設定

形式 (set-up form) と呼ぶ。定義形式が最上位形式でない場合は,違反とする。

4.2

関数適用形式  関数適用形式 (function application form) は,演算子が関数の名前を与える識別子で

あるか又は演算子がラムダ式である複合形式とする。すべての引数は左から右に順に評価され,その後に

それらの引数で関数が呼び出される。これを

適用する (apply) という。関数の適用において,引数は,評

価の結果であるオブジェクトが評価と同じ順序で使われる。

この規格では,関数適用形式を次の記法を使って記述する。

(function-name argument*)  →結果のクラス

関数

これは,通常の関数(包括関数以外の関数)を記述する。

(generic-function-name argument*)  →結果のクラス

包括関数

これは,包括関数を記述する。

(local-function-name argument*)  →結果のクラス

局所関数

これは,指定された静的有効範囲だけで利用できる通常の関数を記述する。

4.3

特殊形式  特殊形式 (special form) とは,その引数が特別な方法で扱われる評価形式とする。例えば,

引数が評価されなかったり,特殊な順序で評価されたりする。ある特殊形式がマクロ(4.5 及び 8.参照)で

記述されるかどうかは,処理系定義とする。特殊形式は,その演算子位置に

特殊演算子 (special operator) が

あることで判別できる。次のものを,特殊演算子とする。

and dynamic-let

let* unwind-protect

assure flet

or

while

block for

progn  with-error-output

case function quote with-handler

case-using go

return-from

with-open-input-file

catch if

setf

with-open-io-file

class ignore-errors

setq

with-open-output-file

cond labels

tagbody

with-standard-input

convert lambda

the

with-standard-output

dynamic let

throw

これ以外にも,処理系定義の特殊演算子がある場合もある。

この規格では,次の表記で特殊形式を記述する。

(special-operator argument*)  →結果のクラス

特殊演算子

4.4

定義形式  定義形式 (defining form) は,名前 name とオブジェクトとの束縛を設定する最上位形式

4.1 参照)とする。この束縛は,定義形式の名前 defining-form-name ごとに定められた意味に基づいて,

argument

を操作した結果として設定される。定義形式が最上位形式でない場合は,違反とする。それぞれ

の名前空間において,定義形式は同じ名前に対して 2 回以上現れてはならない。ただし,メソッド定義の

場合は,名前だけでなくパラメタ記述についても同じものが,2 回以上現れてはならない。定義形式は,

その演算子が

定義演算子 (defining operator) である複合形式とする。次のものを,定義演算子とする。

defclass defdynamic

defglobal

defmethod


16

X 3012 : 1998 (ISO/IEC 13816 : 1997)

defconstantt defgeneric

defmacro

defun

この規格では,次の表記で定義形式を記述する。

(defining-form-name name argument*)  →<symbol>

定義演算子

4.5

マクロ形式  マクロ形式は,実行準備の間に展開される。マクロが展開される方法は,8.による。

4.6

評価モデル  ここでは,評価についての操作的モデルを規定する。

評価には,二つの段階がある。正しい ISLISP テキストは,まず実行準備され,次にその準備されたテキ

ストが実行される。実行準備のための処理は処理系依存とし,準備が完了したテキストの性質も処理系依

存とする。ただし,マクロは実行準備が完了した時点で,展開が完了しているとする(8.参照)

。ここでは,

実行については,マクロがすべて展開された評価形式に対して規定する。

実行準備された評価形式は,次のとおり実行される。

a)

評価形式がリテラルの場合,評価形式そのものを結果とする。

b)

評価形式が識別子の場合,現在の静的環境での変数名前空間でその識別子が指定するオブジェクトを

結果とする。現在の静的環境の変数名前空間で,その識別子が束縛されていない場合は,エラーが発

生する(エラー名 unbound-variable

1.8.2 参照)

c)

評価形式が複合形式の場合,次のいずれか一つの場合が,必ず適用される。

1)

演算子が特殊演算子の場合,その評価形式は特殊形式であり,その引数は特殊演算子の定義に従っ

て評価される。例えば,if 形式 (if test-form then-form else-form)  は,まず test-form を評価し,次に,

その評価結果に依存して then-form 又は else-form を評価する。

2)

演算子が定義演算子の場合,第 1 引数は,識別子とする。残りの引数は,定義形式の仕様に従って

扱われ,その結果のオブジェクトが,適切な名前空間において,識別子に束縛される。

3)

演算子がラムダ式の場合,まず引数が評価される。引数の評価は,左から右へ順に行われる。その

後,引数を評価した結果を

実引数 (actual argument) として,ラムダ式で指定された関数を呼び出す。

関数が戻るならば,評価形式の結果は,関数が返す値とする。

例  ((lambda (x) (+ x x)) 4)

⇒ 8

4)

上のいずれでもない場合,複合形式は,関数適用形式とする。評価形式の演算子位置には,識別子

があるものとする。この識別子を現在の静的環境の関数名前空間で評価し,呼び出すべき関数を生

成する。関数名前空間で,その識別子が束縛されていない場合は,エラーが発生する(エラー名

undefined-function

。引数は,左から右へ順に評価される。その後,引数を評価した結果を実引数と

して,関数を呼び出す。関数が戻るならば,評価形式の結果は,関数が返す値とする。

d)

上のいずれでもなければ,エラーが発生する(エラー名 undefined-function

上のそれぞれの場合に起こり得るエラーについては,1.8.2 による。

4.7

関数  関数は,呼び出されるときに,幾つかのオブジェクトを実引数として受け取る (receive) こと

ができる。関数が戻るときには,オブジェクトを

値 (value) として返す (return)。関数の束縛は,次のいず

れかで設定することができる。

・  関数定義形式を使う方法。すなわち,defun,defgeneric 又は defclass の定義形式を使う方法。

・ labels 又は flet の特殊形式を使う方法。

(functionp obj)  →真偽値

関数

関数 functionp は,obj が通常の関数又は包括関数である場合は t を返し,それ以外の場合は nil を返す。

obj

は,いかなる ISLISP オブジェクトでもよい。


17

X 3012 : 1998 (ISO/IEC 13816 : 1997)

例    (functionp (function car))                          ⇒t

関数束縛は,labels 形式又は flet 形式の実行の間に設定されるか,又は関数定義形式で設定される。関数

束縛は,関数名と関数オブジェクトとの対応関係とする。その関数オブジェクトは,関数名が演算子位置

にあるときは名前によって,そうでないときは (function function-name)  の評価形式によって指定する。

(function function-name)  →<function>

特殊演算子

#’function-name→<function>

構文

特殊形式の function は,function-name という名前の関数への参照を表す。この特殊形式は,関数定義形

式,labels 形式又は flet 形式で定義された識別子を,演算子位置以外の場所で参照するために使用する。

(function function-name)  は,#’function-name と記述してもよい。

この評価形式は,function-name という名前の関数オブジェクトを,値として返す。

現在の静的環境の関数名前空間において,識別子 function-name に対する束縛がない場合は,エラーが発

生する(エラー名 undefined-function

1.8.2 参照)

function-name がマクロ,特殊形式又は定義形式の名前

である場合は,結果は未定義とする。

例  (funcall (function -) 3)

⇒ -3

(apply #’-’(4 3))

⇒ 1

(lambda lambda-list form*)  →<function>

特殊演算子

ここで,

lambda-list ::=

(identifier* [&rest identifier]) |

(identifier* [:rest identifier])

また,同じ識別子が,一つの lambda-list に 2 回以上現れてはならない。

lambda 形式を実行すると,関数オブジェクトが生成される。

lambda-list

は,

ラムダリスト (lambda list) と呼ばれ,関数のパラメタを記述する。lambda-list に指定さ

れた識別子の有効範囲は,form*で指定された評価形式の並びとする。この並びの全体を本体と呼ぶ。また,

ラムダリストに&rest 又は:rest がある場合は,その左側にある各 identifier が表すパラメタを

必す(須)パ

ラメタ (required parameter) と呼び,右側にある identifier の表すパラメタを残余パラメタ (rest parameter)

と呼ぶ。ラムダリストに&rest も:rest もない場合は,すべての identifier の表すパラメタを必すパラメタと

呼ぶ。

関数が引数とともに後で呼び出されたとき(オブジェクトとして別の位置に渡されていても)

,その関数

の本体は,あたかも,lambda 形式があったテキスト位置にあるかのように評価される。ただし,必すパラ

メタが,対応する引数の値に変数名前空間で束縛された状態で評価される。残余パラメタがあるならば,

それは,残りの引数の値のリストに束縛される。関数が受け取った引数の個数が,指定された lambda-list

と一致しない場合は,エラーが発生する(エラー名 arity-error

必すパラメタ(及び残余パラメタ)を束縛した後に,本体を実行する。本体が空のときは,nil が値とし

て返る。本体が空でなく,かつ非局所的脱出(6.7 参照)で本体から抜け出ない場合には,本体の最後の評

価形式の評価結果が値として返る。

関数が残余パラメタをもつ場合,残余パラメタに束縛されるリストである L

1

は,無制限の存在期間をも

つ。L

1

は,新しく生成されるリストとする。ただし,関数が apply で呼び出され,残余パラメタがその最

後の引数 L

2

又は L

2

の後ろの一部分に束縛される場合,L

1

と L

2

とがリストを共有するかどうかは,処理系


18

X 3012 : 1998 (ISO/IEC 13816 : 1997)

定義とする。

例  ((lambda (x y) (+ (* x x) (* y y))) 3 4)   

⇒ 25 

((lambda (x y &rest z) z) 3 4 5 6)

⇒ (5  6) 

((lambda (x y :rest z) z) 3 4 5 6)

⇒ (5  6)

(funcall (lambda (x y) (- y (* x y))) 7 3)

⇒ -18

(labels ((function-name lambda-list form*) *)body-form*)  →<object>

特殊演算子

(flet ((function-name lambda-list form*) *)body-form*)  →<object>

特殊演算子

labels 形式及び flet 形式は,関数名前空間において,関数オブジェクトに対する新しい識別子を定義する。

labels 形式において,function-name の有効範囲は,その labels 形式全体とする。一方,flet 形式において

は,識別子の有効範囲は body-form*だけとする。これらの有効範囲内では,function-name は, (lambda

lambda-list form*)

と同じ振る舞いをする関数オブジェクトに束縛される。ただし,form*内の自由な識別子

は次のとおり処理される。

・ labels 形式に対しては,labels のすぐ外側の静的環境に,与えられた関数のための束縛が追加される。

その環境を用いて,自由識別子の意味を決定する。すなわち,function-name という関数名は,labels

形式が設定する束縛を参照する。

・ flet 形式に対しては,自由識別子の参照は,flet 形式のすぐ外側の静的環境で処理される。すなわち,

flet 形式が定義する function-name という名前の関数は参照できない。

labels 形式又は flet 形式を実行すると,関数束縛が設定され,その後,body-form*で指定された本体の評

価形式を左から右に順に実行する。最後の評価形式の値(評価形式がない場合は nil)を,これらの特殊形

式の値とする。

同じ function-name が,関数束縛の指定に 2 回以上現れてはならない。

例  (labels ((evenp (n)

             (if(= n 0)

                    t

                    (oddp (- n 1))))

             (oddp  (n)

               (if (= n 0)

                    nil

                    (evenp (- n 1)))))

   (evenp  88))

⇒ t

(flet ((f (x) (+ x 3)))

  (flet ((f (x) (+ x (f x))))

    (f 7)))

⇒ 17

(apply function-objlist)  →<object>

関数

関数 apply は,function で指定された関数を呼び出す。その引数は,list で指定されたリストの要素を obj*

の後に追加したものとする。function で指定された関数の返り値が,全体の値となる。

function

が関数でない場合は,エラーが発生する(エラー名 domain-error

。各 obj は,いかなる ISLISP


19

X 3012 : 1998 (ISO/IEC 13816 : 1997)

オ ブ ジ ェ ク ト で も よ い 。 list が nil で 終 わ る リ ス ト で な い 場 合 は , エ ラ ー が 発 生 す る ( エ ラ ー 名

improper-argument-list

例  (apply (if (< 1 2) (function max) (function min))

        1 2 (list 3 4))

⇒ 4

(defun compose (f g)

  (lambda (:rest args)

    (funcall f (apply g args)))))

⇒ compose

(funcall (compose (function sqrt) (function*)) 12 75)

⇒ 30

(funcall function obj*)  →<object>

関数

関数 funcall は,

function

で指定された関数を呼び出し,

その関数の返り値を funcall 自身の値として返す。

funcall の 番目の引数  (i

2)  は,その関数の  (i−1)  番目の引数になる。funcall は,apply を使用して,次

のとおり定義できる。

          (defun funcall (function :rest arguments)

            (apply function arguments))

function

が関数でない場合は,エラーが発生する(エラー名 domain-error

。各 obj は,いかなる ISLISP

オブジェクトでもよい。

例  (let ((x ’(1 2 3)))

  (funcall (cond ((listp x) (function car))

                    (t (lambda (x) (cons x 1))))

          x))

⇒ 1

4.8

定義演算子  定義形式によって定義される名前は,最上位有効範囲全体で使うことができるが,

ISLISP テキスト単位における実行準備された最上位形式は,左から右に順に実行される。

一つの名前空間で同じ名前をもつ二つの定義形式は,同じ最上位有効範囲で使ってはならない。

(defconstant name form)  →<symbol>

定義演算子

defconstant 形式は,名前付き定数を最上位有効範囲の変数名前空間に定義する。name の有効範囲は,form

の部分を除いた最上位有効範囲全体とする。

name

は,

大域的な定数とするが,

束縛形式を用いて局所的に name という名前の変数を束縛してもよい。

form

で指定された評価形式の評価の結果が,name という名前の変数に束縛される。この束縛及び form

を評価した結果生成されたオブジェクトは,変更不可能とする。name という名前の記号を,この定義形式

の値とする。

例  (defconstant e 2.7182818284590451)

⇒ e

e

⇒ 2.7182818284590451

(defun f () e)

⇒ f

(f)

⇒ 2.7182818284590451

(defglobal name form)  →<symbol>

定義演算子

defglobal 形式は,最上位有効範囲の変数名前空間に識別子を定義する。name の有効範囲は,form の部


20

X 3012 : 1998 (ISO/IEC 13816 : 1997)

分を除いた最上位有効範囲全体とする。

form

は,name という名前の変数の初期値を計算するために評価される。したがって,defglobal は変数

を定義するためだけに使用し,変数を変更するためには使用できない。name という名前の記号を,この定

義形式の値とする。

name

に対して,束縛形式を用いて静的な変数束縛を局所的に設定してもよい。この場合,局所的な束縛

は,defglobal が定義した name の束縛を遮へいする。

例  (defglobal today ’wednesday)

⇒ today

today

⇒ wednesday

(defun what-is-today () today)

⇒ what-is-today

(what-is-today)

⇒ wednesday

(let ((what-is-today ’thursday)) (what-is-today))

⇒ wednesday

(let ((today ’thursday)) (what-is-today))

⇒ wednesday

(defdynamic name form)  →<symbol>

定義演算子

defdynamic 形式は,動的変数の名前空間に,動的変数を定義するために使用する。name の有効範囲は,

form

の部分を除いた最上位有効範囲全体とする。

name

という名前の記号を,この定義形式の値とする。

例  (defdynamic *color* ’red)

⇒ red

(dynamic *color*)

⇒ red

(defun what-color () (dynamic *color*))

⇒ what-color

(what-color)

⇒ red

(dynamic-let ((*color* ’green)) (what-color))

⇒ green

(defun function-name lambda form*)  →<symbol>

定義演算子

defun 形式は,function-name を,関数名前空間の識別子として定義する。function-name は, (lambda

lambda-list form*)

と等価な関数オブジェクトに束縛される。

function-name

の有効範囲は,最上位有効範囲全体とする。したがって,defun による関数定義では,再

帰が許される。すなわち,form*の中で,定義しようとしている関数を function name という名前で用いる

ことができる。function-name とそれに対応する関数オブジェクトとの束縛は,変更不可能とする。

defun は function-name という名前の記号を返す。関数本体 form*に現れる自由識別子(すなわち,ラムダ

リストに含まれない識別子)は,静的有効範囲規則に従うものとする。

例  (defun caar (x) (car (car x)))       ⇒ caar 

5.

述語

5.1

真偽値  値 t 及び値 nil は,真偽値 (boolean) と呼ばれる。t は真を表し,nil は偽を表す唯一の値と

する。

述語 (predicate) は,真偽値関数 (boolean function) とも呼ばれ,その引数が条件を満たす場合は t

を返し,そうでなければ nil を返す。

(t に限らず)nil 以外のすべてのオブジェクトは,真として扱う。オブジェクトは,このように真又は

nil として扱われる場合,準真偽値 (quasi-boolean) と呼ぶ。


21

X 3012 : 1998 (ISO/IEC 13816 : 1997)

t は記号 t を表す識別子であり,nil は記号 nil を表す識別子とする(記号 nil は,空リストでもある。)。

nil は,クラス<null>の唯一のインスタンスとする。

真偽値関数と同様に,and 形式及び or 形式は,真又は偽を返す。しかし,返される値は,条件が満たさ

れない場合は nil であり,そうでなければ nil 以外の値とする。つまり,and 及び or は,準真偽値を値とす

る。

t→<symbol>

名前付き定数

nil→<null>

名前付き定数

t は,記号 t を値とする名前付き定数とする。nil は,記号 nil を値とする名前付き定数とする。

5.2

クラス述語  次の関数は,1 引数のクラス述語とする。

basic-array*-p floatp

integerp  stringp

basic-array-p functionp

listp

symbolp

basic-vector-p general-array*-p  null

characterp general-vector-p

numberp

consp generic-function-p

streamp

なお,関数 instancep は,クラスのインスタンスか否かを判定する,2 引数の述語とする。

5.3

等価性

(eq obj

1

 obj

2

)  →真偽値

関数

(eql obj

1

 obj

2

)  →真偽値

関数

関数 eq 及び関数 eql は,引数 obj

1

と引数 obj

2

とが,同一のオブジェクトであるか否かを判定する。これ

らの関数は,二つの引数が同一のオブジェクトであれば t を返し,そうでなければ nil を返す。二つのオブ

ジェクトは,それらを(オブジェクトの変更なしに)区別する操作がなく,かつ,一つのオブジェクトの

変更がもう一つのオブジェクトを同じように変更する場合に同一とする。

関数 eq では,引数がいずれも数値であるか,又はいずれも文字である場合は,結果は未定義とする。関

数 eql では,数値及び文字に対する意味は次のとおり定義する。

・  引数 obj

1

及び引数 obj

2

が数値であれば,eql は,二つの引数が同じクラスの直接インスタンスであり,

かつ,同じ値をもつか否かを判定する。

処理系が,正のゼロ及び負のゼロを異なる値として実装していれば,  (eql 0.0 -0.0)  は nil を返す。

-0.0 が読み込まれた場合に,値 0.0 と解釈されるならば,  (eql 0.0 -0.0)  は t を返す。

・  引数 obj

1

及び引数 obj

2

が文字ならば,eql は,それらが同じ文字か否か(char=参照)を判定する。

例  (eql () ())

⇒ t

(eq  ()  ())

⇒ t

(eql ’() ’())

⇒ t

(eq  ’()  ’())

⇒ t

(eql ’a ’a)

⇒ t

(eq  ’a  ’a)

⇒ t

(eql ’a ’A)

⇒ t

(eq  ’a  ’A)

⇒ t

(eql ’a ’b)

⇒ nil

(eq  ’a  ’b)

⇒ nil


22

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(eql ’f ’nil)

⇒ nil

(eq  ’f  ’ml)

⇒ nil

(eql 2 2)

⇒ t

(eq  2  2)

⇒ nil 又は t (処理系定義)

(eql 2 2.0)

⇒ nil

(eq  2  2.0)

⇒ nil

(eql 100000000 100000000)

⇒ t

(eq  100000000  100000000)

⇒ nil 又は t(処理系定義)

(eql 10.00000 10.0)

⇒ t

(eq  10.00000  10.0)

⇒ nil 又は t(処理系定義)

(eql (cons 1 2) (cons 1 2))

⇒ nil

(eq  (cons 1 2) (cons 1 2))

⇒ nil

(let ((x ’(a))) (eql x x))

⇒ t

(let ((x ’(a))) (eq x x))

⇒ t

(eql ’(a) ’(a))

⇒ nil 又は t(処理系定義)

(eq  ’(a)  ’(a))

⇒ nil 又は t(処理系定義)

(let ((x ’(b))

       (y ’(a b)))

  (eql x (cdr y)))

⇒ nil 又は t(処理系定義)

(let ((x ’(b))

       (y ’(a b)))

  (eq x (cdr y)))

⇒ nil 又は t(処理系定義)

(eql ’(b) (cdr ’(a b)))

⇒ nil 又は t(処理系定義)

(eq  ’(b) (cdr ’(a b)))

⇒ nil 又は t(処理系定義)

(let ((p (lambda (x) x)))

  (eql p p))

⇒ t

(let ((p (lambda (x) x)))

  (eq p p))

⇒ t

(let ((x "a")) (eql x x))

⇒ t

(let ((x "a")) (eq x x))

⇒ t

(eql "a" "a")

⇒ nil 又は t(処理系定義)

(eq  "a"  "a")

⇒ nil 又は t(処理系定義)

(let ((x ""))(eql x x))

⇒ t

(let ((x ""))(eq x x))

⇒ t

(eql "" "")

⇒ nil 又は t(処理系定義)

(eq  ""  "")

⇒ nil 又は t(処理系定義)

(eql #

\a #\A)

⇒ nil

(eq  #

\a #\A)

⇒ nil

(eql #

\a #\a)

⇒ t

(eq  #

\a #\a)

⇒ nil 又は t(処理系定義)


23

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(eql #

\space #\Space)

⇒ t

(eq  #

\space #\Space)

⇒ nil 又は t(処理系定義)

(eql #

\space #\space)

⇒ t

(eq  #

\space #\space)

⇒ nil 又は t(処理系定義)

(equal obj

1

 obj

2

)  →真偽値

関数

関数 equal は,引数 obj

1

及び引数 obj

2

が同形 (isomorphic),すなわち,引数 obj

1

及び引数 obj

2

が等価な値

をもつ同じ構造を表すか否かを判定する。equal は,同形の場合は t を返し,そうでなければ nil を返す。

正確には,次のとおり判定する。

引数 obj

1

と引数 obj

2

とが同じクラスの直接インスタンスである場合,その二つが eql であるか又は次の

いずれかが成り立つときに equal は t を返す。これ以外の場合は,nil を返す。

a)

リスト

          (and (equal (car obj

1

) (car obj

2

))

                (equal (cdr obj

1

) (cdr obj

2

)))

b)

配列

          (equal (array-dimensions obj

1

)

                  (array-dimensions obj

2

))

が成り立ち,かつ,すべての正しい参照 (aref obj

1

 ind

1

 ... ind

n

)  に対して,次の条件が成り立つ。

          (equal (aref obj

1

 ind

1

 ...ind

n

)

                  (aref obj

2

 ind

1

 ...ind

n

))

obj

1

及び obj

2

は,いかなる ISLISP オブジェクトでもよい。

例  (equal ’a ’a)

⇒ t

(equal 2 2)

⇒ t

(equal 2 2.0)

⇒ nil

(equal ’(a) ’(a))

⇒ t

(equal ’(a (b) c) ’(a (b) c))

⇒ t

(equal (cons 1 2) (cons 1 2))

⇒ t

(equal ’(a) (list ’a))

⇒ t

(equal "abc" "abc")

⇒ t

(equal (vector ’a) (vector ’a))

⇒ t

(equal #(a b) #(a b))

⇒ t

(equal #(a b) #(a c))

⇒ nil

(equal "a" "A" )

⇒ nil

5.4

論理演算

(not obj)  →真偽値

関数

関数 not は,論理否定であり,引数 obj が nil であれば t を返し,そうでなければ nil を返す。obj は,い

かなる ISLISP オブジェクトでもよい。

(not t)

⇒ nil

(not ’())

⇒ t


24

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(not ’nil)

⇒ t

(not nil)

⇒ t

(not 3)

⇒ nil

(not (list))

⇒ t

(not (list 3))

⇒ nil

(and form

*

)  →<object>

特殊演算子

and は,逐次的な論理積とする。引数 form*は,そのいずれかの form の評価結果が nil であるか,又は引

数がなくなるまで,左から右に順に評価される。引数のいずれかの評価結果が nil であれば,and は nil を

返し,そうでなければ最後に評価した引数 form の値を返す。and 形式は,次の式と同値とする。

(and)

≡ ’t

(and form)

≡  form

(and form

1

 form

2

 ... form

n

)

≡ (if

form

1

 (and form

2

...form

n

) ’nil)      (

2

)

(

2

) if

の定義については,6.4参照。

例  (and (= 2 2) (> 2 1))

⇒ t

(and (= 2 2) (< 2 1))

⇒ nil

(and (eql ’a ’a) (not (> 1 2)))

⇒ t

(let ((x ’a)) (and x (setq x ’b)))

⇒ b

(let ((x nil)) (and x (setq x ’b)))

⇒ nil

(let ((time 10))

  (if (and (< time 24) (> time 12))

       (- time 12) time))

⇒ 10

(let ((time 18))

  (if (and (< time 24) (> time 12))

       (- time 12) time))

⇒ 6

(or form

*

)  →<object>

特殊演算子

or は,逐次的な論理和とする。引数 form*は,そのいずれかの form の評価結果が nil 以外の値であるか,

又は引数がなくなるまで,左から右に順に評価される。or は,引数のいずれかの評価結果が nil 以外の値

であれば,その nil 以外の値を返し,そうでなければ nil を返す。or 形式は,次の式と同値とする。

(or)

≡ ’nil

(or form)

≡  form

(or form

1

 form

2

 ... form

n

)  ≡ ((lambda

(var) (if var var (or form

2

...form

n

))) form

1

)

ここで,var は,form

2

...form

n

に現れないものとする。

例  (or (= 2 2) (> 2 1))

⇒ t

(or (= 2 2) (< 2 1))

⇒ t

(let ((x ’a)) (or x (setq x ’b)))

⇒ a

(let ((x nil)) (or x (setq x ’b)))

⇒ b


25

X 3012 : 1998 (ISO/IEC 13816 : 1997)

6.

制御構造

6.1

定数  定数には,リテラル,引用形式及び名前付き定数の 3 種類がある。引用形式については,quote

参照。名前付き定数については,defconstant 参照。

定数の値を変更しようとした場合は,結果は未定義とする。

constant  →<object>

構文

クラス<basic-array>,<character>及び<number>のインスタンスは,リテラル定数とする。リテラル定数

constant

を評価した結果は,その constant 自身とする。

例  #2A((a b c) (d e f))

⇒ #2A((a b c) (d e f))

#

\a

⇒ #\a

145932

⇒ 145932

"abc"

⇒ "abc"

#(abc)

⇒ #(abc)

(quote obj)  →<object>

特殊演算子

obj  →<object>

構文

quote 形式は,引用形式 (quoted expression) と呼ばれ,ISLISP テキストにオブジェクト obj を埋め込むた

めに使用する。quote 形式の評価結果は,obj とする。

(quote obj)は,’obj と記述してもよい。

例  (quote a)

⇒ a

(quote #(a b c))

⇒ #(a b c)

(quote (+ 1 2))

⇒ (+ 1 2)

’()

⇒ nil

’a

⇒ a

’#(a b c)

⇒ #(a b c)

’(car 1)

⇒ (car  1)

’(+ 1 2)

⇒ (+ 1 2)

’(quote a)

⇒ (quote  a)

’’a

⇒ (quote  a)

(car ’’a)

⇒ quote

引用形式の値を変更しようとした場合は,結果は未定義とする。

6.2

変数  変数束縛 (variable binding) は,変数束縛形式の実行又は関数の起動によって設定される。

変数 (variable) は,識別子で表され,その識別子と ISLISP オブジェクトとの間の結合を設定する。この結

合は,setf 形式又は setq 形式を使って(代入によって)

,変更できる。

変数束縛形式には次のものがある。

          defglobal  let  let*  for

var 

→<object>

構文

変数 var の値は,その変数の束縛によって,var と結合されているオブジェクトとする。

例  (defglobal x 0)

⇒ x


26

X 3012 : 1998 (ISO/IEC 13816 : 1997)

x

⇒ 0

(let ((x 1)) x)

⇒ 1

x

⇒ 0

(setq var form)  →<object>

特殊演算子

setq 形式は,識別子 var で表される変数への代入を表す。この結果として,form の値が識別子 var の値

となる。

setq 形式は,引数 form を評価した結果を返す。この結果は,識別子 var で表される変数束縛を(もし変

更可能ならば)変更するために用いられる。setq 形式は,束縛の変更だけに用い,変数束縛の設定に用い

るものではない。setq 形式は,defglobal,let,let*,for 又はラムダ式で設定される変数 var の有効範囲の中

に含まれていなければならない。

例  (defglobal x 2)

⇒ x

(+ x 1)

⇒ 3

(setq x 4)

⇒ 4

(+ x 1)

⇒ 5

(let ((x 1)) (setq x 2) x)

⇒ 2

(+ x 1)

⇒ 5

(setf place form)  →<object>

特殊演算子

setf 形式は,一般化された代入に使う。

setf 形式は,場所を指定する place を受け取り,評価形式 form の評価結果をその場所に格納する。評価

形式 place は,全体が評価されるのではなく,結果を格納する場所を決定するために,place の部分形式が

左から右に順に評価される。place が識別子で表される場合には,setf は setq と全く同じ動作をする。setf

形式は,form の評価結果を返す。setf 形式の正しい場所指定は,次のとおりとする。

変数

var

動的束縛 (dynamic

var)

配列の要素 (aref

basic-array z

1

...z

n

)

一般配列の要素 (garef

general-array z

1

...z

n

)

リストの要素 (elt

list z)

ベクタの要素 (elt

basic-vector z)

コンスの car 要素 (car

cons)

コンスの cdr 要素 (cdr

cons)

記号の属性 (property

symbol property)

クラスのインスタンスのスロット

(reader-function-name instance)

ここで,reader-function-name は,: accessor 任意機能(7.1 参照)に指定した識別子とする。

また,場所指定は,

(実行準備の段階で)場所指定に展開されるマクロ形式であるか,setf が定義されて

いる演算子の関数適用形式であるか,又は (setf op)  という名前の包括関数が定義されている演算子 op 

関数適用形式であってよい。後の二つの場合には,その関数は引数として,代入される新しい値と関数適

用形式の引数を評価して得られたオブジェクトとを受け取る。


27

X 3012 : 1998 (ISO/IEC 13816 : 1997)

例  (setf (car x) 2)

⇒ 2

コンス x において,その car は 2 となる。

(defmacro first (spot)

  ’(car ,spot))

⇒ first

(setf (first x) 2)

⇒ 2

コンス x において,その car は 2 となる。

(let ((var form)

*

body-form

*

)  →<object>

特殊演算子

let 形式は,一連の評価形式 body-form*(まとめて body と呼ぶ。)に対して,識別子の有効範囲を定義す

るために使われる。対のリスト  (var form)*は,let 変数リストと呼ばれる。識別子 var の有効範囲は,body

とする。

let 変数リスト中の各 form は,左から右に順に評価される。そして識別子 var で表される各変数は,対応

する値に初期化される。これらの束縛と,既存の束縛とを使って,body-form*が順に評価される。let の返

り値は,本体の最後の body-form を評価した結果(body-form がない場合は,nil)とする。

同じ var が,let 変数リストに 2 回以上現れてはならない。

備考  この形式は特殊形式であるが,書換え規則が次のように定義されたマクロと考えてもよい。

(let ( ) body-form*)

(progn body-form*) (

3

)

(let ((var

1

 form

1

)

((lambda (var

1

 var

2

 ... var

n

body-form*)

      (var

2

 form

2

)

  form

1

 form

2

 ... form

n

) (

4

)

    ...

      (var

n

 form

n

))

body-form*)

(

3

)  progn

の定義については,6.5参照。

(

4

) lambda

の定義については,4.7 参照。

例  (let ((x 2) (y 3))

  (* x y))

⇒ 6

(let ((x 2) (y 3))

  (let ((x 7)

         (z (+ x y)))

    (* z x)))

⇒ 35

(let ((x 1) (y 2))

  (let ((x y) (y x))

    (list x y)))

⇒ (2  1)

(let* ((var form) *) body-form*)  →<object>

特殊演算子

let*形式は,一連の評価形式 body-form*(まとめて body と呼ぶ)に対して,識別子の有効範囲を定義す


28

X 3012 : 1998 (ISO/IEC 13816 : 1997)

るために使われる。最初の部分形式(let*変数リスト)は,対  (var form)  のリストとする。識別子 var の有

効範囲は,本体 body 及び let*変数リスト中の対  (var form)  の後のすべての form とする。

各対  (var form)  に対して次が実行される。その時点で有効な束縛の文脈で,form が評価される。評価結

果は,識別子 var を名前とする変数に束縛される。これらの変数束縛は,現在有効な識別子の集合を拡大

する。場合によっては(同じ名前の変数が外側で定義されている場合)

,以前の変数束縛を遮へいする。そ

して,この拡大又は修正された環境で,body-form*が順に評価される。let*の返り値は,本体の最後の

body-form

の評価結果(body-form がなければ nil)とする。

備考  この形式は特殊形式であるが,書換え規則が次のように定義されたマクロと考えてもよい。

(let* () body-form*)

(progn body-form*)

(let* ((var

1

 form

1

)

(let ((var

1

 form

1

))

      (var

2

 form

2

)

  (let ((var

2

 form

2

))

     ...

    ...

      (var

n

 form

n

))

      (let ((var

n

 form

n

))

body-form*)

          body-form*)...)

例  (let ((x 2) (y 3))

  (let* ((x 7)

          (z (+ x y)))

    (* z x)))

⇒ 70

(let ((x 1) (y 2))

  (let* ((x y) (y x))

    (list x y)))

⇒ (2  2)

6.3

動的変数  動的変数は,動的変数の名前空間における識別子 var と ISLISP オブジェクトとの結合と

する。動的変数は,動的束縛を実装する。

動的変数は,defdynamic によって大域的に定義されるか,又は dynamic-let の実行によって設定される。

defdynamic で定義された動的変数束縛は無限に存在し続ける。これに対して,dynamic-let で設定された

動的変数束縛は,この特殊形式の実行の終了によって消滅する。

動的変数の値は, (dynamic var)  によって参照できる。

(dynamic var)  →<object>

特殊演算子

この特殊形式は,動的変数の参照を表す。この特殊形式は,defdynamic 又は dynamic-let で定義された変

数 var の存在期間内だけで使用できる。

活動中,最も近くに設定され,かつ,現在も有効な変数 var の動的束縛の値が返される。そのような束

縛が存在しない場合は,エラーが発生する(エラー名 unbound-variable

(setf (dynamic varform)  →<object>

特殊形式

この特殊形式は,動的変数への代入を表す。この特殊形式は, (dynamic var)  が使用できるところなら,

どこででも使うことができる。

form

が評価され,その結果が変数 var の動的束縛を変更するために使用される。変数 var が動的な値を

もたない場合は,エラーが発生する(エラー名 unbound-variable

。dynamic に対する setf は,束縛の変更


29

X 3012 : 1998 (ISO/IEC 13816 : 1997)

にだけ用いられ,束縛の設定には用いられない。

(dynamic-let ((var form)*)body-form*)  →<object>

特殊演算子

dynamic-let 形式は,動的変数束縛の設定に使われる。最初の部分式(dynamic-let 変数リスト)は,対  (var 

form)

のリストとする。dynamic-let で定義される識別子 var の有効範囲は,最上位有効範囲全体とする。

各 var の束縛の存在期間は,dynamic-let の本体の実行中とする。dynamic-let 形式は,指定されたすべての

var

に対する動的変数束縛を設定する。

var

という名前の動的変数への参照は,dynamic 形式を使って行わなければならない。

すべての初期化形式は,左から右に順に評価され,値はそれぞれ対応する var と対応付けられる。これ

らの追加された動的束縛及び既に存在する可視な識別子の束縛を使って,評価形式 body-form*が順に評価

される。

dynamic-let の返り値は,本体の最後の body-form の値(body-form がない場合は,nil)とする。dynamic-let

から制御が離れるときに束縛は解消される。

例  (defun foo (x)

  (dynamic-let ((y x))

    (bar 1)))

⇒ foo

(defun bar (x)

  (+ x (dynamic y)))

⇒ bar

(foo 2)

⇒ 3

6.4

条件式

(if test-form then-form [else-form])  →<object>

特殊演算子

if 形式は,まず test-form を評価する。その結果が nil 以外の値であれば,then-form を評価し,その値を

返す。そうでなければ(もし test-form が nil を返すならば)

else-form を評価し,その値を返す。

else-form

がない場合は,nil が省略されたものとする。

例  (if (> 3 2) ’yes ’no)

⇒ yes

(if (> 2 3) ’yes ’no)

⇒ no

(if (> 2 3) ’yes)

⇒ nil

(if (>3 2) (- 3 2) (+ 3 2))

⇒ 1

(let ((x 7))

  (if (< x 0) x (- x)))

⇒ -7

(cond (test form*)*)  →<object>

特殊演算子

cond の実行では,節  (test form*)  を順に走査し,各節の test を評価する。test が nil 以外の値を返せば,

走査を停止し,対応する節の form*が順に評価され,その最後の form の値が返される。どの test の値も真

でなければ,nil が返される。test が真である節に form が一つもなければ,test の値が返される。

cond 形式は,次と同値とする。

(cond)

≡ nil

(cond (test

1

)

≡ (or

test

1

      (test

2

 form

2

*)

   (cond (test

2

 form

2

*)

        ...)

            ...))


30

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(cond (test

1

 form

1

)

≡ (if

test

1

      (test

2

 form

2

*)

   (progn form

1

)

          ...)

   (cond (test

2

 form

2

*)

            ...))

例  (cond ((> 3 2) ’greater)

       ((< 3 2) ’less))

⇒ greater

(cond ((> 3 3) ’greater)

       ((< 3 3) ’less))

⇒ nil

(cond ((> 3 3) ’greater)

       ((< 3 3) ’less)

       (t        ’equal))

⇒ equal

(case keyform ((key*) form*)* [(t form*)])  →<object>

特殊演算子

(case-using predform keyform ((key*) form*)* [ (t form*)])  →<object>

特殊演算子

case 形式及び case-using 形式は,分類形式 (case form) と呼ばれ,一連の節の中から評価形式 keyform 

値に一致する節を実行する機構を提供する。

実行される節は,キーの集合で識別される。キーkey は,いかなるオブジェクトでもよい。最後の節の

キーリストが t である場合は,いずれのキーも keyform に一致しないときに,その最後の節が実行される。

keyform

は,分類形式の実行開始時に計算される評価形式とする。keyform の評価結果が key と一致すれ

ば,対応する節内の評価形式が順に評価され,最後の値が分類形式全体の値として返される。case は,一

致するかどうかを eql によって判断する。case-using は,一致の判断を predform の評価結果を用いて行う。

predform

は,keyform の評価結果と key とを引数として受け取る真偽値関数又は準真偽値関数でなければな

らない。一致した key に form がなければ,分類形式は nil を返す。keyform の値がすべての key と異なり,

かつ最後の節のキーリストが t であれば,その節の評価形式が順に評価され,最後の評価形式の値が分類

形式の結果となる。keyform の値がすべての key と異なり,かつ最後の節のキーリストが t でなければ,分

類形式は nil を返す。

一つの分類形式では,同じ key は 2 回以上現れてはならない。

例  (case (* 2 3)

  ((2 3 5 7) ’prime)

  ((4 6 8 9) ’composite))

⇒ composite

(case (car ’(c d))

  ((a) ’a)

  ((b) ’b))

⇒ nil

(case (car ’(cd))

  ((a i u e o) ’vowel)


31

X 3012 : 1998 (ISO/IEC 13816 : 1997)

  ((y) ’semivowel)

  (t ’consonant))

⇒ consonant

(let ((char #

\u))

  (case char

    ( (#\a #\i #\u #\e #\o) ’vowels)

    (t ’consonants)))

⇒ vowels

(case-using #’= (+ 1.0 1.0)

  ((1) ’one)

  ((2) ’two)

  (t ’more))

⇒ two

(case-using #’string= "bar"

  (("foo") 1)

  (("bar") 2))

⇒ 2

6.5

評価形式の逐次実行

(progn form*)  →<object>

特殊演算子

progn 形式は,form*を順に評価し,その最後の評価形式の評価結果を返す。すべての form が,左から右

に順に評価される。最後の評価形式以外のすべての form の値は,破棄される。したがって,それらの評価

形式は,副作用のためだけに実行される。form をもたない progn は,nil を返す。

例  (defglobal x 0)

⇒ x

(progn

  (setq x 5)

  (+ x 1))

⇒ 6

(progn

  (format (standard-output) "4 plus 1 equals")

  (format (standard-output) "

~

D" (+ 4 1)))

⇒nil

これは,4 plus 1 equals 5 を印字する。

6.6

繰返し

(while test-form body-form*)  →<null>

特殊演算子

while 形式は,test-form が真を返す間,body-form*の実行を繰り返す。詳細を次に示す。

a)

test-form

を評価する。その値を V

t

とする。

b)  V

t

が nil であれば,while 形式は直ちに nil を返す。

c)

V

t

が nil 以外の値であれば,一連の評価形式 body-form*を左から右に順に評価する。

d)  body-form*

の評価が正常に終了した場合,while 形式は再び a)から実行する。

例  (let ((x ’()) (i 5))


32

X 3012 : 1998 (ISO/IEC 13816 : 1997)

  (while (> i 0) (setq x (cons i x)) (setq i (- i 1)))

  x)

⇒ (1 2 3 4 5)

(for (iteration-spec*) (end-test result*) form*)  →<object>

特殊演算子

ここで,

iteration-spec ::=

(var init [step])

for 形式は,本体と呼ばれる評価形式の並び form*を繰り返し実行する。for 形式には,局所的な変数を表

す識別子の集合,それらの変数の初期化及び繰返しごとの更新を指定する。終了条件が満たされる場合,

繰返しを終了し,指定された値を返す。

各識別子 var の有効範囲は,本体,すべての stepend-test 及び result*とする。step は省略でき,その場

合の効果は,  (var init)  の代わりに  (var init var)  と書いたものと同じとする。

for 形式は,次のとおり実行される。各 init 形式が,左から右に順に評価される。そして,各値は,対応

する識別子 var で表される変数の初期値として使われ,繰返しが開始される。

各繰返しは,end-test の評価で始まる。結果が nil であれば,本体の評価形式が順に評価される。これら

の評価形式の値は,破棄される。次に各 step 形式が左から右に順に評価され,それらの値が対応する変数

に代入され,次の繰返しが開始される。end-test が nil 以外の値を返せば,result*が左から右に順に評価さ

れ,最後の値が for 形式の値として返される。result が一つもなければ,for 形式の値は nil とする。

例  (for ((vec (vector 0 0 0 0 0))

       (i 0 (+ i 1)))

      ((= i 5) vec)

  (setf (elt vec i) i))

⇒ #(0 1 2 3 4)

(let ((x ’(1 3 5 7 9)))

  (for ((x x (cdr x))

         (sum 0 (+ sum (car x))))

        ((null x) sum)))

⇒ 25

6.7

非局所的脱出

6.7.1

非局所的脱出の設定及び起動  ISLISP では,非局所的脱出を実行する次の三つの方法を定義する。

脱出先の指定

設定する評価形式 起動する評価形式 動作

ブロック名 block

return-from

静的脱出

捕そくタグ catch

throw

動的脱出

タグ本体のタグ tagbody

go

制御の静的移行

非局所的脱出 (non-local exit) は,それを起動した特殊形式から,脱出先 (destination) と呼ばれるプログ

ラム内のあらかじめ設定された位置へ制御を移行し,場合によってはデータの転送も行う操作とする。

静的脱出 (lexical exit) は,return-from 形式から,それを静的にも動的にも含んでいる block 形式への非

局所的脱出であり,block 形式が return-from に指定されたオブジェクトを返すようにする。

動的脱出 (dynamic exit) は,throw 形式から,それを動的に(しかし必ずしも静的ではなく)含む catch

形式への非局所的脱出であり,catch 形式が throw 形式に指定されたオブジェクトを返すようにする。

制御の静的移行  (lexical transfer of control)  は,go 形式から,それを静的にも動的にも含んでいる tagbody


33

X 3012 : 1998 (ISO/IEC 13816 : 1997)

内のタグ付き位置への非局所的脱出とする。

非局所的脱出が起動されると,制御が移行される脱出先よりも後に設定された脱出先は,直ちに無効と

なる。

(block name form

*

)  →<object>

特殊演算子

(return-from name result-form)  制御の移行及びデータの転送

特殊演算子

block 形式は,form*を左から右に順に実行する。最後の form が正常に終了した場合,それが返す値が block

形式の返す値とする。

block 形式の name は評価されない。それは識別子でなければならない。name の有効範囲は,本体 form*

とする。すなわち,いずれかの form にテキスト上で含まれる return-from 形式だけが,そのブロックを脱

出できる。name に対する束縛は,動的存在期間をもつ。

return-from 形式が実行されると,result-form が評価される。評価が正常に終了すれば,その値は,

return-from の呼出しを静的に含み,同じ name をもつ最も内側の block 形式の値として返される。

return-from 形式は,block から戻るために使う。return-from 形式の name は評価されず,識別子でなけれ

ばならない。同じ name をもつ block が,return-from の呼出しを静的に含んでいなければならない。

result-form

が生成する値は,対応する block 形式から直ちに返される。return-from は,戻ることはなく,

また値をもたない。

block を出た後で,その block から脱出しようとする場合は,エラーが発生する(エラー名 control-error)。

name

が識別子でない場合は,違反とする。対応する名前をもつブロックが存在しない場合も,違反とす

る。その他のエラーについては,6.7.2 参照。

例  (block x

  (+ 10 (return-from x 6) 22)) ;;;悪いプログラム書法

⇒ 6

(defun f1 ()

  (block b

    (let ((f (lambda () (return-from b ’exit))))

       …  ; 大規模計算

      (f2 f))))

⇒ f1

(defun f2 (g)

   …  ; 大規模計算

  (funcall g))

⇒ f2

(f1)

⇒ exit

(block sum-block

  (for ((x ’(1 a 2 3) (cdr x))

         (sum 0 (+ sum (car x))))

        ((null x) sum)

    (cond ((not (numberp (car x))) (return-from sum-block 0))))))

⇒ 0


34

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(defun bar (x y)

  (let ((foo #’car))

    (let ((result

             (block  b1

               (setq foo (lambda () (return-from b1 ’first-exit)))

               (if x (return-from b1 ’second-exit) ’third-exit))))

      (if y (funcall foo) nil)

      result)))

⇒ bar

(bar t nil)

⇒ second-exit

(bar nil nil)

⇒ third-exit

(bar nil t)

エラーが発生する。

(bar t t)

エラーが発生する。

(catch tag-form form*)  →<object>

特殊演算子

(throw tag-form result-form)  制御の移行及びデータの転送

特殊演算子

catch 形式及び throw 形式は,構造化された動的な非局所的脱出機能を提供する。catch 形式及び throw 形

式は,catch の tag-form 及び throw の tag-form の評価結果が,同一のオブジェクトになる場合,対応すると

呼ばれる。このオブジェクトを

捕そくタグ (catch tag) と呼ぶ。捕そくタグは,数値及び文字以外のいかな

るオブジェクトでもよい。捕そくタグの比較は,eq で行う。

catch 形式は,まず tag-form を評価して捕そくタグを生成し,次に各 form を左から右に順に実行する。

すべての form の実行が正常に終了した場合,最後の form の返す値が,catch 形式の値として返される。

catch 形式 C

0

の form*の実行に先立って,捕そくタグ T

0

と実行する評価形式 C

0

との間の対応が動的に設

定され,C

0

の実行終了時にこの対応は解除される。同じ捕そくタグ T

0

に対して外側の対応があれば,それ

は C

0

の form*の実行中は遮へいされる。すなわち,T

0

の最も最近(最も内側)の対応だけが見えるものと

する。

throw 形式が実行されると,tag-form を評価して捕そくタグ T

1

を生成し,次に result-form を評価して結

果 R

1

を生成する。T

1

と実行中のある catch 形式 C

1

との間に対応があれば,C

1

の値として R

1

が直ちに返さ

れる。throw 形式は,最上位有効範囲全体のどこにあってもよい。すなわち,C

1

に静的に含まれている必

要はない。

T

1

に対する catch 形式が存在しない場合は,エラーが発生する(エラー名 control-error

。その他のエラ

ーについては,6.7.2 参照。

例  (defun foo (x)

  (catch ’block-sum (bar x)))

⇒ foo

(defun bar (x)

  (for ((1 x (cdr 1))

         (sum 0 (+ sum (car 1))))

        ((null 1) sum)

    (cond ((not (numberp (car 1))) (throw ’block-sum 0)))))

⇒ bar


35

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(foo ’(1 2 3 4))

⇒ 10

(foo ’(1 2 a 4))

⇒ 0

(tagbody {tagbody-tag | form}*)  →<object>

特殊演算子

(go tagbody-tag)  制御の移行

特殊演算子

tagbody は,各 form を左から右に順に実行し,それらの値を破棄する。最後の form の実行が正常に終了

した場合,tagbody 形式は,nil を返す。

一連の tagbody-tag 及び form は,まとめて tagbody 形式の本体(又は,タグ本体)と呼ぶ。この本体の最

上位に現れる識別子 tagbody-tag は,go によって本体内のその位置に制御を移すために使われる

タグ本体

のタグ (tagbody tag) を表す。本体の最上位に現れる複合形式は,すべて form として扱われる。リテラル

が,タグ本体の最上位にあってはならない。同一の tagbody-tag が,本体内のタグとして 2 回以上現れては

ならない。

タグ本体のタグに使用される名前空間は,ブロックの名前空間とは異なる。

タグ本体に静的に含まれる任意の位置で,評価形式 (go tag)  は,静的原理(3.1 参照)によって遮へい

される場合を除いて,タグ tag に一致する tagbody-tag に制御を移すために使うことができる。

tagbody によって設定されたタグは静的有効範囲をもつが,それが表すプログラム内の位置は,動的存在

期間をもつ。tagbody の実行が終了した後は,go を使ってその本体内のタグ位置に制御を移行してはなら

ない。

本体のどの要素が tagbody-tag であるか,また,どれが form であるかの決定は,その要素のマクロ展開

よりも先に行われる。form がマクロ形式で,かつ,そのマクロ展開結果が記号又はリテラルである場合,

展開結果は tagbody-tag ではなく,form として扱われる。

タグ本体のタグが識別子以外である場合は,違反とする。その他のエラーについては,6.7.2 参照。

備考  利用者が日常のプログラム開発で tagbody 及び go を使用することは望ましくない。これらの評

価形式の主な用法は,

(マクロを使った)他の制御機能を実装する場合及び,実世界で時に必要

となる(有限状態機械のような)構造化されていない命令型の制御移動を実装する場合である。

例  (defmacro with-retry (:rest forms)

  (let ((tag (gensym)))

    ‘(block ,tag

       (tagbody

         ,tag

         (return-from  ,tag

           (flet ((retry () (go ,tag)))

             ,@forms))))))

⇒ with-retry

(let ((i -5))

  (with-retry

    ;; if-error は,仮想的なエラー修正関数であり,

    ;; ISLISP では定義していない。


36

X 3012 : 1998 (ISO/IEC 13816 : 1997)

    (if-error (sqrt (setq i(+ i 4)))

                (retry))))

⇒ 1.7320508075688772

6.7.2

非局所的脱出におけるデータ整合性の保証

(unwind-protect form cleanup-form*)  →<object>

特殊演算子

unwind-protect は,まず form を評価する。cleanup-form*は,form の評価が正常に終了するか又は非局所

的脱出によって終了するかにかかわらず,常に評価される。

form

が正常に終了し,値 を返した場合,すべての cleanup-form が正常に終了したときには,値 

unwind-protect から返される。

form

からの非局所的脱出が発生した場合,cleanup-form*が脱出の一部として実行される。この場合,す

べての cleanup-form が正常に終了すれば,元の非局所的脱出が継続して実行される。

cleanup-form*

は左から右に順に評価され,それらの値は破棄される。cleanup-form*の評価が正常に終了

した場合,unwind-protect からの脱出は上のとおり実行される。cleanup-form は,次の制約のもとに

unwind-protect からの非局所的脱出を行ってもよい。

unwmd-protect 形式の cleanup-form*の実行中に,既に進行中の他の非局所的脱出によって無効となった脱

出先への非局所的脱出を実行した場合は,エラーが発生する(エラー名 control-error

備考 ISLISP は対話型デバッガを規定していないので,プログラムによるエラー処理が失敗した場合

にエラー回復が対話的に行われるか,またどのように行われるかは規定しない。しかし,ISLISP

処理系が異常停止しなければ,非局所的脱出の機構(return-from,throw 又は go)が必要に応じ

て使われ,cleanup-form が実行される。

(defun foo (x)

  (catch ’duplicates

    (unwind-protect (bar x)

      (for ((1 x (cdr 1)))

            ((null 1) ’unused)

        (remove-property (car 1) ’label)))))

⇒ foo

(defun bar (1)

  (cond ((and (symbolp 1) (property 1 ’label))

          (throw ’duplicates ’found))

         ((symbolp 1) (setf (property 1 ’label) t))

         ((bar (car 1)) (bar (cdr 1)))

         (t  nil)))

⇒ bar

(foo ’(a b c))

⇒ t

(property ’a ’label)

⇒ nil

(foo ’(a b a c))

⇒ found

(property ’a ’label)

⇒ nil

(defun test ()


37

X 3012 : 1998 (ISO/IEC 13816 : 1997)

  (catch ’outer (test 2)))

⇒ test

(defun test2 ()

  (block inner

    (test3 (lambda () (return-from inner 7)))))

⇒ test2

(defun test3 (fun)

  (unwind-protect (test4) (funcall fun)))

⇒ test3

(defun test4 ()

  (throw ’outer 6))

⇒ test4

(test)

エラーが発生する。

この test の例では,test4 内で実行された throw の脱出先は,test 内の catch 形式である。test3 に

おける unwind-protect は,制御の移行を横取りし,test2 における block からの return-from を実行

しようとする。この block は,脱出先である catch 形式の動的存在期間内で設定されているので,

エラーが通知される。

7.

オブジェクト指向機能

7.1

クラスの定義  defclass 定義形式は,新しい名前付きクラスを定義する。

クラス定義は,次のものを含む。

・  新しいクラスの名前。

・  新しいクラスの直接の上位クラスのリスト。

スロット指定 (slot specifier) の集合。それぞれのスロット指定は,そのスロットの名前及び 0 個以上

スロット任意機能 (slot option) を含む。一つのスロット任意機能は,一つのスロットだけに対する

指示とする。クラス定義は,同じ名前のスロット指定を二つ以上含んではならない。

クラス任意機能 (class option) の集合。それぞれのクラス任意機能は,そのクラス全体に対する指示と

する。

defclass 定義形式のスロット任意機能及びクラス任意機能は,次の機構を提供する。

・  スロットの初期値を与える評価形式を指定する機構。インスタンス生成時に,そのスロットの初期値

が明示的に与えられなかった場合は,スロット任意機能で指定した評価形式の値が初期値となる。

・  スロットの値を取り出すメソッド,スロットに値を格納するメソッド及びスロットに値が束縛されて

いるどうかを判定するメソッドが,自動的に生成されることを要求する機構。

・  そのクラスのメタクラスを指定する機構。

・  そのクラスが抽象クラスであるかどうかを指定する機構。

(defclass class-name (sc-name*) (slot-spec*) class-opt*)  →<symbol>

定義演算子

ここで,

class-name ::=

identifier

sc-name ::=

identifier

slot-spec ::=

slot-name | (slot-name slot-opt*)

slot-name ::=

identifier


38

X 3012 : 1998 (ISO/IEC 13816 : 1997)

slot-opt ::=

:

reader

reader-function-name |

:

writer

writer-function-name |

:

accessor

reader-function-name |

:

boundp

boundp-function-name |

:

initform

form |

:

initarg

initarg-name

reader-function-name ::= identifier

writer-function-name

::=

identifier

boundp-function-name ::= identifier

initarg-name ::=

identifier

class-opt ::=

(:

metaclass

metaclass-name) |

(:

abstractp

abstract-flag)

metaclass-name ::=

identifier

obstract-flag ::=

|

nil

defclass 定義形式は,実行結果として class-name という名前の記号を返す。

引数 class-name は識別子であり,新しいクラスの名前となる。class-name の定義位置は,defclass 定義形

式の直後とする。

引数 sc-name のそれぞれは,識別子であり,新しいクラスの直接の上位クラスを指定する。新しいクラ

スは,それぞれの上位クラスからスロットを継承し,スロットの : reader,: writer,: accessor 及び : boundp

メソッドを継承する。スロットの継承方法は 7.1.3 において,メソッドの継承方法は 7.2.3 において規定す

る。同じ sc-name が,上位クラス名として 2 回以上現れてはならない。sc-name のうちのいずれか二つが,

<standard-object>及び<object>以外の上位クラスを共通にもつ場合は,違反とする。ただし,<standard-class>

以外のメタクラスが指定された場合を除く。

引数 slot-spec のそれぞれは,スロットの名前か又はスロット名の後に 0 個以上のスロット任意機能を伴

ったリストとする。引数 slot-name は,識別子でなければならない。同じスロット名が,二つ以上の slot-spec

に現れてはならない。

次のスロット任意機能が使用できる。

・ :

reader 任意機能は,そのスロットの値を取り出すために,パラメタ記述 ((x class-name))  を伴った修

飾なしメソッドを,reader-function-name という名前の包括関数に対して定義することを指示する。引

数 reader-function-name は,識別子でなければならない。: reader 任意機能は,一つのスロットに対して

複数回指定してもよい。

・ :

writer 任意機能は,そのスロットに値を格納するために,パラメタ記述 ((<object>) (x class-name))  を

伴った修飾なしメソッドを,writer-function-name という名前の包括関数に対して定義することを指示

する。引数 wirter-function-name は,識別子でなければならない。: writer 任意機能は,一つのスロット

に対して複数回指定してもよい。

・ :

accessor 任意機能は,そのスロットの値を取り出すために,パラメタ記述 ((x class-name))  を伴った

修飾なしメソッドを,reader-function-name という名前の包括関数に対して定義することを指示する。

さらに,次のような包括関数を(もしなければ)定義する。その包括関数を,第 1 引数を y,第 2 引

数を として呼び出すことと,

 (setf (reader-function-name x) y)  とが同値となる。その包括関数に対し,

パラメタ記述 ((y  <object>) (x class-name))  を伴ったメソッドが定義される。引数 reader-function-name


39

X 3012 : 1998 (ISO/IEC 13816 : 1997)

は,識別子でなければならない。: accessor 任意機能は,一つのスロットに対して複数回指定してもよ

い。

・ :

boundp 任意機能は,そのスロットが既に束縛されているかどうかを判定するために,パラメタ記述

((x class-name))  を伴った修飾なしメソッドを,boundp-function-name という名前の包括関数に対して定

義することを指示する。引数 boundp-function-name は,識別子でなければならない。: boundp 任意機能

は,一つのスロットに対して複数回指定してもよい。

・ : initform 任意機能は,そのスロットの初期化時に用いられる

省略時初期値形式 (default initial value

form)  を指定する。この任意機能は,一つのスロットに対して高々1 回しか指定してはならない。こ

の初期値形式は,スロットを初期化するたびに評価される。スロットの初期化に用いられる識別子の

静的有効範囲は,defclass 形式中におけるそれらの識別子の静的有効範囲とする。静的有効範囲は,変

数識別子及び関数識別子の両方に対して適用される。一方,現在の動的束縛としては,create(7.4.1

参照)の実行中に存在しているものが用いられる。

・ :

initarg 任意機能は,initarg-name という名前の初期化引数 (initialization argument) を宣言し,この初

期化引数がそのスロットを初期化することを指定する。initialize-object に渡された初期化リスト(7.4

参照)が,初期化引数及びそれに付随する値を含む場合は,その値が,スロットに格納される。この

場合,スロットに : initform 任意機能が指定されていても,省略時初期値形式は,評価されない。初

期化リストがそのような初期化引数を含まない場合,: initform 任意機能が指定されていれば,それに

従ってスロットが初期化される。初期化リストが,同じスロットに対する複数の初期化引数を含む場

合は,結果は未定義とする。詳細については,7.4.1 による。: initarg 任意機能は,同じスロットに対

して複数回指定してもよい。

: reader,: writer 及び : accessor のスロット任意機能によって生成されたメソッドを,それぞれ: reader メ

ソッド,: writer メソッド及び: accessor メソッドと呼び,これらのメソッドが属する包括関数を

スロットア

クセス関数  (slot accessor)  と呼ぶ。: boundp 任意機能によって生成されたメソッドを: boundp メソッドと呼

ぶ。

処理系は,  (slot-name form)  が  (slot-name : initform form)  の省略形となるように defclass の構文を拡張し

てはならない。

引数 class-opt は,クラス任意機能を指定する。これは,クラス全体に対する指示とする。次のクラス任

意機能が使用できる。

・ : metaclass 任意機能は,定義しようとしているクラスが,システムの提供する省略時のメタクラス

<standard-class>とは異なるメタクラスをもつことを指示する。引数 metaclass-name は,メタクラスの

名前とする。: metaclass 任意機能は,高々1 回しか指定してはならない。<built-in-class>がメタクラス

として指定された場合は,違反とする。

・ :

abstractp 任意機能は,そのクラスが抽象クラスかどうかを指示する。この任意機能が指定され,かつ

abstract-flag

が t の場合,このクラスの直接インスタンスを生成しようとしたとき,create がエラーを

通知する。この任意機能が指定されない場合又は abstract-flag が nil の場合,そのクラスは,抽象クラ

スではない。t 及び nil 以外の abstract-flag が指定された場合は,違反とする。

標準クラスにおいては,defclass に関して次の規則が成り立たなければならない。

・ defclass 定義形式は,それが参照する上位クラス識別子の有効範囲内になければならない。

・  クラスは,そのインスタンスが生成される前に定義されていなければならない。

・ defmethod 形式の中で,

パラメタ特殊化指定として class-name を使用する場合,

その defmethod 形式は,


40

X 3012 : 1998 (ISO/IEC 13816 : 1997)

class-name

の有効範囲内になければならない。すなわち,クラスの名前を用いる defmethod 形式は,

そのクラスを定義する defclass 形式よりもテキスト上で後になければならない。

ISLISP 処理系を,これらの規則に適合しない状況にも対処できるように拡張してもよい。そのような拡

張は,処理系定義とする。

スロット任意機能は,上位クラスから下位クラスへ継承されたり,別のスロット記述によって遮へい又

は変更されることがある。しかし,クラス任意機能は,継承されない。スロット及びスロット任意機能の

継承については,7.1.3 による。

スロットにスロットアクセス関数が指定されていない場合,そのスロットにはアクセスできない。

クラスを定義する場合,その定義形式の中で,直接の上位クラスを指定する順序が重要となる。新しい

クラスは,

局所的優先順位  (local precedence order)  をもつ。これは,クラスが並べられたリストであり,

その順序は,最初にその新しいクラス,次に直接の上位クラスをその defclass 定義形式に指定された順序

で並べたものとする。

7.1.1

クラス優先度リストの決定  クラス のクラス優先度リスト  (class precedence list)  とは,及びそ

のすべての上位クラスに関する全順序であり,及びその上位クラスの局所的優先順位と矛盾しないもの

とする。すなわち,それぞれの局所的優先順位の中に現れるクラスは,クラス優先度リストの中に同じ順

序で現れるものとする。

C

1

,...,C

n

を,の直接の上位クラスとする。C

1

,...,C

n

は,この順序で C の defclass 定義形式に指定

されているとする。C

1

,...,C

n

のクラス優先度リストを,それぞれ P

1

,...,P

n

とする。Pを,クラス優

先度リスト と とを連結したリスト又はクラス優先度リスト の先頭にクラス を追加したリストと

定義する。このとき,のクラス優先度リストは,CP

1

○...○P

n

から,重複を除去したリストとする。連結

結果のリストに,あるクラスが 2 回現れた場合には,その左側を除去する。

標準クラスを定義するとき,その直接の上位クラスのもつクラス優先度リストの間に,<standard-object>

及び<object>以外のクラスが共通に含まれている場合は,違反とする。

7.1.2

スロットのアクセス  defclass 定義形式によって生成又は変更されたスロットアクセス関数を用い

て,スロットをアクセスできる。

defclass 定義形式には,スロット値の取出し及び格納を行うメソッドを生成するための任意機能を指定で

きる。: reader 任意機能を指定した場合,スロットの値を取り出すメソッドが自動的に生成される。ただし,

値を格納するメソッドは生成されない。: writer 任意機能を指定した場合,スロットに値を格納するメソッ

ドが自動的に生成される。ただし,値を取り出すメソッドは生成されない。: accessor 任意機能を指定した

場合,スロットの値を取り出すメソッド及び値を格納するメソッドが自動的に生成される。

: reader 又は : writer 任意機能をスロットに指定する場合,生成されるメソッドが属する包括関数の名前

を,直接指定する。: writer 任意機能に対して指定した名前が識別子 name の場合,スロットへ値を格納す

るための包括関数の名前は識別子 name であり,この包括関数は,新しい値及びインスタンスという二つ

の引数をこの順序で受け取る。: accessor 任意機能に対して指定した名前が識別子 name の場合,スロット

値を取り出す包括関数の名前は識別子 name であり,スロットへの値の格納は, (setf (name  instance)

new-value)

という構文によって行われる。ここで,instance はそのスロットをもつインスタンスとし,

new-value

は新しい値とする。

: reader,: writer,: accessor 及び : boundp の任意機能を指定することによって生成又は変更される包括関

数は,<standard-generic-function>の直接インスタンスとする。


41

X 3012 : 1998 (ISO/IEC 13816 : 1997)

7.1.3

スロット及びスロット任意機能の継承  クラス のインスタンス中でアクセス可能なすべてのス

ロット名の集合は,及びその上位クラスで定義されたスロット名の和集合とする。インスタンスの

構造

(structure)  とは,そのインスタンス中のすべてのスロット名の集合とする。

最も単純な場合,ある名前のスロットは,又はその上位クラスのいずれか一つのクラスだけで定義さ

れている。スロットが の上位クラスで定義されている場合,そのスロットは,

継承 (inherit) されている

という。そのスロットの特性は,それを定義しているクラスのスロット指定によって決定される。

一般的には,及びその上位クラスの複数のクラスにおいて,同じ名前のスロットが定義されている可

能性がある。その場合,その名前のただ一つのスロットだけが,のインスタンス中でアクセス可能とな

り,そのスロットの特性は,幾つかのスロット指定を次の規則に従って組み合せることによって決定され

る。

・  あるスロット名に対するすべてのスロット指定は,のクラス優先度リスト中の順序に従って,優先

度の高い指定から低い指定の順に並べられる。次で用いるスロット指定の優先度とは,この順序を意

味する。

・  スロットの省略時初期値形式は,: initform 任意機能を含むスロット指定のうちで最も優先度の高いス

ロット指定に与えられた省略時初期値形式とする。いずれのスロット指定も: initform 任意機能を含ま

ない場合は,そのスロットは省略時初期値形式をもたない。

・  スロットの初期化引数は,: initarg 任意機能を含むスロット指定に与えられたすべての初期化引数の和

集合とする。いずれのスロット指定も: initarg 任意機能を含まない場合は,そのスロットは初期化引数

をもたない。

: reader,: writer,: accessor 及び : boundp 任意機能は,メソッドを生成するのであって,スロットの特性

を定義するのではない。これらによって生成されるメソッドは,7.2.3 で規定する意味で,継承される。

7.2

包括関数  包括関数 (generic function) は,呼び出されたときの振る舞いが,引数のクラスによって

決定される。包括関数オブジェクトは,メソッドの集合,ラムダリスト,メソッド組合せの方法及びその

他の情報からなる。メソッドは,包括関数のクラスごとの振る舞い及び操作を定義する。このため,メソ

ッドは,包括関数を

特殊化 (specialize) するという。包括関数は,呼び出されると,引数のクラスに基づ

いてメソッド集合の部分集合を実行する。

包括関数は,通常の関数と同様に使用できる。

メソッド (method) は,メソッドの本体,そのメソッドがいつ適用可能かを指定するパラメタ特殊化指

定 (parameter specializer) を含むパラメタ記述の並び,及びメソッド組合せ機能がメソッドを区別するため

に用いる

修飾子 (qualifier) の並びからなる。メソッドのそれぞれの必すパラメタは,付随するパラメタ特

殊化指定をもち,それらのパラメタ特殊化指定を満たす引数に対してそのメソッドが起動される。

メソッド組合せ機能は,メソッドの選択,それらを起動する順序及び包括関数の返す値を制御する。

ISLISP では,標準的なメソッド組合せ方法は定義するが,メソッド組合せの新しい方法を定義するための

機能は規定しない。

通常の関数と同様に,包括関数も引数を受け取り,一連の操作を実行し,値を返す。通常の関数は,そ

れが呼び出されたときに必ず実行される本体のコードをただ一つもつ。包括関数は,本体コードの集合を

もち,その中から空でない部分集合が選択されて実行される。包括関数への引数のクラス及びそのメソッ

ド組合せ方法が,本体コードの選択方法及びそれらの組合せ方法を決定する。

(generic-function-p obj)  →真偽値

関数


42

X 3012 : 1998 (ISO/IEC 13816 : 1997)

関数 generic-function-p は,obj が包括関数である場合は t を返し,それ以外の場合は nil を返す。obj は,

いかなる ISLISP オブジェクトでもよい。

7.2.1

包括関数の定義  包括関数を明示的に定義するには,defgeneric 形式を使用する。defgeneric 形式に

は,メソッド組合せの方法などの,包括関数の特性を指定することができる。また,: reader,: writer,: accessor

及び : boundp 任意機能によって,defclass 形式が暗黙のうちに包括関数を定義することができる。

包括関数に対してメソッドを定義する評価形式は,

メソッド定義形式 (method-defining form) と呼ばれ,

これには defmethod 形式及び defclass 形式がある。メソッドは,defgeneric 形式によっても定義できるが,

この規格では,defgeneric 形式はメソッド定義形式に含めない。

実行準備においては,defmethod 形式は,特殊化しようとする包括関数の defgeneric 形式より後になけれ

ばならない。ただし,defclass 形式が定義する : reader メソッド,: writer メソッド,: accessor メソッド及

び : boundp メソッドに対しては,対応する包括関数を定義する defgeneric 形式を与える必要はない。

(defgeneric func-spec lambda-list {option | method-desc}*)  →<object>

定義演算子

ここで,

func-spec ::=

identifier | (setf identifier)

lambda-list ::=

(var* [&rest var]) |

(var* [: rest var])

option ::=

(:

method-combination

{identifier | keyword}) |

(:

generic-function-class

class-name)

method-desc ::=

(:

method method-qualifierparameter-profile form*)

method-qualifier ::=

identifier | keyword

parameter-profile ::=

({var | (var parameter-specializer-name)}* [{&rest | : rest} var])

parameter-specializer-name ::=

 class-name

class-name ::=

identifier

var ::=

identifier

defgeneric 形式は,包括関数を定義するために用いる。この定義形式は,包括関数名 func-spec を返す。

包括関数名 func-spec における識別子 identifier の有効範囲は,最上位有効範囲全体とする。

引数 lambda-list は,4.7 による。

引数 option は,次のいずれかの任意機能とする。それぞれの任意機能は,高々1 回しか指定してはなら

ない。

・ : method-combination 任意機能は,メソッド組合せ方法の名前である記号又はキーワードを指定する。

組込みのメソッド組合せ方法の名前には,nil 及び standard がある。

・ : generic-function-class 任意機能は,システムの提供する省略時クラス<standard-generic-function>以外の

クラスに包括関数が属することを指定する。引数 class-name は,包括関数のクラスになりうるクラス

の名前とする。

引数 method-desc は,

メソッド記述 (method description) と呼ばれ,包括関数に属するメソッドを,

defmethod に よ っ て 定 義 し た か の よ う に 定 義 す る 。 メ ソ ッ ド 記 述 中 の 引 数 method-qualifier 及 び

parameter-profile

は,defmethod のそれと同じとする。引数 form*は,メソッドの本体を指定する。

メソッド記述が指定されない場合,

メソッドをもたない包括関数が生成される。包括関数が呼び出され,

適用するメソッドがない場合は,エラーが発生する。


43

X 3012 : 1998 (ISO/IEC 13816 : 1997)

defgeneric の引数 lambda-list は,この包括関数に対するメソッドのパラメタ記述の形を指定する。包括

関数のすべてのメソッドは,この lambda-list と合同なパラメタ記述をもたなければならない。ここでの合

同の定義は,7.2.2.2 による。

処理系は,これ以外に,処理系定義の任意機能を含むように defgeneric を拡張してもよい。

7.2.2

包括関数に対するメソッド定義

(defmethod func-spec method-qualifier

*

 parameter-profile form*)  →<object>

定義演算子

ここで,

func-spec ::=

identifier | (setf identifier)

method-qualifier ::=

identifier | keyword

parameter-profile ::=

({var | (var parameter-specializer-name)}* [{&rest | : rest} var])

parameter-specializer-name ::=  class-name

class-name ::=

identifier

var ::=

identifier

defmethod 定義形式は,包括関数のメソッドを定義し,包括関数名 func-spec を返す。

メソッド定義形式は,包括関数に対する引数によってそのメソッドが起動されたときに,実行すべきコ

ードを含む。

メソッド定義形式の実行準備によって,次のいずれかが起こる。

・  func-spec が既存の包括関数の名前であり,この包括関数がパラメタ特殊化指定及び修飾子に関して,

新たに定義しようとしているメソッドと合致するメソッドを含んでいる場合は,違反とする。パラメ

タ特殊化指定及び修飾子の合致の定義は,7.2.2.1 による。

・  func-spec が既存の包括関数の名前であり,この包括関数がパラメタ特殊化指定及び修飾子に関して新

たに定義しようとしているメソッドと合致するメソッドを含まない場合,新しいメソッドがこの包括

関数に追加される。

・ defmethod 定義形式が,包括関数でない関数の名前 func-spec の有効範囲に入っている場合は,違反と

する。

・  func-spec という名前の包括関数が,最上位有効範囲で定義されていない場合は,違反とする。さらに,

func-spec

に対する defgeneric 形式が,実行準備しようとしているそのテキスト上で,メソッド定義形

式よりも前にない場合は,違反とする。ただし,そのメソッド定義形式が defclass である場合を除く。

定義されるメソッドのパラメタ記述は,包括関数のラムダリストと合同でなければならない。ここでの

合同の定義は,7.2.2.2 による。

引数 method-qualifier は,メソッド修飾子と呼ばれ,メソッド組合せは,これをメソッドに対する属性と

して用いる。メソッド修飾子は,nil 以外の記号又はキーワードとする。メソッド修飾子として許されるも

のは,包括関数のメソッド組合せ方法によって,更に制限される。単純メソッド組合せ方法の場合は,修

飾なしメソッドだけが許される。標準メソッド組合せ方法の場合は,修飾なしメソッド,又は: before,: after

及び: around のキーワードのうちのいずれか一つだけを修飾子としてもつメソッドが許される。

引数 parameter-profile は,

パラメタ記述 (parameter profile) と呼ばれ,通常の関数のラムダリストと似て

いるが,必すパラメタの名前を

特殊化されたパラメタ (specialized parameter) で置き換えられる点が異なる。

特殊化されたパラメタとは,  (var parameter-specializer-name)  の形のリストとする。必すパラメタだけが

特殊化できる。パラメタ特殊化指定の名前 parameter-specializer-name は,クラス名を表す識別子とする。


44

X 3012 : 1998 (ISO/IEC 13816 : 1997)

必すパラメタに対して,パラメタ特殊化指定名が指定されていない場合,パラメタ特殊化指定として,識

別子<object>が省略されたものとする。

引数 form*は,メソッドの本体を指定する。

パラメタ特殊化指定及び修飾子に関して合致する二つのメソッドを,同じ包括関数に対して定義しては

ならない。ここでの合致の定義は,7.2.2.1 による。

メソッドは関数ではなく,関数として呼び出すことはできない。

7.2.2.1

パラメタ特殊化指定及び修飾子に関する合致  次の条件がすべて成り立つとき,二つのメソッド

は,パラメタ特殊化指定及び修飾子に関して合致するという。

a)

二つのメソッドが,同じ個数の必すパラメタをもつ。ここで,二つのメソッドのパラメタ特殊化指定

を,P

1

,...,P

n

及び Q

1

,...,Q

n

とする。

b)  1

i

n

であるすべての について P

i

と Q

i

とが合致する。パラメタ特殊化指定 P

i

と Q

i

とは,それぞれ

が同じクラスを指す場合に合致する。それ以外の場合,P

i

と Q

i

とは合致しない。

c)

両方のメソッドに修飾子がある場合に,それらが一致する。

ここで,パラメタ特殊化指定は,パラメタ記述から得られる(defmethod 参照)

7.2.2.2

包括関数のラムダリストとメソッドのパラメタ記述との合同  ある包括関数のラムダリストと

そのメソッドのパラメタ記述とは,次の二つの条件を満たすときに合同であるという。

a)

両方が,同じ個数の必すパラメタをもつ。

b)

一方が&rest 又は : rest を含む場合,他方も&rest 又は : rest を含む。

7.2.3

メソッドの継承  下位クラスは,次の意味でメソッドを継承する。あるクラスのすべてのインスタ

ンスに対して適用可能なメソッドは,そのクラスの下位クラスのすべてのインスタンスに対しても適用可

能となる。下位クラスのインスタンスは,上位クラスのインスタンスでもあるからである。

メソッドは,それが defmethod 形式によって生成されたものか,defclass 形式の任意機能によって自動生

成されたものかに関係なく,全く同様に継承される。

7.3

包括関数の呼出し  包括関数がある引数とともに呼び出されると,まず実行するコードを決定する。

このコードは,与えられた引数に対する

実効メソッド (effective method) と呼ばれる。実効メソッドは,そ

の包括関数中の適用可能メソッドの一部又はすべての組合せとする。包括関数が呼び出され,適用可能な

メソッドがない場合は,エラーが発生する。

実効メソッドが決定されると,

包括関数に渡された引数がそのまま渡されて実効メソッドが起動される。

それが返す値が,包括関数の値として返される。

実効メソッドは,次の 3 段階の手続によって決定される。

a)

適用可能なメソッドを選択する。

b)

適用可能なメソッドを,優先順位に従って,優先度の高いメソッドから低いメソッドの順に並べる。

c)

適用可能なメソッドを,メソッド組合せ方法に従って適用する。

7.3.1

適用可能なメソッドの選択  ある包括関数及びそれへの引数が与えられたとき,適用可能なメソッ

  (applicable method)  とは,その包括関数のメソッドであり,そのすべてのパラメタ特殊化指定が対応す

る引数によって満たされるメソッドとする。メソッドが適用可能であること及び引数がパラメタ特殊化指

定を満たすことの定義を次に示す。

A

1

,...,A

n

を,包括関数への必すパラメタに対応する引数とする。P

1

,...,P

n

を,メソッド の必すパ

ラメタに対応するパラメタ特殊化指定とする。すべての A

i

が P

i

満たす (satisfy) とき,メソッド は適

用可能 (applicable) であるという。A

i

がクラス の直接インスタンスとするとき,が P

i

及びその下位ク


45

X 3012 : 1998 (ISO/IEC 13816 : 1997)

ラスのいずれかである場合に,A

i

は P

i

を満たすという。

すべてのパラメタ特殊化指定がクラス<object>となっているメソッドを,

省略時メソッド (default

method)  と呼ぶ。これは常に適用可能なメソッドであるが,優先度の高いメソッドによって遮へいされる

ことがある。

メソッドは

修飾子 (qualifier) をもっことができ,これによってメソッド組合せの際に,メソッドを区別

することができる。一つ以上の修飾子をもつメソッドを,

修飾付きメソッド (qualified method) と呼ぶ。修

飾子をもたないメソッドを,

修飾なしメソッド (unqualified method) と呼ぶ。

7.3.2

適用可能メソッドの優先順位  二つのメソッドの優先順位を決定するために,それらのパラメタ特

殊化指定が左から右に順に比較される。

二つのメソッドの,対応するパラメタ特殊化指定が比較される。パラメタ特殊化指定が等しい場合は,

その次が比較される。すべての対応するパラメタ特殊化指定が等しい場合,二つのメソッドは異なる修飾

子をもつはずなので,修飾子を比較することによって,それらのメソッド間に優先順位をつけることがで

きる。

ある対応するパラメタ特殊化指定が等しくなかった場合,それらに対応する引数のクラスのクラス優先

度リストを調べ,その中に先に現れるパラメタ特殊化指定をもつメソッドを,優先度の高いメソッドとす

る。そのクラス優先度リストに,両方のパラメタ特殊化指定が現れることは,適用可能なメソッドの選択

方法が保証する。

この結果として生成される適用可能メソッドのリストは,優先度の最も高いメソッドが最初に,最も低

いメソッドが最後に現れる。

7.3.3

メソッドの適用  一般的に,実効メソッドは,適用可能メソッドの組合せとなる。実効メソッドは,

適用可能メソッドの一部又はすべてを呼び出し,包括関数の値となる値を返す。また,幾つかのメソッド

が call-next-method によってアクセスできるようにする。実効メソッドの本体とは,これらを行う評価形式

であり,これに適切なラムダリストが付加され,関数となる。

実効メソッドの中の各メソッドの役割は,そのメソッド修飾子及びメソッドの優先順位によって決定さ

れる。メソッド修飾子は,メソッドに対する印であり,修飾子の意味は,メソッド組合せの際にこれらの

印がどのように用いられるかによって決まる。適用可能メソッドが,メソッド組合せ方法が認識できない

修飾子をもつ場合は,エラーが発生する。

ISLISP には,二つのメソッド組合せ方法がある。defgeneric 形式の: method-combination 任意機能に対し

て,nil 又は standard を指定することによって,どちらのメソッド組合せ方法を使うかを指定できる。

7.3.3.1

単純メソッド組合せ  メソッド組合せ方法の名前が nil の場合は,単純メソッド組合せ (simple

method combination)  が使用される。この場合,実効メソッドは,すべての適用可能メソッドのうち,最も

優先度の高いメソッドを呼び出す。呼び出されたメソッドでは,優先度が次に最も高いメソッドを

call-next-method を用いて呼び出すことができる。call-next-method が呼び出すメソッドを,次メソッド (next 
method)  と呼ぶ。述語 next-method-p は,次メソッドの有無を判定する。call-next-method が呼び出され,次

メソッドが存在しない場合は,エラーが発生する。

7.3.3.2

標準メソッド組合せ  メソッド組合せ方法が指定されていない場合,又はメソッド組合せ方法の

名前として standard が指定された場合は,

標準メソッド組合せ  (standard method combination)  が用いられる。

主メソッド (primary method) は,実効メソッドの主要な動作を定義する。補助メソッド (auxiliary

method)  は,主メソッドの動作を 3 通りの方法で修正する。主メソッドとはメソッド修飾子をもたないメ

ソッドとし,補助メソッドとはメソッド修飾子が: before,: after 又は: around のいずれかであるメソッドと


46

X 3012 : 1998 (ISO/IEC 13816 : 1997)

する。

・ :

before メソッドとは,キーワード: before を修飾子としてもつメソッドとする。: before メソッドは,

主メソッドの前に実行されるコードを指定する。

・ :

after メソッドとは,キーワード: after を修飾子としてもつメソッドとする。: after メソッドは,主メ

ソッドの後に実行されるコードを指定する。

・ :

around メソッドは,キーワード: around を修飾子としてもつメソッドとする。: around メソッドは,

他の適用可能メソッドの代わりに実行されるコードを指定するが,それらの適用可能メソッドを起動

することもできる。

標準メソッド組合せの意味は,次のとおりとする。

・ :

around メソッドがある場合,最も優先度の高い: around メソッドが呼び出される。このメソッドの値

が包括関数の値となる。

・ :

around メソッドの本体の中では,call-next-method を用いて次メソッドを呼び出すことができる。次

メソッドが戻ると,: around メソッドは,その返り値に基づいて更にコードを実行できる。

call-next-method が使用されたとき,適用可能なメソッドがない場合は,エラーが発生する。

next-method-p を用いて,次メソッドの有無を判定できる。

・ :

around メソッドが call-next-method を起動した場合,優先度が次に最も高い: around メソッドが適用可

能であれば,それが呼び出される。: around メソッドがない場合,又は最も優先度の低い: around メソ

ッドから call-next-method が呼び出された場合,他のメソッドが次のように呼び出される。

・  すべての: before メソッドが,優先度の高いものから順に呼び出される。それらの返り値は無視される。

call-next-method を: before メソッドの中で使用した場合は,エラーが発生する。

・  最も優先度の高い主メソッドが呼び出される。その主メソッドの本体の中では,call-next-method を用

いて,優先度が次に最も高い主メソッドを呼び出すことができる。そのメソッドが戻ると,元の主メ

ソッドは,その返り値に基づいて更にコードを実行できる。call-next-method が使用され,適用可能な

主メソッドがそれ以上存在しない場合は,エラーが発生する。関数 next-method-p を用いて,次メソッ

ドの有無を判定できる。call-next-method が使用されない場合は,優先度の最も高い主メソッドだけが

呼び出される。

・  すべての: after メソッドが,優先度の低いものから順に呼び出される。それらの返り値は無視される。

call-next-method が:after メソッドの中で使用された場合は,エラーが発生する。

・ :

around メソッドが起動されなかった場合,優先度の最も高い主メソッドの値が包括関数の返す値と

なる。なお,優先度の最も低い: around メソッド中での call-next-method の呼出しが返す値は,優先度

の最も高い主メソッドの返す値となる。

標準メソッド組合せを用いる場合,適用可能な主メソッドがない場合は,エラーが発生する。: before メ

ソッドは優先度の最も高いものから順に実行され,: after メソッドは優先度の最も低いものから順に実行

される。この相違の理由を,例によって示す。クラス C

1

がその上位クラス C

2

の振る舞いを,: before 及び:

after メソッドを追加することで,変更したとする。クラス C

2

の振る舞いが,C

2

のメソッドによって直接

定義されているか上位クラスから継承されているかは,クラス C

1

のインスタンスに対するメソッド起動の

相対的順序に影響を与えない。クラス C

1

の: before メソッドは,クラス C

2

のすべてのメソッドよりも前に

実行される。クラス C

1

の: after メソッドは,クラス C

2

のすべてのメソッドよりも後に実行される。

一方,すべての: around メソッドは,: around メソッド以外のどのメソッドよりも先に実行される。この

ため,より優先度の低い: around メソッドが,より優先度の高い主メソッドよりも先に実行される。


47

X 3012 : 1998 (ISO/IEC 13816 : 1997)

主メソッドだけが用いられ,かつ call-next-method が用いられなかった場合,優先度の最も高い主メソッ

ドだけが起動される。つまり,優先度の高い主メソッドは,優先度の低い主メソッドを遮へいする。

7.3.4

次メソッド及びその呼出し

(call-next-method)  →<object>

局所関数

関数 call-next-method は,メソッドの中で次メソッドを呼び出すために使われる。呼び出した次メソッド

の返り値が,この関数の値となる。call-next-method が戻ると,その呼出し以降の計算を続けることができ

る。

どのメソッドが call-next-method を呼び出せるか,またどのメソッドが呼び出されるかは,メソッド組合

せの方法によって決定される。

単純メソッド組合せの場合,次メソッドとは,優先度が次に最も高いメソッドとする。

標準メソッド組合せ方法の場合,主メソッド及び: around メソッドの中で,call-next-method を使うこと

ができる。このとき,次メソッドは,7.3.3.2 で定義したとおりとする。

call-next-method は,現在のメソッドに渡された引数をそのまま次メソッドに渡す。メソッドのパラメタ

に対して setq を用いたり,パラメタと同じ名前の変数を再束縛しても,call-next-method が渡す引数には影

響を与えない。

call-next-method の関数束縛は,メソッドの本体における静的束縛とする。すなわち,labels によって設

定されたかのように見える。この束縛の関数オブジェクトは,無制限の存在期間をもつ。

call-next-method が,それを許さないメソッド中で使用された場合は,エラーが発生する。

call-next-method が実行され,次メソッドがない場合は,エラーが発生する。

(next-method-p)  →真偽値

局所関数

関数 next-method-p は,メソッドの本体内で,次メソッドの有無を判定するために使われる。この関数は,

次メソッドが存在する場合は t を返し,それ以外の場合は nil を返す。

next-method-p の関数束縛は,メソッドの本体における静的束縛とする。すなわち,labels によって設定

されたかのように見える。この束縛が参照する関数オブジェクトは,無制限の存在期間をもつ。

7.4

オブジェクトの生成及び初期化

(create class {initarg initval}

*

)  →<object>

包括関数

関数 create は,新しいオブジェクトを生成して返す。そのオブジェクトは,指定されたクラスのインス

タンスとする。第 1 引数は,クラスオブジェクトでなければならない。

新しいインスタンスの初期化は,インスタンスのための記憶領域の割当て,スロットへの値の設定,初

期化の追加処理のために利用者が与えたメソッドの実行,という手順からなる。第 2 と第 3 の手順は,

initialize-object という包括関数によって実装されている。これによって,これらの手順を変更することが

可能となる。初期化引数  (initarg)  とそれに付随する値  (initval)  とが,交互に並んだ一つのリストとして,

initialize-object に渡される。このリストを初期化リスト (initialization list) と呼ぶ。create は,initialize-object

が初期化した新しいインスタンスを返す。

7.4.1

インスタンスの初期化  create は,新しく生成したインスタンスを初期化するために,包括関数

initialize-objecを呼び出す。この包括関数は,標準メソッド組合せを用いる。initialize-object には,利用者

定義のクラスに対するメソッドを定義できる。これによって,システムの提供するスロット設定機構を拡

張したり変更することが可能となる。

初期化においては,すべてのスロットが未束縛である新しいインスタンスが生成され,その後で


48

X 3012 : 1998 (ISO/IEC 13816 : 1997)

initialize-object が呼び出される。

包括関数 initialize-object は,新しいインスタンス及び初期化リストを引数として,呼び出される。

initialize-object は,システムが提供する主メソッドをもつ。このメソッドのパラメタ特殊化指定は,クラ

ス<standard-object>とする。このメソッドは,与えられた初期化リスト及び各スロットに対する: initform 任

意機能に従って,次のとおりスロットを設定する。

・  そのスロットが既に値をもっていれば,その値は変更しない。

・  そのスロットに対する初期化引数と初期値との組が初期化リスト中にある場合,その初期値によって

スロットを初期化する。スロットに対する初期化引数の名前は,defclass 中の: initarg 任意機能によっ

て宣言される。

・  そのスロットが省略時初期値形式(defclass 参照)をもつ場合,その評価形式が定義された静的環境及

び現在の動的環境の下で,それを評価する。評価の結果が,スロットの値となる。

・  上のいずれでもない場合,スロットは初期化されない。

(initialize-object instance initialization-list)  →<object>

包括関数

包括関数 initialize-object は,新しく生成されたインスタンスを初期化するために create から呼び出され

る。包括関数 initialize-object は,新しいインスタンス及び初期化リストを引数とする。

initialize-object に対しシステムが提供する主メソッドは,initialization-list 及びスロットの: initform 任意機

能に従って,インスタンスのスロットを初期化する。

引数 instance は,初期化されるインスタンスとする。初期化されたインスタンスが結果として返される。

利用者は,インスタンスの初期化時の動作を指定するため,initialize-object に対してメソッドを定義でき

る。

: after メソッドだけが定義された場合,それらのメソッドは,システムの提供する初期化用の主メソッ

ドの後に実行される。したがって,それらのメソッドは,initialize-object の元々の動作に対して影響を与

えない。利用者がこの包括関数に対して定義した主メソッド又は: around メソッドが instance を返さない場

合は,結果は未定義とする。

7.5

クラスに関する問合せ

(class-of obj)  →<class>

関数

関数 class-of は,与えられた obj を直接インスタンスとするクラスを返す。obj は,いかなる ISLISP オブ

ジェクトでもよい。

(instancep obj class)  →真偽値

関数

関数 instancep は,obj がクラス class の(直接あるいはそれ以外の)インスタンスである場合は t を返し,

それ以外の場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。class がクラスオブジェク

トでない場合は,エラーが発生する(エラー名 domain-error

(subclassp class

1

 class

2

)  →真偽値

関数

関数 subclassp は,クラス class

1

がクラス class

2

の下位クラスである場合は t を返し,それ以外の場合は

nil を返す。class

1

又は class

2

のいずれかがクラスオブジェクトでない場合は,エラーが発生する(エラー

名 domain-error

(class class-name)  →<class>

特殊演算子

この特殊形式は,class-name という名前のクラスオブジェクトを返す。


49

X 3012 : 1998 (ISO/IEC 13816 : 1997)

8.

マクロ  マクロ機能は,言語を構文的に拡張する。マクロは,表層的変換を抽象化したものとする。

ISLISP テキスト(例えば,関数定義)は,内部的には ISLISP のオブジェクトによって表現できるので,

この表層的変換は,リスト処理によって記述できる。評価形式はコンス又は他のオブジェクトで表され,

個々のマクロはあるオブジェクトのグループから他のグループヘの変換関数を記述する。

マクロは,あるオブジェクトのグループから他のグループへの変換を実装する

展開関数 (expander

function)  によって内部的に定義される。展開関数の操作は,defmacro 形式によって指定する。

展開関数は,引数として一つの評価形式を受け取り,異なる評価形式を値として返す。展開関数は主な

役割として,入れ子になったリスト集合を生成する。このために,逆引用符機能を用意している。

マクロは,実行準備時に展開される。いかなる実行時情報も使えない。使用可能な操作は,単純なデー

タ構造の生成及び処理に制限される。すなわち,

(端末への入出力のような)環境への副作用,

(記号の属

性リスト変更のような)外部的にアクセスできるデータ構造への副作用,及びマクロ形式自身への副作用

を引き起こす操作は禁止する。

マクロは,最上位でだけ定義できる。マクロは,再定義(すなわち,重複定義)してはならない。マク

ロは,実行準備の段階で,それを使用する前に定義しなければならない。

マクロ形式の展開結果は,他の評価形式となる。展開後の評価形式がマクロ形式である場合は,結果が

マクロ形式でなくなるまで展開される。

最上位形式がマクロ形式のとき,そのマクロ展開結果も,最上位形式とみなす。

マクロ形式は,setf 形式の場所指定として使用できる(6.2 の setf 参照)

(defmacro macro-name lambda-list form

*

)  →<symbol>

定義演算子

defmacro 形式は,名前の付いたマクロを定義する。マクロ展開関数が呼び出されるとき,マクロ名をも

つ暗黙のブロックは生成されない。macro-name は識別子であり,その有効範囲は,最上位有効範囲全体と

する。lambda-list の定義は,4.7 による。macro-name の定義位置は,lambda-list の直後とする。

例  (defmacro caar (x) (list 'car (list ’car x)))

⇒ caar

form→<object>

構文

,form→<object>

構文

,@form→<object>

構文

これらの構文を,それぞれ

逆引用符構文 (quasiquote syntax),非引用構文 (unquote syntax) 及び非引用連

結構文  (unquote-splicing syntax)  と呼ぶ。

逆引用符構文は,リスト構造を作る。form 内に非引用構文又は非引用連結構文のいずれも現れない場合,

逆引用符構文は,quote 形式と同様に,引数を評価せずに返す。

非引用構文は,逆引用符構文内だけで有効とする。逆引用符構文内に現れた場合,非引用構文は,その

form

を評価し,その結果を逆引用符構文内に非引用構文の代わりとして挿入する。

非引用連結構文も,逆引用符構文内だけで有効な構文とする。逆引用符構文内に現れた場合,非引用連

結構文は,その form を評価する。評価結果は,リストでなければならない。このリストのすべての要素が,

上位リスト内に非引用連結構文の代わりとして挿入される。

逆引用符構文は入れ子にしてもよい。置換は,入れ子の“深さ”が同じである非引用構文又は非引用連

結構文に対してだけ行われる。入れ子の深さは,逆引用符構文に入ると一つ増加し,非引用構文又は非引

用連結構文に入ると一つ減少する。


50

X 3012 : 1998 (ISO/IEC 13816 : 1997)

例  ‘(list ,(+ 1 2) 4)

⇒ (list 3 4)

(let ((name ’a)) ’(list name ,name ’,name))

⇒ (list name a (quote a))

‘(a ,(+ 1 2) ,

@(create-list 3 ’x) b)

⇒ (a 3 x x x b)

‘((foo ’(- 10 3)) ,

@(cdr ’(c)) . ,(car ’(cons)))

⇒ ((foo 7) . cons)

‘(a ‘(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)

⇒ (a ’(b , (+ 1 2) ,(foo 4 d) e) f)

(let((name1 ’x)

      (name2 ’y))

    ‘(a ‘(b ,,name1 ,’,name2 d) e))

⇒ (a ‘(b ,x ,’y d) e)

9.

宣言及び型変換

(the class-name form)  →<object>

特殊演算子

(assure class-name form)  →<object>

特殊演算子

これらの評価形式は,form を評価する。form が戻るならば,その返り値が the 形式又は assure 形式の値

として返される。さらに,これらの評価形式は,form の値が class-name(存在するクラスの名前でなけれ

ばならない。

)によって示されたクラスのインスタンスであることを指定する。

the 形式では,form の値が class-name によって指定されたクラス又はその下位クラスのインスタンスで

ない場合は,結果は未定義とする。assure 形式では,form の値が class-name によって指定されたクラス又

はその下位クラスのインスタンスでない場合は,エラーが発生する(エラー名 domain-error

例  (the <integer> 10)

⇒ 10

(the <number> 10)

⇒ 10

(the <float> 10)

結果は未定義とする。

(assure <integer> 10)

⇒ 10

(assure <number> 10)

⇒ 10

(assure <float> 10)

エラーが発生する。

(convert obj class-name)  →<object>

特殊演算子

convert は,型変換関数 (coercion function) と呼ばれる次のいずれかに従って,オブジェクト obj に対応

するクラス class-name のオブジェクトを返す。表は最左列に obj,最上行に class-name を示す(クラス名

の<>は,この表では記述上の簡潔さのために省略する。


51

X 3012 : 1998 (ISO/IEC 13816 : 1997)

 character

integer

float

symbol

string

general-vector

list

character

= I

− I(3) −(4)

integer I

= X − X(5)

float

−(1)

− X(6)

symbol

= I(3)

string

− X(2)

X(2)

I(3)

= X(7) X

general-vector

= X

list

− X

備考

=  これは,恒等関数とする。

X

この型変換は,用意される。

  

X(2)

この型変換が試みられ,文字列が変換先クラスの数値のテキスト表現を含

まない場合は,エラーが発生する。その他すべての点において,これは

parse-number と同じとする。

  

X(5)

これは,

D 書式指示と同じでよい。

  

X(6)

これは,

G 書式指示と同じでよい。

  

X(7)

これは,文字列が実装上ベクタであるならば恒等関数とする。

I

この型変換は用意されるが,その定義は処理系定義とする。

  

I(3)

この型変換は用意されるが,その定義は処理系定義とする。型変換は,処

理系におけるエスケープ不要の英文字(10.1.2 参照)に依存する。

−  この型変換を行おうとした場合は,エラーが発生する。

(1)

この型変換を必要とする場合は,floor,ceiling,round 又は truncate のいず

れかの関数を代わりに使用すればよい。

(4)

この型変換を必要とする場合は,代わりに (create-string 1 obj)  を使用すれ

ばよい。

処理系が,処理系定義のクラスを用意している場合は,それらのクラス名に対して,convert を使用して

処理系定義の型変換を提供してもよい。

例  (convert 3 <float>)

⇒ 3.0

(convert "abc" <general-vector>)

⇒ #  (#\a #\b #\c)

(convert #(a b) <list>)

⇒ (a  b)

10.

記号クラス  記号は,クラス<symbol>のインスタンスとする。記号は,名前付き (named) でも名前な

し (unnamed) でもよい。記号の名前は,入出力時に記号を識別するために使用されることから,しばしば

印字名 (print name) と呼ばれる。記号は,属性 (property) をもつことができる。

(symbolp obj)  →真偽値

関数

関数 symbolp は,obj が記号(クラス<symbol>のインスタンス)である場合は t を返し,それ以外の場合

は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (symbolp ’a)

⇒ t

(symbolp "a" )

⇒ nil

(symbolp #

\a)

⇒ nil


52

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(symbolp ’t)

⇒ t

(symbolp t)

⇒ t

(symbolp ’nil)

⇒ t

(symbolp nil)

⇒ t

(symbolp ’())

⇒ t

(symbolp ’*pi*)

⇒ t

(symbolp *pi*)

⇒ nil

10.1

記号名  記号は,名前付き (named) 又は名前なし (unnamed) のいずれかとする。

名前から記号への写像がある。異なる記号(eq が真でない記号)は,常に異なる名前をもつ。このよう

な写像は,名前なしの記号には定義されない。

記号の名前は,文字列として表現される。

10.1.1

記号の表記  記号の名前を構成する文字は,1.4 による。

名前付き記号は,縦棒  (“|”)  で囲まれた印字名で示される。しかし,記号が次の二つの条件を満たす

場合は,縦棒で囲む必要はない。

a)

記号の印字名が,エスケープ不要の英文字(10.1.2 参照)又はそれらと次の追加文字だけからなると

き。

         0 1 2 3 4 5 6 7 8 9 + - < > / * = ? _ ! $ % [ ] ^ { }

(この集合は,処理系定義の追加の文字を含んでもよい。

b)

記号の印字名の最初の文字が,通常の英文字か又は次の文字のとき。

         < > / * = ? _ ! $ % [ ] ^ { } ~

(この集合は,処理系定義の追加文字を含んでもよい。

さらに,次の記号は,縦棒で囲まなくてもよい。

         +  -  1+  1-

記号名が縦棒を含む場合は,縦棒の前に逆斜線  “\”  を置かなければならない。記号名が逆斜線を含む

場合は,その逆斜線の前に別の逆斜線を置かなければならない。例えば, “|\\\\\|\\\||”  は,逆

斜線,逆斜線,縦棒,逆斜線,縦棒という五つの文字からなる名前の記号を表す。

備考  すべての必すの記号は縦棒なしで書くことができる。

記号の名前が,コロン (:) 又はアンパサンド (&) を含み得るかどうかは処理系定義とする。したがって,

&rest,: rest 及びその他のキーワード(例えば,: before)が,記号として表されるか又は何か別のものと

して表されるかは処理系定義とする。

10.1.2

記号名における大小文字  記号のテキスト表現が縦棒で囲まれていないとき,テキスト表現内の英

文字の大文字小文字の相違は無視される。したがって,次のテキスト表現は,同じ記号を表す。

       foo

    foO    fOo    fOO    Foo    FoO    FOo    FOO

内部的には記号の印字名内の大文字小文字は保存され,区別される。例えば,|FOO|と|foo|とは,いかな

る処理系においても同じ記号ではない。しかし,入力機構は,名前が縦棒で囲まれていない記号に対して

は,大文字小文字を正規化する。したがって,foo と FOO とは,同じ記号を表すことになる。しかし,こ

の記号が|foo|又は|FOO|のどちらであるかは処理系定義とする。

各処理系は,

英文字の変換方向  (neutral alphabetic case)  と呼ばれる処理系定義の属性をもつ。これは,

“小文字へ”又は“大文字へ”のいずれかとする。英文字の変換方向が“小文字へ”である処理系の場合,

エスケープ不要の英文字  (neutral alphabetic character)  は,次のとおりとする。


53

X 3012 : 1998 (ISO/IEC 13816 : 1997)

       a b c d e f g h i j k l m n o p q r s t u v w x y z

そうでない場合(英文字の変換方向が“大文字へ”である処理系では)

,エスケープ不要の英文字は,次

のとおりとする。

       A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

英文字の変換方向が“小文字へ”である処理系の場合は,foo,FOO 及び|foo|は同じ記号を表す。そうで

ない場合は,foo,FOO 及び|FOO|が同じ記号を表す。

処理系は,エスケープ不要の英文字の集合に処理系定義の文字を追加してもよい。

10.1.3  nil

及び()  記号 nil は偽値及び空リストの両方を表し,()と表記してもよい。

10.2

記号属性  記号の属性 (property) は,属性名 (property name) と属性値 (property value) との間の名

前による関連付けとする。記号 に属性名 が関連付けられている場合,は属性 をもつという。

(property symbol property-name [obj])  →<object>

関数

関数 property は,記号 symbol に関連付けられた property-name という名前の属性の値を返す。symbol 

property-name

という名前の属性をもたなければ,obj(省略時値は nil)を返す。

symbol

又は property-name のいずれかが記号でない場合は,エラーが発生する(エラー名 domain-error

obj

は,いかなる ISLISP オブジェクトでもよい。

例  (property ’zeus ’daughter)

⇒ athena

(setf (property symbol property-nameobj)  →<object>

特殊形式

(set-property obj symbol property-name)  →<object>

関数

これらは,obj を記号 symbol に関連付けられた property-name という名前の属性の新しい値とする。

property-name

という名前の属性が既に存在するならば,それに対応する属性値を置き換える。そうでな

ければ,新しい属性を生成する。obj を値として返す。

symbol

又は property-name のいずれかが記号でない場合は,エラーが発生する(エラー名 domain-error

obj

は,いかなる ISLISP オブジェクトでもよい。

例  (setf (property ’zeus ’daughter) ’athena)

⇒ athena

(set-property ’athena ’zeus ’daughter)

⇒ athena

(remove-property symbol property-name)  →<object>

関数

関数 remove-property は,記号 symbol に関連付けられた属性 property-name を削除し,属性が存在する場

合は削除された属性の属性値を返す。そのような属性が存在しない場合は,nil を返す。

symbol

又は property-name のいずれかが記号でない場合は,エラーが発生する(エラー名 domain-error

例    (remove-property ’zeus ’daughter) 

⇒ athena 

10.3

名前なしの記号

(gensym)  →<symbol>

関数

関数 gensym は,名前なしの記号を生成して返す。gensym は,マクロを書くのに有用となる。名前なし

の記号は,識別子によって指定することはできない。

例  (defmacro twice (x)

  (let ((v (gensym)))

    ‘(let((,v ,x)) (+ ,v ,v))))

⇒ twice


54

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(twice 5)

⇒ 10

11.

数値クラス  クラス<number>は,<float>及び<integer>という,重なりのない下位クラスをもつ。

11.1

数値クラス

(numberp obj)  →真偽値

関数

関数 numberp は,obj が数値(クラス<number>のインスタンス)である場合は t を返し,それ以外の場

合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (numberp 3)

⇒ t

(numberp -0.3)

⇒ t

(numberp ’(a b c))

⇒ nil

(numberp "17")

⇒ nil

(parse-number string)  →<number>

関数

関数 parse-number は,string 内の文字を(read のように)走査し,結果の字句要素が数値のテキスト表

現である場合は,その数値を返す。

string

が文字列でない場合は,エラーが発生する(エラー名 domain-error

string が数値のテキスト表現

でない場合は,エラーが発生する(エラー名 cannot-parse-number

例  (parse-number "123.34")

⇒ 123.34

(parse-number "#XFACE")

⇒ 64206

(parse-number "-37.")

エラーが発生する。

(parse-number "-.5")

エラーが発生する。

これは,浮動小数点数の表記において,小数点の前後の両方

に,少なくとも一つの数字が必要であるためである。

(= x

1

 x

2

)  →真偽値

関数

関数=は,x

1

が x

2

と数学的に等しい値をもつ場合は t を返し,それ以外の場合は nil を返す。x

1

又は x

2

いずれかが数値でない場合は,エラーが発生する(エラー名 domain-error

備考  =は eql とは異なる。=は引数の数学的な値だけ(すなわち,数値としての等価性)を比較する

が,eql は表現をも比較する。

例  (= 3 4)

⇒ nil

(= 3 3.0)

⇒ t

(= (parse-number "134.54") 134.54)

⇒ t

(= 0.0 -0.0)

⇒ t

(/= x

1

 x

2

)  →真偽値

関数

関数/=は,x

1

と x

2

が数学的に異なる値をもつ場合は t を返し,それ以外の場合は nil を返す。x

1

又は x

2

のいずれかが数値でない場合は,エラーが発生する(エラー名 domain-error

例  (/= 3 4)

⇒ t

(/= 3 3.0)

⇒ nil


55

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(/= (parse-number "134.54") 134.54)

⇒ nil

(>= x

1

 x

2

)  →真偽値

関数

(<= x

1

 x

2

)  →真偽値

関数

(> x

1

 x

2

)  →真偽値

関数

(< x

1

 x

2

)  →真偽値

関数

関数>=は,x

1

が x

2

より大きいか=であるなら t を返す。関数<=は,x

1

が x

2

より小さいか=であるなら t を

返す。関数>は,x

1

が x

2

より大きければ t を返す。関数<は,x

1

が x

2

より小さければ t を返す。

これらの関数は,引数の数学的な値を比較する。x

1

又は x

2

のいずれかが数値でない場合は,エラーが発

生する(エラー名 domain-error

例  (> 2 2)

⇒ nil

(> 2.0 2)

⇒ nil

(> 2 -10)

⇒ t

(> 100 3)

⇒ t

(< 2 2)

⇒ nil

(< 1 2)

⇒ t

(>= 2 2)

⇒ t

(>= 2.0 2)

⇒ t

(>= -1 2)

⇒ nil

(<= -1 2)

⇒ t

(<= 2 -1)

⇒ nil

この節の残りの定義において,<float>への型変換は,float 又は (convert z <float>) によるものと同じと

する。

(+ x*)  →<number>

関数

(* x*)  →<number>

関数

関数+及び関数*は,それぞれ引数の和及び積を返す。すべての引数が整数なら結果は整数とする。いず

れかの引数が浮動小数点数なら,結果は浮動小数点数とする。引数がない場合は,+は 0 を,*は 1 を返す。

x

のいずれかが数値でない場合は,エラーが発生する(エラー名 domain-error

例  (+ 12 3)

⇒ 15

(+ 1 2 3 )

⇒ 6

(+ 12 3.0)

⇒ 15.0

(+ 4 0.0)

⇒ 4.0

(+)

⇒ 0

(* 12 3)

⇒ 36

(* 12 3.0)

⇒ 36.0

(* 4.0 0)

⇒ 0.0

(* 2 3 4)

⇒ 24

(*)

⇒ 1


56

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(- x

)  →<number>

関数

関数-は,1 個の引数 が与えられると,符号を反転した値を返す。が数値でない場合は,エラーが発

生する(エラー名 domain-error

処理系が-0.0 と 0.0 とを区別する場合は, (- 0.0) は-0.0 を返す。処理系が-0.0 と 0.0 とを区別しない場合

は, (- 0.0) は 0.0 を返す。

例  (- 1)

⇒ -1

(- -4.0)

⇒ 4.0

(- 4.0)

⇒ -4.0

(eql (- 0.0) -0.0)

⇒ t

(eql (- -0.0) 0.0)

⇒ t

2 個以上の引数 x

1

...x

n

が与えられた場合は,関数-は,それらの連続した差 x

1

-x

2

-... -x

n

を返す。のいずれ

かが数値でない場合は,エラーが発生する(エラー名 domain-error

例  (- 1 2)

⇒ -1

(- 92 43)

⇒ 49

(- 2.3 -3.0)

⇒ 5.3

(- 0.0 0.0)

⇒ 0.0

(- 3 4 5)

⇒ -6

(reciproca1 x)  →<number>

関数

(quotient dividend divisor

)  →<number>

関数

関数 reciprocal は,引数 の逆数,すなわち,1/を返す。がゼロである場合は,エラーが発生する(エ

ラー名  division-by-zero

関数 quotient は,2 個の引数 dividend 及び divisor を与えられると,それらの数値の商を返す。結果は,

dividend

及び divisor がいずれも整数で,dividend が divisor で割り切れるなら,整数とし,そうでなければ

浮動小数点数とする。

3 個以上の引数が与えられた場合は,quotient は,dividend divisor

1

/ ... / divisor

n

というように,各 divisor

に繰り返し作用する。3 引数以上の quotient は次のとおり定義できるので,結果の型は 2 引数の場合に従

う。

(quotient dividend divisor

1

 divisor

2

...)

≡(quotient (quotient dividend divisor

1

divisor

2

...)

dividend

が数値でない場合は,エラーが発生する(エラー名 domain-error

divisor のいずれかが数値で

ない場合は,エラーが発生する(エラー名 domain-error

。いずれかの divisor がゼロである場合は,エラー

が発生する(エラー名 division-by-zero

例  (reciproca1 2)

⇒ 0.5

(quotient 10 5)

⇒ 2

(quotient 1 2)

⇒ 0.5

(quotient 2 -0.5)

⇒ -4.0

(quotient 0 0.0)

エラーが発生する。


57

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(quotient 2 3 4)

⇒ 0.16666666666666666

(max x

)  →<number>

関数

(min x

)  →<number>

関数

関数 min は,引数の中で最小の値(負の無限大に最も近い値)を返す。比較は,<によって行う。

関数 max は,引数の中で最大の値(正の無限大に最も近い値)を返す。比較は,>によって行う。

x

のいずれかが数値でない場合は,エラーが発生する(エラー名 domain-error

例  (max -5 3)

⇒ 3

(max 2.0 3)

⇒ 3

(max 2 2.0)

⇒ 2 又は 2.0 (処理系定義)

(max 1 5 2 4 3)

⇒ 5

(min 3 1)

⇒ 1

(min 1 2.0)

⇒ 1

(min 2 2.0)

⇒ 2 又は 2.0 (処理系定義)

(min 1 5 2 4 3 )

⇒ 1

(abs x)  →<number>

関数

関数 abs は,引数の絶対値を返す。が数値でない場合は,エラーが発生する(エラー名 domain-error

例  (abs -3)

⇒ 3

(abs 2.0)

⇒ 2.0

(abs -0.0)

⇒ 0.0

(exp x)  →<number>

関数

関数 exp は,の 乗を返す。ここで,は,自然対数の底とする。が数値でない場合は,エラーが発

生する(エラー名 domain-error

例  (exp 1)

⇒ 2.718281828459045

(exp 2)

⇒ 7.38905609893065

(exp 1.23)

⇒ 3.4212295362896734

(exp 0)

⇒ 1 又は 1.0(処理系定義)

(log x)  →<number>

関数

関数 log は,

x

の自然対数を返す。

x

が正の数値でない場合は,

エラーが発生する

(エラー名 domain-error

例  (log 2.718281828459045)

⇒ 1.0

(log 10)

⇒ 2.302585092994046

(log 1)

⇒ 0 又は 0.0 (処理系定義)

(expt x

1

 x

2

)  →<number>

関数

関数 expt は,x

1

の x

2

乗を返す。x

1

が整数で x

2

が非負整数ならば,結果は整数とする。x

1

がゼロで x

2

負,x

1

がゼロで x

2

が浮動小数点数のゼロ,又は x

1

が負で x

2

が整数でない場合は,エラーが発生する。


58

X 3012 : 1998 (ISO/IEC 13816 : 1997)

例  (expt 2 3)

⇒ 8

(expt -100 2)

⇒ 10000

(expt 4 -2)

⇒ 0.0625

(expt 0.5 2)

⇒ 0.25

(expt x 0)

⇒ 1

x

が,整数の場合

(expt x 0)

⇒ 1.0  が,浮動小数点数の場合

(expt -0.25 -1)

⇒ -4.0

(expt 100 0.5)

⇒ 10.0

(expt 100 -1.5)

⇒ 0.001

(expt x 0.0)

⇒ 1.0

x

が,正の浮動小数点数の場合

(expt 0.0 0.0)

エラーが発生する。

(sqrt x)  →<number>

関数

関数 sqrt は,の正の平方根を返す。が非負の数値でない場合は,エラーが発生する(エラー名

domain-error

例  (sqrt 4)

⇒ 2

(sqrt 2)

⇒ 1.4142135623730951

(sqrt  -1)  

エラーが発生する。

(sin x)  →<number>

関数

(cos x)  →<number>

関数

(tan x)  →<number>

関数

関数 sin は,の正弦を返す。関数 cos は,の余弦を返す。関数 tan は,の正接を返す。どの場合も x

はラジアンで与える。

x

が数値でない場合は,エラーが発生する(エラー名 domain-error

例  ;; これらの結果における浮動小数点数の精度は,

;;

処理系によって異なる可能性があることに注意せよ。

(sin 1)

⇒ 0.8414709848078965

(sin 0)

⇒ 0 又は 0.0 (処理系定義)

(sin 0.001)

⇒ 9.999998333333417E-4

(cos 1)

⇒ 0.5403023058681398

(cos 0)

⇒ 1 又は 1.0 (処理系定義)

(cos 0.001)

⇒ 0.9999995000000417

(tan 1)

⇒ 1.557407724654902

(tan 0)

⇒ 0 又は 0.0 (処理系定義)

(tan 0.001)

⇒ 0.0010000003333334668

(atan x)  →<number>

関数

関数 atan は,の逆正接を返す。


59

X 3012 : 1998 (ISO/IEC 13816 : 1997)

結果は,−

π

/2 を超え

π

/2 未満の数値とする。

x

が数値でない場合は,エラーが発生する(エラー名 domain-error

(atan2 x

1

 x

2

)  →<number>

関数

関数 atan2 は,点の直交座標  (x

2

x

1

)  を与えられて,その点の極座標の偏角を返す。x

1

がゼロで x

2

が負な

ら結果は正とする。x

1

及び x

2

がいずれもゼロならば,結果は処理系定義とする。

  の条件    x の条件

座標位置

結果の値域

  y=0

  x>0

x

軸の正方向

0

y=+0

  x>0

x

軸の正方向

+0

y=−0

  x

>0

x

軸の正方向

−0

  y>0

  x

>0

第 1 象限

0<結果<

π

/2

  y>0

  x

=0

y

軸の正方向

π

/2

  y>0

  x

<0

第 2 象限

π

/2<結果<

π

  y=0

  x

<0

x

軸の負方向

π

y=+0

  x

<0

x

軸の負方向

π

y=−0

  x

<0

x

軸の負方向

π

  y<0

  x

<0

第 3 象限

π

<結果<−

π

/2

  y<0

  x

=0

y

軸の負方向

π

/2

  y<0

  x

>0

第 4 象限

π

/2<結果<0

  y=0

  x

=0

原点

処理系定義

y=+0

  x

=+0

原点 +0

y=−0

  x

=+0

原点

−0

y=+0

  x

=−0

原点

π

y=−0

  x

=−0

原点

π

図 3  atan2 の象限情報 

x

1

又は x

2

のいずれかが数値でない場合は,エラーが発生する(エラー名 domain-error

atan2 の値は,負のゼロが実装されていなければ,常に-

π

を超え

π

までの間とする。負のゼロが実装され

ていれば,-

π

も値域に含むものとする。

x

1

及び x

2

の符号が象限情報を得るために用いられる。その詳細を

図 に示す。この図では,x

1

を y,x

2

を と表記する。アステリスク (*) は,負のゼロを実装した処理系に適用されることを意味する。

例  (atan2 0 3.0)

⇒ 0 又は 0.0(処理系定義)

(atan2 1 1)

⇒ 0.7853981633974483

(atan2 1.0 -0.3)

⇒ 1.8622531212727635

(atan2 0.0 -0.5)

⇒ 3.141592653589793

(atan2 -1 -1)

⇒ -2.356194490192345

(atan2 -1.0 0.3)

⇒ -1.2793396

(atan2 0.0 0.5)

⇒ 0.0

(defun asin (x) (atan2 x (sqrt (-1 (expt x 2)))))

⇒ asin

(defun acos (x) (atan2 (sqrt (-1 (expt x 2))) x))

⇒ acos

(defun atan (x) (atan2 x 1))

⇒ atan


60

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(sinh x)  →<number>

関数

(cosh x)  →<number>

関数

(tanh x)  →<number>

関数

関数 sinh は,の双曲線正弦を返す。関数 cosh は,の双曲線余弦を返す。関数 tanh は,の双曲線正

接を返す。

x

が数値でない場合は,エラーが発生する(エラー名 domain-error

例  (sinh 1)

⇒ 1.1752011936438014

(sinh 0)

⇒ 0 又は 0.0 (処理系定義)

(sinh 0.001)

⇒ 0.001000000166666675

(cosh 1)

⇒ 1.5430806348152437

(cosh 0)

⇒ 1 又は 1.0 (処理系定義)

(cosh 0.001)

⇒ 1.0000005000000416

(tanh 1)

⇒ 0.7615941559557649

(tanh 0)

⇒ 0 又は 0.0 (処理系定義)

(tanh 0.001)

⇒ 9.999996666668002E-4

(atanh x)  →<number>

関数

関数 atanh は,の双曲線逆正接を返す。が絶対値 1 未満の数値でない場合は,エラーが発生する(エ

ラー名 domain-error

例  (atanh 0.5)

⇒ 0.5493061443340549

(atanh 0)

⇒ 0 又は 0.0 (処理系定義)

(atanh 0.001)

⇒ 0.0010000003333335335

(defun asinh (x) (atanh (quotient x (sqrt (+ 1 (expt x 2))))))

⇒ asinh

(defun acosh (x) (atanh (quotient (sqrt (* (- x 1) (+ x 1))) x)))

⇒ acosh

11.2

浮動小数点数クラス  浮動小数点数は,<float>クラスのインスタンスとする。浮動小数点数は,あ

る精度の有理数によって表される(IEEE standard 754 参照)

浮動小数点数の書式は,次のいずれかとする。

[s]dd...d.dd...d

[s]dd...d.dd...dE[s]dd...d

[s]dd...d.dd...de[s]dd...d

[s]dd...dE[sdd...d

[s]dd...de[sdd...d

ここで,は “+” 又は “-” のいずれかとし,dd...は一つ以上の “0” ∼ “9” からなる数字列とする。

*pi*→<float>

名前付き定数

この定数の値は,円周率

π

の近似値とする。

例  *pi*

⇒ 3.141592653589793

*most-positive-float*→<float>

名前付き定数


61

X 3012 : 1998 (ISO/IEC 13816 : 1997)

*most-negative-float*→<float>

名前付き定数

*most-positive-float*の値は,正の無限大に最も近い処理系依存の浮動小数点数とする。

*most-negative-float*の値は,負の無限大に最も近い処理系依存の浮動小数点数とする。

(floatp obj)  →真偽値

関数

関数 floatp は,obj が浮動小数点数(クラス<float>のインスタンス)である場合は t を返し,それ以外の

場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (floatp "2.4")

⇒ nil

(floatp 2)

⇒ nil

(floatp 2.0)

⇒ t

(float x)  →<float>

関数

関数 float は,がクラス<float>のインスタンスならば 自身を返し,そうでなければ の浮動小数点近

似値を返す。が数値でない場合は,エラーが発生する(エラー名 domain-error

例  (float 0)

⇒ 0.0

(float 2)

⇒ 2.0

(float -2.0)

⇒ -2.0

(float 123456789123456789123456789)

⇒ 1.2345678912345679E26

(floor x)  →<integer>

関数

関数 floor は,以下の最大の整数を返す。すなわち,を負の無限大方向に丸める。が数値でない場

合は,エラーが発生する(エラー名 domain-error

例  (floor 3.0)

⇒ 3

(floor 3.4)

⇒ 3

(floor 3.9)

⇒ 3

(floor -3.9)

⇒ -4

(floor -3.4)

⇒ -4

(floor -3.0)

⇒ -3

(ceiling x)  →<integer>

関数

関数 ceiling は,以上の最小の整数を返す。すなわち,を正の無限大方向に丸める。が数値でない場

合は,エラーが発生する(エラー名 domain-error

例  (ceiling 3.0)

⇒ 3

(ceiling 3.4)

⇒ 4

(ceiling 3.9)

⇒ 4

(ceiling -3.9)

⇒ -3

(ceiling -3.4)

⇒ -3

(ceiling -3.0)

⇒ -3

(truncate x)  →<integer>

関数


62

X 3012 : 1998 (ISO/IEC 13816 : 1997)

関数 truncate は,0∼の間で に最も近い整数を返す。すなわち,をゼロ方向に丸める。が数値でな

い場合は,エラーが発生する(エラー名 domain-error

例  (truncate 3.0)

⇒ 3

(truncate 3.4)

⇒ 3

(truncate 3.9)

⇒ 3

(truncate -3.4)

⇒ -3

(truncate -3.9)

⇒ -3

(truncate -3.0)

⇒ -3

(round x)  →<integer>

関数

関数 round は,に最も近い整数を返す。が二つの整数のちょうど中間にある場合は,偶数が採られる。

x

が数値でない場合は,エラーが発生する(エラー名 domain-error

例  (round 3.0)

⇒ 3

(round 3.4)

⇒ 3

(round -3.4)

⇒ -3

(round 3.6)

⇒ 4

(round -3.6)

⇒ -4

(round 3.5)

⇒ 4

(round -3.5)

⇒ -4

(round 2.5)

⇒ 2

(round -0.5)

⇒ 0

11.3

整数クラス  整数オブジェクトは,数学の整数に対応する。整数は,<integer>クラスのインスタン

スとして表現する。

整数だけを扱う算術演算は,整数の大きさに関係なく数学的に正しく動作する。整数の算術演算がハー

ドウェアの精度を超える結果又は中間結果を生成する場合は,ISLISP 処理系は,数学的正しさを確実にす

るために必要な演算を,ソフトウェアで擬似的に処理しなければならない。どのような状況でこの擬似的

処理が必要となるかは,処理系定義とする。この擬似的処理が,いつ処理系の能力を超えるかも処理系定

義とする。

整数の書式は,次のいずれかとする。

#B [s]bb...b

各 は “0” 又は “1”

#b [s]bb...b

各 は “0” 又は “1”

#O [s]oo...o

各 は “0” ∼ “7” のいずれか

#o [s]oo...o

各 は “0” ∼ “7” のいずれか

 [s]dd...d

各 は “0” ∼ “9” のいずれか

#X [s]xx...x

各 は “0” ∼ “9”,“A”  ∼ “F”,“a”  ∼ “f” のいずれか

#x [s]xx...x

各 は “0” ∼ “9”,“A”  ∼ “F”,“a”  ∼ “f” のいずれか

ここで,は “+” 又は “-” とする。

備考 ISLISP では,入力機構を制御する変数はないので,上の表現は厳密に整数の表現となる。

(integerp obj)  →真偽値

関数


63

X 3012 : 1998 (ISO/IEC 13816 : 1997)

関数 integerp は,obj が整数(クラス<integer>のインスタンス)である場合は t を返し,それ以外の場合

は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (integerp 3)

⇒ t

(integerp 3.4)

⇒ nil

(integerp "4")

⇒ nil

(integerp ’(a b c))

⇒ nil

(div z

1

 z

2

)  →<integer>

関数

(mod z

1

 z

2

)  →<integer>

関数

関数 div は,z

1

を z

2

で割った商以下の最大の整数を返す。z

2

がゼロである場合は,エラーが発生する(エ

ラー名 division-by-zero

関数 mod は,z

1

の z

2

による整数除算の余りを返す。結果の符号は,z

2

の符号と一致する。結果は 0 と z

2

との間(0 を含み,z

2

を含まない。

)の整数であり,z

1

とこの結果との差は z

2

で割り切れる。

div と mod との関係は次のとおりとする。

 (=

z

1

 (+ (* (div z

1

 z

2

z

2

) (mod z

1

 z

2

)))

すなわち,上の評価形式の評価結果は,常に t となる。

z

1

又は z

2

のいずれかが整数でない場合は,エラーが発生する(エラー名 domain-error

例  (div 12 3)

⇒4

(div 14 3)

⇒ 4

(div -12 3)

⇒ -4

(div -14 3)

⇒ -5

(div 12 -3)

⇒ -4

(div 14 -3)

⇒ -5

(div -12 -3)

⇒ 4

(div -14 -3)

⇒ 4

(mod 12 3)

⇒ 0

(mod 7 247)

⇒ 7

(mod 247 7)

⇒ 2

(mod 14 3)

⇒ 2

(mod -12 3)

⇒ 0

(mod -14 3)

⇒ 1

(mod 12 -3)

⇒ 0

(mod 14 -3)

⇒ -1

(mod -12 -3)

⇒ 0

(mod -14 -3)

⇒ -2

(gcd z

1

 z

2

)  →<integer>

関数

関数 gcd は,二つの引数の最大公約数を返す。結果は,非負整数とする。ゼロ以外の引数に対しては,

最大公約数は,z

1

及び z

2

の両方の約数である最大の整数とする。


64

X 3012 : 1998 (ISO/IEC 13816 : 1997)

z

1

又は z

2

のいずれかが整数でない場合は,エラーが発生する(エラー名 domain-error

例  (gcd 12 5)

⇒ 1

(gcd 15 24)

⇒ 3

(gcd -15 24)

⇒ 3

(gcd 15 -24)

⇒ 3

(gcd -15 -24)

⇒ 3

(gcd 0 -4)

⇒ 4

(gcd 0 0)

⇒ 0

(lcm z

1

 z

2

)  →<integer>

関数

関数 lcm は,その引数の最小公倍数を返す。gcd 及び lcm は,次の関係を満たす。

(= (* (gcd m n) (lcm m n)) (abs (* m n)))

すなわち,上の評価形式の評価結果は,常に t となる。

z

1

又は z

2

のいずれかが整数でない場合は,エラーが発生する(エラー名 domain-error

例  (lcm 2 3)

⇒ 6

(lcm 15 24)

⇒ 120

(lcm 15 -24)

⇒ 120

(lcm -15 24)

⇒ 120

(lcm -15 -24)

⇒ 120

(lcm 0 -4)

⇒ 0

(lcm 0 0)

⇒ 0

(isqrt z)  →<integer>

関数

関数 isqrt は,の正の平方根以下の最大の整数を返す。が非負整数でない場合は,エラーが発生する

(エラー名 domain-error

例  (isqrt 49)

⇒ 7

(isqrt 63)

⇒ 7

(isqrt 1000000000000002000000000000000)

⇒ 1000000000000000

12.

文字クラス  文字は,<character>クラスのインスタンスとして表現する。これによって,利用者は特

定の文字コードに依存しなくてもよくなる。

ISLISP の文字集合は,少なくとも 95 個の印字文字と復帰改行文字とを含まなければならない。印字文

字は,スペース文字及び次の 94 個の文字からなる。

      ! " # $ % & ’ ( ) * + , -

./ 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

      @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [

\ ] ^ _

      ‘ a b c d e f g h i j k l m n o p q r s t u v w x y z { | }

文字リテラルは,#\とそれに続く文字自身,又は文字が名前をもつ場合は#\とそれに続く名前によっ

て表記する。例えば,英文字の A は,

“#\A”と表記する。復帰改行文字及びスペース文字は,それぞれ

“newline”及び“space”という名前をもつので,それらは“#\newline”及び“#\space”と表記するこ


65

X 3012 : 1998 (ISO/IEC 13816 : 1997)

とができる。

(文字の名前では,大文字小文字は区別しない。

すべての文字は,char<によって順序付けられるが,その順序は,次の順序を満たすものとする。

      A<B<C<D<E<F<G<H<I<J<K<L<M<N<O<P<Q<R<S<T<U<V<W<X<Y<Z

      a<b<c<d<e<f<g<h<i<j<k<l<m<n<o<p<q<r<s<t<u<v<w<x<y<z

      0<1<2<3<4<5<6<7<8<9

ここで,char

1

<char

2

は, (char< char

1

 char

2

)  が真であることを意味する。

(characterp obj)  →真偽値

関数

関数 characterp は,obj が文字(クラス<character>のインスタンス)である場合は t を返し,それ以外の

場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (characterp #\a)

⇒ t

(characterp "a")

⇒ nil

(characterp ’a)

⇒ nil

(char= char

1

 char

2

)  →真偽値

関数

(char/= char

1

 char

2

)  →真偽値

関数

(char< char

1

 char

2

)  →真偽値

関数

(char> char

1

 char

2

)  →真偽値

関数

(char<= char

1

 char

2

)  →真偽値

関数

(char>= char

1

 char

2

)  →真偽値

関数

関数 char=は,char

1

が char

2

と同じ文字かどうか検査する。関数 char<は,char

1

が char

2

より小さいかど

うか検査する。関数 char<=は,char

1

が char

2

以下かどうか検査する。ここで使用される順序は,上で定義

した部分的な順序関係に従い,処理系定義の方式ですべての文字に対する全順序に拡張したものとする。

検査する条件が満たされれば t を返し,そうでなければ nil を返す。

二つの文字は,それらが char=でない場合に,char/=とする。二つの文字は,それらが char<=でない場合

に,char>とする。二つの文字は,それらが char<でない場合に,char>=とする。

char

1

又は char

2

のいずれかが文字でない場合は,エラーが発生する(エラー名 domain-error

例  (char= #\a #\a)

⇒ t

(char= #

\a #\b)

⇒ nil

(char= #

\a #\A)

⇒ nil

(char/= #

\a #\a)

⇒ nil

(char< #

\a #\a)

⇒ nil

(char< #

\a #\b)

⇒ t

(char< #

\b #\a)

⇒ nil

(char< #

\a #\A)

⇒ nil 又は t(処理系定義)

(char< #

\* #\a)

⇒ nil 又は t(処理系定義)

(char> #

\b #\a)

⇒ t

(char<= #

\a #\a)

⇒ t

(char<= #

\a #\A)

⇒ nil 又は t(処理系定義)

(char>= #

\b #\a)

⇒ t


66

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(char>= #

\a #\a)

⇒ t

13.

リストクラス  クラス<list>は,二つの下位クラス<cons>及び<null>に分割される。

13.1

コンス  コンス(“ドット対”とも呼ばれる。)は,二つの構成要素をもつ。左側の構成要素を car

と呼び,右側の構成要素を cdr と呼ぶ。このクラスの生成関数は,cons とする。コンスは,次のとおり表

記する。

(car  .cdr)

ここで,car 及び cdr は,それぞれコンスオブジェクトの car 要素及び cdr 要素の値を表す。特別な場合

として,cdr の値が nil であるとき,コンスオブジェクトは,次のとおり表記する。

(car)

一般に,コンスオブジェクトから構成されるデータ構造は,次のいずれかの書式で表記する。

(x

1

  .(x

2

  .... (x

n-1

  .x

n

) ...))

(x

1

  .(x

2

  .... (x

n-1

) ...))

これらはそれぞれ,次のとおり表記できる。

(x

1

 x

2

...x

n-1

  .x

n

)

(x

1

 x

2

...x

n-1

)

(consp obj)  →真偽値

関数

関数 consp は,obj がコンス(クラス<cons>のインスタンス)である場合は t を返し,それ以外の場合は

nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (consp ’(a . b))

⇒ t

(consp ’(a b c))

⇒ t

(consp ’())

⇒ nil

(consp #(a b))

⇒ nil

(cons obj

1

 obj

2

)  →<cons>

関数

関数 cons は,二つのオブジェクトからコンスを作成して返す。obj

1

をその car 要素とし,obj

2

を cdr 要素

とする。要求されたコンスが割り当てられない場合は,エラーが発生する(エラー名 cannot-create-cons

obj

1

及び obj

2

は,いかなる ISLISP オブジェクトでもよい。

例  (cons ’a ’())

⇒ (a)

(cons ’(a) ’(b c d))

⇒ ((a) b c d)

(cons "a" ’(b c))

⇒ ("a" b c)

(cons ’a 3)

⇒ (a . 3)

(cons ’(a b) ’(c)

⇒ ((a b) . c)

(car cons)  →<object>

関数

関数 car は cons の car 要素を返す。

cons

がコンスでない場合は,

エラーが発生する

(エラー名 domain-error

例  (car ’())

エラーが発生する。

(car ’(a b c))

⇒ a

(car ’((a) b c d))

⇒ (a)


67

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(car ’(1 . 2))

⇒ 1

(cdr cons)  →<object>

関数

関数 cdr は cons の cdr 要素を返す。

cons

がコンスでない場合は,

エラーが発生する

(エラー名 domain-error

例  (cdr ’())

エラーが発生する。

(cdr ’((a) b c d))

⇒ (b c d)

(cdr ’(1 . 2))

⇒ 2

(setf (car consobj)  →<object>

特殊形式

(set-car obj cons)  →<object>

関数

これらは,car で示される場所指定を受け取り,<cons>クラスのインスタンスの car 要素を obj で更新す

る。返り値は obj とする。cons がコンスでない場合は,エラーが発生する(エラー名 domain-error

obj

は,いかなる ISLISP オブジェクトでもよい。

例  (let((x (list ’apple ’orange)))

  (list x (carx)

         (setf (car x) ’banana)

         x (car x)))

⇒ ((banana orange) apple banana (banana orange) banana)

(setf (cdr consobj)  →<object>

特殊形式

(set-cdr obj cons)  →<object>

関数

これらは,cdr で示される場所指定を受け取り,<cons>クラスのインスタンスの cdr 要素を obj で更新す

る。返り値は,obj とする。cons がコンスでない場合は,エラーが発生する(エラー名 domain-error

obj

は,いかなる ISLISP オブジェクトでもよい。

例  (let ((x (list ’apple ’orange)))

  (list x (cdr x)

         (setf (cdr x) ’banana)

         x (cdr x)))

⇒ ((apple . banana) (orange) banana (apple . banana) banana)

13.2

空リストクラス  このクラスは,nil と呼ばれるただ一つの要素からなる。このオブジェクトは,真

偽値式における偽の値とする。列 nil の長さは,0 とする。

(null obj)  →真偽値

関数

関数 null は,obj が nil である場合は t を返し,それ以外の場合は nil を返す(

5

)

obj は,いかなる ISLISP

オブジェクトでもよい。

(

5

)

命名の方式を厳格に守るならば,null は,nullp と名付けられなければならない。しかし,歴史

的及び互換性の理由で,null と名付ける。

例  (null ’(abc))

⇒ nil

(null ’())

⇒ t

(null (list))

⇒ t


68

X 3012 : 1998 (ISO/IEC 13816 : 1997)

13.3

リスト操作

(listp obj)  →真偽値

関数

関数 listp は,obj がリスト(クラス<list>のインスタンス)である場合は t を返し,それ以外の場合は nil

を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (listp ’(a b c))

⇒ t

(listp ’())

⇒ t

(listp ’(a . b))

⇒ t

(let ((x (list ’a)))

  (setf (cdr x) x)

  (listp x))

⇒ t

(listp "abc")

⇒ nil

(listp #(1 2))

⇒ nil

(listp ’takayasu)

⇒ nil

(create-list i [initial-element])  →<list>

関数

関数 create-list は,長さ のリストを生成して返す。initial-element が与えられた場合,新しいリストの要

素を,このオブジェクトで初期化する。そうでなければ,初期化は処理系定義とする。要求されたリスト

の割当てができない場合は,エラーが発生する(エラー名 cannot-create-list

が非負整数でない場合は,

エラーが発生する(エラー名 domain-error

initial-element は,いかなる ISLISP オブジェクトでもよい。

例  (create-list 3 17)

⇒ (17 17 17)

(create-list 2 #

\a)

⇒ (#\a #\a)

(list obj*)  →<list>

関数

関数 list は,その長さが引数の個数と一致し,すべての引数を同じ順序で要素とする新しいリストを返

す。要求されたリストの割当てができない場合は,エラーが発生する(エラー名 cannot-create-list

。各 obj

は,いかなる ISLISP オブジェクトでもよい。

例  (list ’a(+ 3 4) ’c)

⇒ (a 7 c)

(list)

⇒ nil

(reverse list)  →<list>

関数

(nreverse list)  →<list>

関数

これらの関数は,どちらも与えられた list の要素の順序が逆転したリストを返す。list がリストでない場

合は,エラーが発生する(エラー名 domain-error

reverse では,与えられた list に対する副作用はない。結果となるリストは,与えられた list と構造を共

有してもよい。

nreverse では,新しいリストを作る目的で,与えられた list の最上位を構成するコンスに対して副作用を

及ぼしてもよい。リテラルオブジェクトに対しては,nreverse を適用してはならない。

例  (reverse ’(a b c d e))

⇒ (e d c b a)

(reverse ’(a))

⇒ (a)


69

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(reverse ’())

⇒ ()

(let* ((x (list ’a ’b)) (y (nreverse x))) (equal x y))

⇒ 処理系定義

(append list*)  →<list>

関数

関数 append は,すべての list を連結した結果を返す。list が与えられなかった場合は,

()を返す。list

のいずれかがリストでない場合は,エラーが発生する(エラー名 domain-error

この関数は,その引数を変更しない。結果と引数 list とが構造を共有するかどうか,更に,どのような

場合に共有するかは,処理系定義とする。

リストの割当てができない場合は,エラーが発生する(エラー名 cannot-create-list

例  (append ’(a b c) ’(d e f))

⇒ (a b c d e f)

(member obj list)  →<list>

関数

関数 member は,list の中に obj と eql であるオブジェクトが含まれている場合,その car が obj と eql で

ある list の最初の部分リストを返す。そうでなければ nil を返す。list がリストでない場合は,エラーが発

生する(エラー名 domain-error

例  (member ’c ’(a b c d e f))

⇒ (c d e f)

(member ’g ’(a b c d e f))

⇒ nil

(member ’c ’(a b c a b c))

⇒ (c a b c)

(mapcar function list

)  →<list>

関数

(mapc function list

)  →<list>

関数

(maplist function list

)  →<list>

関数

(mapl function list

)  →<list>

関数

(mapcan function list

)  →<list>

関数

(mapcon function list

)  →<list>

関数

これらの関数は,与えられた一連の list によって決定される引数の集合に,与えられた function を連続し

て適用する。引数を決定する方法及び結果を蓄積していく方法が,関数によって異なる。

関数

  引数

  結果

mapcar

要素

  返り値のリスト

mapc

要素

  最初の list

maplist

部分リスト

  返り値のリスト

mapl

部分リスト

  最初の list

mapcan

要素

  返り値を破壊的に連結した結果

mapcon

部分リスト

  返り値を破壊的に連結した結果

mapcar は,各 list の要素に対して順に演算を行う。function は,各 list の第 1 要素に対して適用され,次

に各 list の第 2 要素に対して適用され,これを順次繰り返す。最も短い list が終わったときに,繰返しは終

了し,他のリストの余った要素は無視される。mapcar が返す値は,function の呼出し順にそれらの結果を

リストにしたものとする。

mapc は,mapcar と似ているが,function の適用結果を蓄積しない点が異なる。関数 mapc は,最初の list

を返す。

maplist は,mapcar と似ているが,function を各 list の部分リストに適用する点が異なる。function は,各


70

X 3012 : 1998 (ISO/IEC 13816 : 1997)

list

自身に最初に適用され,次に各 list の cdr に適用され,次に各 list の cdr の cdr に適用され,これを順次

繰り返す。

mapl は,maplist と似ているが,function の適用結果を蓄積しない点が異なる。関数 mapl は,最初の list

を返す。

mapcan 及び mapcon は,それぞれ mapcar 及び maplist に似ているが,function の適用結果を一つのリスト

に結合する際に,list ではなく append と同様の操作を破壊的に実行する演算を用いる点が異なる。

function

が関数でない場合は,エラーが発生する(エラー名 domain-error

list のいずれかがリストでな

い場合は,エラーが発生する(エラー名 domain-error

いずれの関数においても,function の呼出しは左から右へと進む。したがって,function が副作用をもつ

場合,利用者はこの順序に依存してよい。

例  (mapcar #’car ’((1 a) (2 b) (3 c)))

⇒ (1 2 3)

(mapcar #’abs ’((3 -4 2 -5 -6))

⇒ (3 4 2 5 6)

(mapcar #’cons ’(a b c) ’(1 2 3))

⇒ ((a . 1) (b . 2) (c . 3))

(let ((x 0)) (mapc (lambda (v) (setq x (+ x v))) ’(3 5)) x)

⇒ 8

(maplist #’append ’(1 2 3 4) ’(1 2) ’(1 2 3))

⇒ ((1 2 3 4 1 2 1 2 3) (2 3 4 2 2 3))

(maplist (lambda (x) (cons ’foo x)) ’(a b c d))

⇒ ((foo a b c d) (foo b c d) (foo c d) (foo d))

(maplist (lambda (x) (if (member (car x) (cdr x)) 0 1))

           ’(a b a c d b c))

⇒ (0 0 1 0 1 1 1)

(let ((k 0))

  (mapl(lambda (x)

          (setq k (+ k (if (member (car x) (cdr x)) 0 1))))

        ’(a b a c d b c))

k)

⇒ 4

(mapcan (lambda (x) (if (> x 0) (list x))) ’(-3 4 0 5 -2 7))

⇒ (4 5 7)

(mapcon (lambda (x) (if (member (car x) (cdr x)) (list (car x))))

          ’(a b a c d b c b c))

⇒ (a b c b c)

(mapcon #’list ’(1 2 3 4))

⇒ ((1 2 3 4) (2 3 4) (3 4) (4))


71

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(assoc obj association-list)  →<list>

関数

関数 assoc は,association-list の中に,その car が obj と eql であるコンスが少なくとも一つ含まれている

場合,そのような最初のコンスを返す。そうでなければ nil を返す。association-list がコンスのリストでな

い場合は,エラーが発生する(エラー名 domain-error

例  (assoc ’a ’((a . 1) (b . 2)))

⇒ (a . 1)

(assoc ’a ’((a . 1) (a . 2)))

⇒ (a . 1)

(assoc ’c ’((a . 1) (b . 2)))

⇒ nil

14.

配列

14.1

配列のクラス  配列は,その構成要素にデータを格納する。配列の構成要素は,添字 (index) と呼

ばれる非負整数の組を使ってアクセスできる。

配列中の要素の総数は,各次元の大きさの積とする。0 次元の配列も許され,この規則の結果として,

ちょうど一つの要素を格納する事ができ,添字なしにアクセスされる。

配列のクラスは複数存在する。それらの継承関係を,

図 に示す。各クラスの用途を,次に示す。

・ <basic-array>

すべての配列は抽象クラス<basic-array>に属するが,

(すべての抽象クラスがそうであるように)こ

のクラスは直接インスタンスをもたない。このクラスは,型の識別のためだけに用意されている。

<basic-array>は,下位クラス<basic-vector>及び<basic-array*>をもつ。これらのクラスは,重なりが

なく,配列の集合を完全に分割する。これ以外には<basic-array>の直接の下位クラスは,存在しない。

・ <basic-vector>

すべての 1 次元の配列は抽象クラス<basic-vector>に属するが,

(すべての抽象クラスがそうである

ように)このクラスは直接インスタンスをもたない。このクラスは,型の識別のためだけに用意され

ている。

<basic-vector>は,下位クラス<general-vector>及び<string>をもつ。<basic-vector>は,付加的な処理系

定義の下位クラスをもってもよい。

備考  処理系が,ビットの 1 次元配列のために,特殊化された配列表現を用意する場合がある。その

場合,そのような配列表現は,<basic-vector>の下位クラスになるであろう。

・ <general-vector>

クラス<general-vector>のオブジェクトは,<object>型の要素を格納可能な 1 次元の配列とする。関数

create-array が 1 次元配列を作成するよう命令された場合,結果の配列は,このクラスに属する。

・ <string>

クラス<string>のオブジェクトは,<character>型の要素だけを格納可能な 1 次元の配列とする。関数

create-string が用いられた場合,結果は,このクラスに属する。

・ <basic-array*>

1 次元でないすべての配列は抽象クラス<basic-array*>に属するが,(すべての抽象クラスがそうで

あるように)このクラスは直接インスタンスをもたない。このクラスは,型の識別のためだけに用意

されている。

ISLISP は , <basic-array*> に 直 接 の 下 位 ク ラ ス を 一 つ だ け 定 義 す る 。 そ の 下 位 ク ラ ス を ,

<general-array*>とする。<basic-array*>には,処理系定義の付加的な下位クラスが存在してもよい。


72

X 3012 : 1998 (ISO/IEC 13816 : 1997)

備考  処理系が,モノクローム又はカラーのスクリーンの表示情報を保持する目的で,1 ビット以上

の 2 次元配列のために,特殊化された配列表現を用意する場合がある。その場合,そのような

配列表現は,<basic-array*>の下位クラスになるであろう。

・ <general-array*>

クラス<general-array*>のオブジェクトは,<object>型の要素を格納可能な 1 次元でない配列とする。

関数 create-array が 1 次元でない配列を作成するよう命令された場合,結果の配列は,このクラスに属

する。

14.2

一般配列  クラス<general-vector>又はクラス<general-array*>に属するオブジェクトは,一般配列

(general array)  と呼ばれることがある。

一般配列は,クラス<object>のいかなるオブジェクトも格納可能とする。一般配列以外の配列は,より

特殊化されたクラスのオブジェクトを格納するための制限された配列とする。

一般配列は,その配列の内容を示す並びを入れ子となったリストにして続ける#ra 記法(は配列の次元

数を表す整数)を用いて,リテラルとして表現可能とする。その構造は,次のように定義できる。r=1 の

とき,配列構造は単純に  (obj

1

...obj

n

)  とする。r>1 のとき,各次元の大きさを n

1

n

2

,...,n

r

とすると,配列

構造は  (str

1

...str

n1

)  となる。ここで,str

i

は r−1 次元の部分配列構造であり,個々の部分配列の各次元の大

きさは n

2

,...,n

r

とする。例えば,(create-array ’( 2 3 4) 5)が生成する配列は,次のように表記する。

        #3a (((5 5 5 5) (5 5 5 5) (5 5 5 5)) ((5 5 5 5) (5 5 5 5) (5 5 5 5)))

14.3

配列操作  配列操作のために ISLISP は,次の関数を用意する。

(basic-array-p obj)  →真偽値

関数

(basic-array*-p obj)  →真偽値

関数

(general-array*-p obj)  →真偽値

関数

関数 basic-array-p は,obj が配列(クラス<basic-array>のインスタンス)である場合は t を返し,それ以

外の場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

関数 basic-array*-p は,obj がクラス<basic-array*>のインスタンスである場合は t を返し,それ以外の場

合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

関数 general-array*-p は,obj がクラス<general-array*>のインスタンスである場合は t を返し,それ以外の

場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (mapcar (lambda (x)

            (list (basic-array-p x)

                   (basic-array*-p  x)

                   (general-array*-p  x)))

         ’((a b c)

           "abc"

           #(a b c)

           #1a(a b c)

           #2a((a) (b) (c))))

⇒ ((nil nil nil) (t nil nil) (t nil nil) (t nil nil) (t t t))

(create-array dimensions [initial-element])  →<basic-array>

関数


73

X 3012 : 1998 (ISO/IEC 13816 : 1997)

関数 create-array は,新しい配列を生成し,その配列を値として返す。dimensions 引数は,非負整数のリ

ストとする。生成される配列の次元数は dimensions の長さと一致し,各次元の大きさは,dimensions の各

要素の値と一致する。

結果は,一次元ならばクラス<general-vector>に属し,そうでなければ<general-array*>に属する。

initial-element

が与えられれば,新しい配列の要素は,このオブジェクトで初期化され,そうでなければ

初期化は処理系定義とする。

要求された配列の割当てができない場合は,エラーが発生する(エラー名 cannot-create-array

dimensions

が非負整数のリストでない場合は,エラーが発生する(エラー名 domain-error

initial-element

は,いかなる ISLISP オブジェクトでもよい。

例  (create-array ’(2 3) 0.0)

⇒ #2a((0.0 0.0 0.0) (0.0 0.0 0.0))

(create-array ’(2) 0.0)

⇒ #(0.0  0.0)

(aref basic-array z

*

)  →<object>

関数

(garef general-array z

*

)  →<object>

関数

関数 aref は,整数 の並びで特定される basic-array の構成要素に格納されたオブジェクトを返す。この

並びは,basic-array の次元数と正確に同じ個数の要素をもたなければならず,その各々は,0

z

I

<d

i

を満た

さなければならない。ここで,d

i

は第 次元の大きさで,次元数を とするとき,0

i<d

とする。配列の

添字は,0 から始まる。したがって,番目の行は添字 i−1 でアクセスする。

basic-array

が配列でない場合は,エラーが発生する(エラー名 domain-error

のいずれかが非負整数

でない場合は,エラーが発生する(エラー名 domain-error

関数 garef は,aref と似ているが,第 1 引数 general-array が,クラス<general-vector>又はクラス

<general-array

*

>のインスタンスでない場合は,エラーが発生する(エラー名 domain-error)。

例  (defglobal array1 (create-array ’(3 3 3) 0)) ⇒ array1

array1

⇒ #3a(((0 0 0) (0 0 0) (0 0 0))

        ((0 0 0) (0 0 0) (0 0 0))

        ((0 0 0) (0 0 0) (0 0 0)))

(aref array1 0 1 2)

⇒ 0

(setf (aref array1 0 1 2) 3.14)

⇒ 3.14

(aref array1 0 1 2)

⇒ 3.14

(aref (create-array ’(8 8) 6) 1 1)

⇒ 6

(aref (create-array ’() 19))

⇒ 19

(setf (aref basic-array z*) obj)  →<object>

特殊形式

(set-aref obj basic-array z*)  →<object>

関数

(setf (garef general-array z*) obj)  →<object>

特殊形式

(set-garef obj general-array z*)  →<object>

関数

これらは,aref 又は garef によって取得可能なオブジェクトを obj で置き換える。返り値は,obj とする。


74

X 3012 : 1998 (ISO/IEC 13816 : 1997)

basic-array

general-array 及び添字 の並びに関する制約条件は,aref 及び garef のものと同じとする。

例  (setf (aref array1 0 1 2) 3.15)

⇒ 3.15

(set-aref 51.3 array1 0 1 2)

⇒ 51.3

(array-dimensions basic-array)  →<list>

関数

関数 array-dimensions は,与えられた basic-array の各次元の大きさをリストとして返す。basic-array 

クラス<basic-array>のインスタンスでない場合は,エラーが発生する(エラー名 domain-error

。返り値の

リストが変更された場合は,結果は未定義とする。

例  (array-dimensions

  (create-array ’(2 2) 0))

⇒ (2  2)

(array-dimensions (vector ’a ’b))

⇒ (2)

(array-dimensions "foo")

⇒ (3)

15.

ベクタ  ベクタは,1 次元の配列とする。配列とベクタとの関係については,14.1 による。

一般ベクタ(クラス<general-vector>のインスタンス)は,次のとおり表記する。

#(x

1

 x

2

...x

n

)

(basic-vector-p obj)  →真偽値

関数

(general-vector-p obj)  →真偽値

関数

関数 basic-vector-p は,obj がクラス<basic-vector>のインスタンスである場合は t を返し,それ以外の場

合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

関数 general-vector-p は,obj が一般ベクタ(クラス<general-vector>のインスタンス)である場合は t を返

し,それ以外の場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (mapcar (lambda (x)

            (list (basic-vector-p x)

                   (general-vector-p  x)))

          ’((a b c)

            "abc"

            #(a b c)

            #1a(a b c)

            #2a((a)(b)(c))))

⇒ ((nil nil) (t nil) (t t) (t t) (nil nil))

(create-vector i [initial-element])  →<general-vector>

関数

関数 create-vector は,長さ の一般ベクタを生成して返す。initial-element が与えられれば,新しいベク

タの要素は,このオブジェクトで初期化され,そうでなければ,初期化は処理系定義とする。要求された

ベクタの割当てができない場合は,エラーが発生する(エラー名 cannot-create-vector

が非負整数でな

い場合は,エラーが発生する(エラー名 domain-error

initial-element は,いかなる ISLISP オブジェクト

でもよい。

例  (create-vector 3 17)

⇒ # (17 17 17)


75

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(create-vector 2 #

\a)

⇒ #  (#\a #\a)

(vector obj

*

)  →<general-vector>

関数

関数 vector は,引数 obj を要素とする新しい一般ベクタを返す。したがって,新たに作成されるベクタ

の長さは,引数として渡された obj の個数と一致する。ベクタは,0 から長さ未満までの範囲の整数で添

字 付 け さ れ る 。 要 求 さ れ た ベ ク タ の 割 当 て が で き な い 場 合 は , エ ラ ー が 発 生 す る ( エ ラ ー 名

cannot-create-vector

。各 obj は,いかなる ISLISP オブジェクトでもよい。

例  (vector ’a ’b ’c)

⇒ #(a b c)

(vector)

⇒ #()

16.

文字列クラス  文字列は,<character>型の要素だけを格納可能なベクタとする。配列,ベクタ及び文

字列の関係は,14.1 による。

処理系定義のいかなる文字も,文字列の要素とすることができる。ISLISP では,文字列の添字は,0 か

ら始まる。要素となるすべての文字を順に並べ,二重引用符“"”で囲むことで,文字列は表記する。文字

列中に二重引用符がある場合,その二重引用符の直前に逆斜線“\”を置かねばならない。文字列中に逆

斜線がある場合,その逆斜線の直前にもう一つの逆斜線“\”を置かねばならない。プログラムテキスト

中にリテラルとして含まれる文字列は,変更不可能なオブジェクトとする。印字文字(12.参照)以外の文

字の表現は,処理系定義とする。

(stringp obj)  →真偽値

関数

関数 stringp は,obj が文字列(クラス<string>のインスタンス)である場合は t を返し,それ以外の場合

は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (stringp "abc")

⇒ t

(stringp ’abc)

⇒ nil

(create-string i [initial-character])  →<string>

関数

関数 create-string は,長さ の文字列を生成して返す。initial-character が与えられれば,新しい文字列中

の文字は,この文字 initial-character で初期化され,そうでなければ,初期化は処理系定義とする。要求さ

れた文字列の割当てができない場合は,エラーが発生する(エラー名 cannot-create-string

が非負整数で

ない場合又は initial-character が文字でない場合は,エラーが発生する(エラー名 domain-error

例  (create-string 3 #\a)

⇒ "aaa"

(create-string 0 #

\a)

⇒ ""

(string= string

1

 string

2

)  →準真偽値

関数

(string/= string

1

 string

2

)  →準真偽値

関数

(string< string

1

 string

2

)  →準真偽値

関数

(string> string

1

 string

2

)  →準真偽値

関数

(string>= string

1

 string

2

)  →準真偽値

関数

(string<= string

1

 string

2

)  →準真偽値

関数

関数 string=は,string

1

が string

2

と同じ文字列かどうか検査する。関数 string<は,string

1

が string

2

より小


76

X 3012 : 1998 (ISO/IEC 13816 : 1997)

さいかどうか検査する。関数 string<=は,string

1

が string

2

以下かどうか検査する。

ここで使用される順序は,文字の比較順序に基づく。

二つの文字列は,それらの長さが同じく であり,かつ,0<I<であるすべての について, (char= (elt

string

1

 i) (elt string

2

 i))が成り立つ場合に,string=とする。

二つの文字列 string

1

及び string

2

は,それぞれの文字が最初に異なる位置において,string

1

の文字が string

2

の対応する文字と比べて char<であるか,又は,string

1

が string

2

より長さが短く,かつ,string

1

中のすべて

の文字が string

2

の先頭から一致する場合に,string<とする。

二つの文字列は,それらが string<であるか又は string=であれば,string<=とする。

二つの文字列は,それらが string=でない場合,string/=とする。二つの文字列は,それらが string<=でな

い場合,string>とする。二つの文字列は,それらが string<でない場合,string>=とする。

これらの六つの文字列比較関数は,検査する条件が満たされる場合には,処理系定義の nil 以外の値を

返し,そうでなければ nil を返す。

string

1

又は string

2

のいずれかが文字列でない場合は,エラーが発生する(エラー名 domain-error

例  (if (string= "abcd" "abcd") t nil)

⇒ t

(if (string= "abcd" "wxyz") t nil)

⇒ nil

(if (string= "abcd" "abcde") t nil)

⇒ nil

(if (string= "abcde" "abcd") t nil)

⇒ nil

(if (string/= "abcd" "wxyz") t nil)

⇒ t

(if (string< "abcd" "abcd") t nil)

⇒ nil

(if (string< "abcd" "wxyz") t nil)

⇒ t

(if (string< "abcd" "abcde") t nil)

⇒ t

(if (string< "abcde" "abcd") t nil)

⇒ nil

(if (string<= "abcd" "abcd") t nil)

⇒ t

(if (string<= "abcd" "wxyz") t nil)

⇒ t

(if (string<= "abcd" "abcde") t nil)

⇒ t

(if (string<= "abcde" "abcd") t nil)

⇒ nil

(if (string> "abcd" "wxyz") t nil)

⇒ nil

(if (string>= "abcd" "abcd") t nil)

⇒ t

(char-index char string [start-position])  →<object>

関数

関数 char-index は,string 中の char の位置を返す。探索は,start-position(文字列の先頭位置を 0 とする。

で示される位置から始まる。start-position の省略時値は 0 とする。探索に成功した場合に返す値は,string

の先頭からのオフセットであり,探索の開始点からのオフセットではない。char が string 中に存在しなか

った場合は,nil を返す。比較には,関数 char=を用いる。

char

が文字でない場合又は string が文字列でない場合は,エラーが発生する(エラー名 domain-error)。

例  (char-index #\b "abcab")

⇒ 1

(char-index #

\B "abcab")

⇒ nil

(char-index #

\b "abcab" 2)

⇒ 4

(char-index #

\d "abcab")

⇒ nil


77

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(char-index #

\a "abcab" 4)

⇒ nil

(string-index substring string [start-position])  →<object>

関数

関数 string-index は,string 中の substring の位置を返す。探索は,start-position(文字列の先頭位置を 0

とする。

)で示される位置から始まる。start-position の省略時値は 0 とする。探索に成功した場合に返す値

は,string の先頭からのオフセットであり,探索の開始点からのオフセットではない。その substring が string

中に存在しなかった場合は,nil を返す。部分文字列の存在検査は,二つの文字列の対応する要素について,

char=を順次使用することによって実行される。

substring

又は string のいずれかが文字列でない場合は,エラーが発生する(エラー名 domain-error

例  (string-index "foo" "foobar")

⇒ 0

(string-index " bar " " foobar")

⇒ 3

(string-index " FOO " " foobar")

⇒ nil

(string-index " foo " " foobar" 1)

⇒ nil

(string-index " bar " " foobar" 1)

⇒ 3

(string-index " foo" "")

⇒ nil

(string-index "" "foo

”)

⇒ 0

(string-append string*)  →<string>

関数

関数 string-append は,各 string の文字の並びを連結して得られる文字列を返す。string が一つも与えられ

なかった場合は,""を返す。string のいずれかが文字列でない場合は,エラーが発生する(エラー名

domain-error

この関数は,引数を変更しない。結果が引数 string と構造を共有するかどうか,更にどの場合に共有す

るかは,処理系定義とする。

文字列の割当てができない場合は,エラーが発生する(エラー名 cannot-create-string

例  (string append "abc" "def")

⇒ "abcdef"

(string-append "abc" "abc")

⇒ "abcabc"

(string-append "abc" "")

⇒ "abc"

(string-append "" "abc")

⇒ "abc"

(string-append "abc" "" "def")

⇒ "abcdef"

17.

列  クラス<basic-vector>又はクラス<list>に属するオブジェクトを総称して,列 (sequence) と呼ぶ。

(length sequence)  →<integer>

関数

関数 length は,sequence の長さを 0 以上の整数として返す。

sequence

がベクタであれば,length は,その長さを返す。

sequence

がリストであれば,結果は,リスト中の要素数とする。要素自身がリストである場合,この部

分リスト中の要素は,数えない。ドットリストの場合,length は,リストの最上位のコンスの個数を返す。

例えば,’(a b. c)  ≡  (cons ’a (cons ’b ’c))  であることから,  (length ’(a b . c))  ⇒  2 とする。

sequence

がベクタ又はリストでない場合は,エラーが発生する(エラー名 domain-error

例  (length ’(a b c))

⇒ 3


78

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(length ’(a (b) (c d e)))

⇒ 3

(length ’())

⇒ 0

(length (vector ’a ’b ’c))

⇒ 3

(elt sequence z)  →<object>

関数

列 sequence 及び 0<z< (length sequence)  を満たす整数 を与えられると,関数 elt は,添字 で示される

sequence

の要素を返す。添字は,0 から始まる。すなわち,z=0 は,第 1 要素を指示する。が,上の範囲

外の整数である場合は,エラーが発生する(エラー名 index-out-of-range

sequence

がベクタ若しくはリストでない場合又は z が整数でない場合は,エラーが発生する(エラー名

domain-error

例  (elt ’(a b c) 2)

⇒ c

(elt (vector ’a ’b ’c) 1)

⇒ b

(elt "abc" 0)

⇒ #\a

(setf (elt sequence zobj)  →<object>

特殊形式

(set-elt obj sequence z)  →<object>

関数

これらは,elt で示される場所指定を受け取り,この場所を obj で更新する。返り値は,obj とする。整

数 は,0<z< (length sequence)  を満足しなければならない。

z

が正しい添字の範囲外の整数である場合は,エラーが発生する(エラー名 index-out-of-range

sequence

がベクタ若しくはリストでない場合又は が整数でない場合は,

エラーが発生する

(エラー名 domain-error

obj

は,いかなる ISLISP オブジェクトでもよい。

例  (let ((string (create-string 5 #\x)))

  (setf (elt string 2) #\0)

x)

⇒ "xx0xx"

(subseq sequence z

1

 z

2

)  →列

関数

列 sequence と 0<z

1

<z

2

< (length sequence)  を満たす二つの整数 z

1

及び z

2

とを与えられると,

関数 subseq は,

長さが z

2

z

1

で添字が z

1

以上 z

2

未満の要素を含む部分列を返す。部分列は,新たに割り当てられ,sequence

と同じクラスに属する。

要求された部分列の割当てができない場合は,エラーが発生する(エラー名 cannot-create-sequence

z

1

又は z

2

が上の範囲外である場合は,エラーが発生する(エラー名 index-out-of-range

sequence がベクタ若

しくはリストでない場合,z

1

が整数でない場合又は z

2

が整数でない場合は,エラーが発生する(エラー名

domain-error

例  (subseq "abcdef" 1 4)

⇒ "bcd"

(subseq ’(a b c d e f) 1 4)

⇒ (b c d)

(subseq (vector ’a ’b ’c ’d ’e ’f) 1 4)

⇒ #(b c d)

(map-into destination function sequence*)  →列

関数


79

X 3012 : 1998 (ISO/IEC 13816 : 1997)

関数 map-into は,列 sequence 中の各要素に順次 function を適用し,それらの結果が含まれるように

destination

を破壊的に変更する。destination を返す。

destination

及び各 sequence がすべて同じ長さでない場合,

(いずれかの sequence 又は destination で)最も

短い列が終わったときに,繰返しが終了する。

function

の呼出しは左から右へと進む。したがって,function が副作用をもつ場合,利用者はこの順序に

依存してよい。

destination

がベクタ又はリストでない場合は,エラーが発生する(エラー名 domain-error

sequence 

いずれかがベクタ又はリストでない場合は,エラーが発生する(エラー名 domain-error

例  (setq a (list 1 2 3 4))

⇒ (1 2 3 4)

(setq b (list 10 10 10 10))

⇒ (10 10 10 10)

(map-into a #’+ a b)

⇒ (11 12 13 14)

a

⇒ (11 12 13 14)

b

⇒ (10 10 10 10)

(setq k ’(one two three))

⇒ (one two three)

(map-into a #’cons k a)

⇒ ((one.1)(two.12)(three.13)14)

(let ((x 0))

  (map-into a

    (lambda () (setq x (+ x 2)))))

⇒ (2 4 6 8)

a

⇒ (2 4 6 8)

18.

ストリームクラス  ストリームは,<stream>クラスのインスタンスとする。これらは,データの入力

元又は出力先の役割を果たすオブジェクトとする。

(streamp obj)  →真偽値

関数

関数 streamp は,obj がストリーム(クラス<stream>のインスタンス)である場合は t を返し,それ以外

の場合は nil を返す。obj は,いかなる ISLISP オブジェクトでもよい。引数がクラス<stream>のインスタン

スである場合,そのストリームが開いていても閉じていても,streamp は,影響を受けない。

例  (streamp (standard-input))

⇒ t

(streamp ’())

⇒ nil

(open-stream-p obj)  →真偽値

関数

関数 open-stream-p は,

obj

が開いているストリームである場合は t を返し,

それ以外の場合は nil を返す。

(input-stream-p obj)  →真偽値

関数

関数 input-stream-p は,obj が入力操作を扱うことができるストリームである場合は t を返し,それ以外

の場合は nil を返す。

例  (input-stream-p (standard-input))

⇒ t

(input-stream-p (standard-output))

⇒ nil

(input-stream-p ’(a b c))

⇒ nil

(output-stream-p obj)  →真偽値

関数


80

X 3012 : 1998 (ISO/IEC 13816 : 1997)

関数 output-stream-p は,obj が出力操作を扱うことができるストリームである場合は t を返し,それ以外

の場合は nil を返す。

例  (output-stream-p (standard-output))

⇒ t

(output-stream-p (standard-input))

⇒ nil

(output-stream-p "hello")

⇒ nil


81

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(standard-input)  →<stream>

関数

(standard-output)  →<stream>

関数

(error-output)  →<stream>

関数

関数 standard-input は,入力関数の省略時ストリームとして使用されるストリームを返す。

関数 standard-output は,出力関数の省略時ストリームとして使用されるストリームを返す。

関数 error-output は,警告及びエラーメッセージのための省略時ストリームとして使用されるストリーム

を返す。

これらの関数が返す値は,初期状態では処理系定義であるが,動的に変更できる(with-standard-input,

with-standard-output 及び with-error-output 参照)。

(with-standard-input stream-form form*)  →<object>

特殊演算子

(with-standard-output stream-form form*)  →<object>

特殊演算子

(with-error-output stream-form form*)  →<object>

特殊演算子

これらの特殊形式は,まず引数 stream-form を評価してストリーム を作り,次に対応する関数

(standard-input,standard-output 又は error-output)がストリーム を返す動的環境の中でその本体 form*を

評価する。これらの特殊形式の返り値は,本体の最後の form を評価した結果(form がない場合は,nil)

とする。

例  (with-standard-input (create-string-input-stream "this is a string" )

  (list (read) (read)))

⇒ (this  is)

18.1

ファイルへのストリーム  ストリームは,ファイル又は入出力装置に接続されることがある。名前

が与えられると,その名前のファイルに接続されたストリームを作成することができる。ISLISP では,名

前が付けられたファイルだけを取り扱う。

ファイル名 (file name) は,文字列で表現する。ファイル名の正しい構文は,処理系定義とする。

フ ァ イ ル へ の ス ト リ ー ム は , open-input-file , open-output-file , open-io-file , with-open-input-file ,

with-open-output-file 又は with-open-io-file によって作成する。

(open-input-file filename [element-class])  →<stream>

関数

(open-output-file filename [element-class])  →<stream>

関数

(open-io-file filename [element-class])  →<stream>

関数

関数 open-input-file は,

ファイルを入力専用に開く。関数 open-output-file は,

ファイルを出力専用に開く。

関数 open-io-file は,ファイルを入出力用に開く。

filename

が文字列でない場合は,エラーが発生する(エラー名 domain-error

。対応するファイルが,処

理系定義の方法で開かれる。これらの関数は,filename で指定されたファイルに接続された<stream>クラス

のインスタンスを返す。

element-class

は,

要素の種類 (element class) であり,クラス<character>(省略時)であるか又は 2 進ス

トリームに用いられる 1 バイト中のビット数である正の整数のいずれかとする。すべての処理系は,8 ビ

ットからなるバイト(整数 0∼255 を表現可能なバイト)を許さなければならないが,処理系によっては,

他のバイトサイズを許す場合がある。

備考  2 進ストリームが使用された場合,バイト中のビットの順序及びワード中のバイトの順序(す

なわち,右から左か又は左から右か)は,それぞれ処理系定義とする。


82

X 3012 : 1998 (ISO/IEC 13816 : 1997)

例  (open-input-file "example.lsp" 8)

⇒ 処理系定義

(with-open-input-file (name filename [element-class]) form*)  →<object>

特殊演算子

(with-open-output-file (name filename [element-class]) form*)  →<object>

特殊演算子

(with-open-io-file (name filename [element-class]) form*)  →<object>

特殊演算子

これらの特殊形式は,

(それぞれ open-input-file,open-output-file 又は open-io-file を使用して)ファイル

ヘのストリームを開き,form*を評価し,ファイルを閉じ,そして最後の form によって返される値(form

がない場合は,nil)を返す。

filename

及び element-class は,評価され,ファイルを開く関数に引数として渡される。ファイルを開く

ことによって作成されたストリームは,name という名前の変数に(let が使用されたかのように)束縛さ

れる。したがって,識別子 name を使ってストリームを参照することができる。

これらの特殊形式の実行が終了する際に,その終了が正常かどうかにかかわらず,ストリームは閉じら

れる。この理由によって,ファイルを開閉する関数よりも,通常はこれらの特殊形式を使うことが多い。

例  (with-open-output-file (outstream "example.dat")

    (format outstream "hello"))

⇒ nil

(with-open-input-file (instream "example.dat")

    (read instream))

⇒ hello

(close stream)  →処理系定義

関数

関数 close は,ストリーム stream を閉じる。stream が閉じられた場合,入力操作又は出力操作に用いる

ことはできない。ファイルに対する stream を閉じると,stream とそのファイルとの関係は終了する。stream

が既に閉じられていた場合,この関数は,何もしない。結果の値は,処理系定義とする。stream がストリ

ームでない場合は,エラーが発生する(エラー名 domain-error

例  (defglobal input-str (open-input-file "data.lsp"))

⇒ input-str

(close input-str)

⇒ 処理系定義

(close input-str)

⇒ 処理系定義

(finish-output stream)  →<null>

関数

関数 finish-output は,stream で指示される出力先への,保留中の出力を出す。保留中の出力が終わるま

で待ち,nil を返す。例えば,保留中の出力がバッファに格納されている場合,finish-output は,ストリー

ムの行き先に出力するようバッファに命令する。stream が出力操作を扱えるストリームでない場合は,エ

ラーが発生する(エラー名 domain-error

例  (defglobal output-str (open-output-file "data.lsp"))

⇒ output-str

(finish-output output-str)

⇒ nil

18.2

その他のストリーム  次の関数によって,ファイル以外のストリームを作成できる。

      create-string-input-stream  create-string-output-stream

文字列ストリームは,文字列に対するストリームとする。入力では,入力関数が,入力文字列から得ら

れる文字の並びからオブジェクトを生成する。出力では,出力関数が文字の並びを生成し,出力文字列に

格納する。


83

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(create-string-input-stream string)  →<stream>

関数

関数 create-string-input-stream は,string からの入力ストリームを作成し,それを値として返す。

string

が文字列でない場合は,エラーが発生する(エラー名 domain-error

例  (let ((str (create-string-input-stream "this is a string")))

  (list (read str) (read str) (read str)))

⇒ (this is a)

(create-string-output-stream)  →<stream>

関数

関数 create-string-output-stream は,文字列出力ストリームを作成し,それを値として返す。文字列ストリ

ームへの出力は,get-output-stream-string によって取り出すことができる。

例  (let ((str (create-string-output-stream)))

  (format str "hello")

  (format str "world")

  (get-output-stream-string str))

⇒ "helloworld"

(get-output-stream-string stream)  →<string>

関数

関数 get-output-stream-string は,stream に対し,この関数の最後の呼出し以降出力されたすべての文字を

含む文字列を返す。この関数が以前に stream を引数として呼び出されていない場合は,ストリームの作成

以降出力されたすべての文字を含む文字列を返す。stream が create-string-output-stream によって作成された

ストリームでない場合は,エラーが発生する(エラー名 domain-error

例  (let ((out-str (create-string-output-stream)))

  (format out-str "This is a string")

  (let ((part1 (get-output-stream-string out-str)))

    (format out-str "right!")

    (list part1 (get-output-stream-string out-str))))

⇒ ("This is a string" "right!")

19.

入出力

19.1

入力関数の引数についての共通事項  入力を行う入力関数の多くは,引数を次のとおり扱う。

ストリームの終わりに到達した場合(すなわち,ストリームの最後の要素の次の要素を読み込もうとし

た場合)

,動作は eos-error-p の値(省略時値は t)に依存する。eos-error-p が nil であった場合は,入力関数

は eos-value(省略時値は nil)を返し,それ以外の場合はエラーが発生する(エラー名 end-of-stream

input-stream

が指定されていない場合は,標準入力ストリーム(関数 standard-input の返す値)を用いる。

input-stream

が述語 input-stream-p を満たさない場合は,エラーが発生する(エラー名 not-an-input-stream

19.2

文字入出力  文字の入出力には,次の操作を用いる。文字入出力操作を扱えないストリームに対し,

これらの操作を行おうとした場合は,エラーが発生する。

(read [input-stream [eos-error-p [eos-value]]])  →<object>

関数

関数 read は,ストリーム input-stream から ISLISP オブジェクトのテキスト表現を読み込み,その ISLISP


84

X 3012 : 1998 (ISO/IEC 13816 : 1997)

オブジェクトを返す。

input-stream

eos-error-p 及び eos-value の意味は,19.1 による。

例  (defglobal str (create-string-input-stream "hello" #(1 2 3) 123 #\\A"))

⇒ str

(read str)

⇒ hello

(read str)

⇒ # (1 2 3)

(read str)

⇒ 123

(read str)

⇒ #\A

(read str nil "the end")

⇒ "the  end”

(read-char [input-stream [eos-error-p [eos-value]]])  →<object>

関数

関数 read-char は,input-stream から 1 文字を読み込み,これに対応する文字オブジェクトを返す。

input-stream

eos-error-p 及び eos-value の意味は,19.1 による。

例  (defglobal str (create-string-input-stream "hi"))

⇒ str

(read-char str)

⇒ #\h

(read-char str)

⇒ #\i

(read-char str)

エラーが発生する。

(preview-char [input-stream [eos-error-p [eos-value]]])  →<object>

関数

関数 preview-char は,input-stream の次の文字を(もしあれば)返す。その文字は消費されない。つまり,

次にそのストリームから文字を読んだ場合には,同じ文字が現れる。

input-stream

eos-error-p 及び eos-value の意味は,19.1 による。

例  (let ((s (create-string-input-stream "foo")))

  (list (preview-char s) (read-char s) (read-char s)))

⇒ (#\f #\f #\o)

(read-line [input-stream [eos-error-p [eos-value]]])  →<object>

関数

関数 read-line は,input-stream から 1 行分の文字を読み込み,これを文字列として返す(行の最後の復帰

改行文字は含まない。

。次の復帰改行文字より前にストリームの終わりに到達した場合,終わりに到達す

るまでに読み込んだ行が空行でなかったときは,その行を返す。

input-stream

eos-error-p 及び eos-value の意味は,19.1 による。

例  (with-open-output-file (out "newfile")

  (format out "This is an example")

  (format out "

%")

  (format out "look at the output file"))

⇒ nil

(defglobal str (open-input-file "newfile"))

⇒ str

(read-line str)

⇒ "This is an example"

(read-line str)

⇒ "look at the output file"


85

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(stream-ready-p input-stream)  →真偽値

関数

関数 stream-ready-p は,stream から次の要素を得ようとしたときに,処理系が待ち状態に入らない場合は

t を返し,それ以外の場合は nil を返す。stream が入力操作可能なストリームでない場合は,エラーが発生

する(エラー名 domain-error

例  (with-open-output-file (out "testfile.dat")

  (format out "This is an example"))

⇒ nil

(with-open-input-file (in "testfile.dat")

  (stream-ready-p in))

⇒ t

(format output-stream format-string obj*)  →<null>

関数

(format-char output-stream char)  →<null>

関数

(format-float output-stream float)  →<null>

関数

(format-fresh-line output-stream)  →<null>

関数

(format-integer output-stream integer radix)  →<null>

関数

(format-object output-stream obj escape-p)  →<null>

関数

(format-tab output-stream column)  →<null>

関数

関数 format は,format-string に従って印字をするという副作用をもつ。返り値は,nil とする。引数

outoput-stream

が , 述 語 output-stream-p を 満 た さ な い 場 合 は , エ ラ ー が 発 生 す る ( エ ラ ー 名

not-an-output-stream

format-string が文字列でない場合は,エラーが発生する(エラー名 domain-error

format の書式指定を次に示す。ここで,obj は,format の引数 obj*の中の,次に印字すべき引数を指す。

A

整形 (aesthetic) : obj は,いかなるオブジェクトでもよい。obj は,

S の場合と同様に印字さ

れるが,エスケープ文字は印字されない。文字は,変換されずに直接出力される。すなわち,

この書式指定が生成する出力は,人間が読むのに適している。

これは,(format-object output-stream obj nil)  によって実装される。

B 2 進 (binary) : obj が整数でない場合は,エラーが発生する。obj は,2 進数で印字される。

これは,(format-integer output-stream obj 2)  によって実装される。

C

文字 (character) : obj が文字でない場合は,エラーが発生する。obj は,変換されずに直接出

力される。

これは,(format-char output-stream obj)  によって実装される。

D 10 進 (decimal) : obj が整数でない場合は,エラーが発生する。obj は,10 進数で印字される。

これは,(format-integer output-stream obj 10)  によって実装される。

G

一般的な浮動小数点数  (general floating-point number) : obj が数値でない場合は,エラーが発生

する。Obj は,浮動小数点数として印字される。

これは,(format-float output-stream obj)  によって実装される。

O 8 進 (octal) : obj が整数でない場合は,エラーが発生する。obj は,8 進数で印字される。

これは,(format-integer output-stream obj 8)  によって実装される。

nR

基数 (radix) : obj が整数でない場合は,エラーが発生する。obj は,進数 (2<n<36)  で印字さ

れる。


86

X 3012 : 1998 (ISO/IEC 13816 : 1997)

これは,(format-integer output-stream obj n)  によって実装される。

S S 式:obj は,いかなるオブジェクトでもよい。この書式指定は,必要であればエスケープ文

字とともに,obj のテキスト表現を出力する。すなわち,この書式指定の生成する出力は,関数

read への入力として適している。

これは,(format-object output-stream obj t)  によって実装される。

nT

タブ (tab) : 第 けたへ移動するための空白文字を出力する(ここで,第 0 けたとは,左マー

ジンのこととする。

。既に第 けた又はそれ以降に達していた場合,空白文字を一つ出力する。

処理系が現在のけたの位置を決定できない場合,その動作は処理系定義とするが,少なくとも

一つの空白文字を出力する。

これは,(format-tab output-stream n)  によって実装される。

X 16 進 (hexadecimal) : obj が整数でない場合は,エラーが発生する。obj は,16 進数で印字され

る。

これは,(format-integer output-stream obj 16)  によって実装される。

%

復帰改行:#\newline 文字を,出力する。

これは,(format-char output-stream #\newline)  によって実装される。

&

条件付き復帰改行:出力ストリームが行の先頭にあると決定できない場合に,#\newline 文

字を出力する。

これは,(format-fresh-line output-stream)  によって実装される。

∼∼

チルダ:チルダ  (

)  を出力する。

これは,(format-char output-stream #\

)  によって実装される。

例  (format output-stream "No result")

⇒ nil

出力:No result

(format output-stream "The result is

A and nothing else." "meningitis")

                                                                         ⇒ nil

出力:The result is meningitis and nothing else.

(format output-stream "The result i

C" #

\s)

⇒ nil

出力:The result is

(format output-stream "The results are

S and

S." 1 #

\a)

⇒ nil

出力:The results are 1 and #\a.

(format output-stream "Binary code

B" 150)

⇒ nil

出力:Binary code 10010110

(format output-stream "permission

O" 493)

⇒ nil

出力:permission 755


87

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(format output-stream "You

X

X" 2989 64206)

⇒ nil

出力:You BAD FACE

(progn

  (format output-stream "

&Name

10Tincome

20Ttax ~%")

  (format output-stream "

A

10T

D

20T

D" "Grummy" 23000 7500))

⇒ nil

出力:Name     income    tax

      Grummy   23000     7500

(format output-stream "This will be split into

%two lines.")

⇒ nil

出力:This will be split into

      two lines.

(format output-stream "This is a tilde:

∼∼

")

⇒ nil

出力:This is a tilde:

19.3  2

進入出力  2 進入出力には次の操作を用いる。2 進入出力操作を扱えないストリームに対し,これ

らの操作を行おうとした場合は,エラーが発生する。

(read-byte input-stream [eos-error-p [eos-value]])  →<integer>

関数

関数 read-byte は,

input-stream

から 1 バイトを読み込み,

それを返す。

1 バイト中のビット数は,input-stream

の要素の種類によって決定される(open-input-file 参照)

input-streameos-error-p

及び eos-value の意味は,19.1 による。

例  ;; この例では,8 ビットの文字コードが,ファイルに格納されるものと仮定する。

(defglobal byte-example (open-output-stream "byte-ex"))

⇒ byte-example

(format byte-example "hello")

⇒ nil

(close byte-example)

⇒ 処理系定義

(setq byte-example (open-input-stream "byte-ex" 8))

⇒ 処理系定義

(read-byte byte-example)

⇒ 104 (処理系定義)

(read-byte byte-example)

⇒ 101 (処理系定義)

(read-byte byte-example)

⇒ 108 (処理系定義)

(read-byte byte-example)

⇒ 108 (処理系定義)

(read-byte byte-example)

⇒ 111 (処理系定義)

(write-byte z output-stream)  →<integer>

関数

関数 write-byte は,を output-stream に書き,その を返す。が output-stream の要素の種類に適した範

囲の整数でない場合又は output-stream が出力操作を扱えるストリームでない場合は,

エラーが発生する

(エ

ラー名 domain-error

例  (let ((out-str (open-output-stream "byte-example" 8)))

  (write-byte #b101 out-str)

  (close out-str))

⇒ 処理系定義


88

X 3012 : 1998 (ISO/IEC 13816 : 1997)

20.

ファイル

(probe-file filename)  →真偽値

関数

関数 probe-file は,filename によって指定されたファイルが存在する場合は t を返し,それ以外の場合は

nil を返す。filename が文字列でない場合は,エラーが発生する(エラー名 domain-error)。

例  (probe-file "notexist.lsp")

⇒ nil

(defglobal new-file (open-output-file "notexist.lsp"))

⇒ new-file

(close new-file)

⇒ 処理系定義

(probe-file "notexist.lsp")

⇒ t

(file-position stream)  →<integer>

関数

関数 file-position は,stream に付随する

ファイル位置 (file position) を返す。

ファイル位置は,ストリーム中の位置を表す非負整数とする。2 進ストリームの場合,ファイル位置は,

ストリーム中の先行するバイト数を表す。次の式のいずれかを実行するたびに,ファイル位置は 1 ずつ増

加する。

      (read-byte  stream)

      (write-byte  z stream)

文字ストリームの場合,ファイル位置は,次の式のいずれかを実行するたびに増加する。その増分値は,

処理系定義の非負整数とする。

      (format  stream...)

      (format-char  stream char)

      (format-float  stream float)

      (format-fresh-line  stream)

      (format-integer  stream integer radix)

      (format-object  stream obj escape-p)

      (format-tab  stream column)

      (report-condition  condition stream)

      (read-char  stream)

      (read-line  stream)

      (read  stream)

増分値は,出力及びファイル位置に依存する。どの整数がファイルの第 1 要素を表すかは,処理系定義

とする。stream がファイルへのストリーム又はファイルからのストリームでない場合は,エラーが発生す

る(エラー名 domain-error

例  ;; この例では,8 ビットの文字コードが,ファイルに格納されるものと仮定する。

(defglobal example (open-output-file "example.lsp"))

⇒ example

(format example "hello")

⇒ nil

(close example)

⇒ 処理系定義

(setq example (open-input-stream "example.lsp" 8))

⇒ 処理系定義

(file-position example)

⇒ 0 (処理系定義)

(read-byte example)

⇒ 104 (処理系定義)


89

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(file-position example)

⇒ 1 (処理系定義)

(set-file-position stream z)  →<integer>

関数

関数 set-file-position は,ストリーム stream のファイル位置(file-position 参照)を,に変更しようとす

る。正確に の位置に移動することができない場合,ファイル内で処理系定義の動作が実行される。

位置に移動できた場合でも,移動できなかった場合でも,返される値は新しいファイル位置とする。

stream

がファイルへのストリームでもファイルからのストリームでもない場合,又は が非負整数でな

い場合は,エラーが発生する(エラー名 domain-error

例  (set-file-position example 4)

⇒ 4

(file-length filename element-class)  →<object>

関数

関数 file-length は,filename によって指定されたファイルの長さを返す。長さが決定できない場合は,nil

を返す。element-class は,要素の種類(18.1 参照)を指定する。filename が文字列でない場合は,エラーが

発生する(エラー名 domain-error

例  (file-length "file27.dat" 8)

⇒ 25

;;

処理系は,2 ビットからなるバイトを実装する必要はない。

(file-length "file27.dat" 2)

⇒ 100

21.

例外処理機能  例外処理機能は,エラー処理機能 (error system) とも呼ばれる。実行時に何らかの問

題が検出されたとき,適合するプログラムの制御の下でその状態を表現し,解決する手段を,例外処理機

能が提供する。

21.1

例外状態  問題が検出されたとき,その状況を表現する例外状態 (condition) が生成され,例外状態

によって表された状況が,

通知 (signaling) と呼ぶ処理によって伝えられる。この通知処理は,動的に設定

される

ハンドラ (handler) に,問題を解決する機会を与える。通常の ISLISP オブジェクトであることを強

調するために,例外状態は,

例外オブジェクト (condition object) とも呼ばれる。

図 に,例外状態クラスに関する継承関係を示す。

幾つかの例外状態クラスに対しては,インスタンス生成時に,そのインスタンスに付随するデータ(21.3

参照)を与えるために,create が初期化引数を要求する。

実行的に検出されるプログラム誤りを表す例外状態は,

エラー (error) と呼ぶ。エラー及び処理系の制

約を表す例外状態を総称して,

重大な例外状態 (serious condition) と呼ぶ。

備考 LISP の方言によっては,“重大でない”例外状態の考え方をもつものがある。そのような例外

状態は,この規格の範囲を超えている。したがって,ここでは,最も一般的な例外状態クラス

として,<serious-condition>を使用する。

21.2

例外状態の通知及び扱い  例外状態が通知されたとき,状況を表す例外オブジェクトをただ一つの

引数として

活性ハンドラ (active handler) が起動される。初期の活性ハンドラは,システムによって生成さ

れている。このハンドラの動作は,処理系定義(例えば,最上位へ戻る,プログラムを終了する,対話型

デバッガに入るなど)とする。利用者のプログラムが,ハンドラを生成してもよい(with-handler 参照)

ある時点では,ただ一つのハンドラが活性であるものとする。with-handler で新しいハンドラを生成する

と,前の活性ハンドラは遮へいされる。この新しく生成されたハンドラは,別の with-handler の利用によ


90

X 3012 : 1998 (ISO/IEC 13816 : 1997)

って遮へいされない限り,それが付随するコード本体の実行中,活性であるものとする。

ハンドラ関数が呼び出されると,signal-condition が呼び出された時点の動的環境において実行を行う。

ただし,ハンドラ全体の状態は,呼び出されたハンドラ関数が活性ハンドラとして設定された時点の状態

に戻る。

備考  これは,ハンドラの実行中にエラーが起きても,そのハンドラ自身がエラーを処理することを

期待されていないことを意味する。ハンドラがそれ自身の実行中のエラーを処理する必要があ

れば,関数定義に labels を利用し,ハンドラ関数の本体内で自分自身をハンドラとして再設定

すればよい。

ハンドラは,その実行終了時に,signal-condition の呼出しの外側へ制御を移行しなければならない。そ

のような制御の移行は,go,throw 若しくは return-from の利用によって明示的に行われるか,又は,これ

らと同等の効果をもつ continue-condition の利用によって行われなければならない。ハンドラが正常に戻る

場合は,結果は未定義とする。ハンドラは,必ず制御を移行する。

ハンドラは,引数として受け取った例外オブジェクトを signal-condition に受け渡すことによって,他の

ハンドラに例外処理を委任してもよい。

21.2.1

例外通知に関する操作

(error error-string obj*)  →<object>

関数

関数 error は,エラーを通知する。

error-string

及び一連の obj は,format に与えられるとエラーメッセージを生成するが,これらの引数が

使われるかどうかは,処理系定義とする。

これは,次と同値とする。

      (signal-condition

        (create  (class  <simple-error>)

                  ’format-string  error-string

                  ’format-arguments  (list  obj*)))

        nil)

(cerror continue-string error-string obj*)  →<object>

関数

関数 cerror は,error と似ているが,通知されるエラーは継続可能(continue-condition 参照)とする。引

数 continue-string は,この関数が戻る場合に何が起こるかを記述する文字列とする。

これは,次と同値とする。

      (signal-condition

        (create  (class  <simple-error>)

                  ’format-string  error-string

                  ’format-arguments  (list  obj*)))

        (let  ((str  (create-string-output-stream)))

          (format  str  continue-string obj*)

          (get-output-stream-string  str)))

(signal-condition condition continuable)  →<object>

関数

関数 signal-condition は,condition を処理するために,例外処理機能を呼び出す。

continuable

が nil のとき,継続(continue-condition 参照)しようとした場合の結果は,未定義とする。こ


91

X 3012 : 1998 (ISO/IEC 13816 : 1997)

の場合,signal-condition の呼出しは正常には戻らない。

continuable

が nil でない場合,signal-condition の呼出しから戻ることができる(continue-condition 参照)

この場合,continuable の値は,継続の結果を記述する文字列又は記号 t とする。後者の場合,"Continue with

no special action."  といった処理系定義の文字列が利用される。

例  (signal-condition (create (class <simple-error>)

                               ’format-string  "A

A problem occurred."

                               ’format-arguments  ’(bad))

                      nil)

21.2.2

例外処理に関する操作

(ignore-error form*)  →<object>

特殊演算子

特殊形式 ignore-errors は,form*の実行中にエラーが発生した場合,ignore-errors が直ちに nil を返すよう

な,<error>クラスに対するハンドラを生成する。その後,form*を左から右に順に実行し,実行が正常に終

了した場合,最後の form が返す値(form がない場合は,nil)を返す。

(report-condition condition stream)  →<condition>

包括関数

包括関数 report-condition は,condition の自然言語による記述を stream に出力する。この包括関数は,利

用者定義の例外状態クラスに対して特殊化してもよい。

(condition-continuable condition)  →<object>

関数

関数 condition-continuable は,condition が継続可能でない場合は nil を返し,継続可能であれば,継続の

結果を記述する文字列を返す。

(continue-condition condition [value])制御の移行及びデータの転送

関数

関数 continue-condition は,condition を通知した signal-condition の呼出しを探し,その呼出しが value 

値として正常に戻るための処理を行うことによって,その signal-condition の呼出し以降の実行を

継続する

(continue)。value の省略時値は,nil とする。

condition

が継続可能でない場合は,結果は未定義とする。

(with-handler handler form*)  →<object>

特殊演算子

特殊形式 with-handler は,まず handler を評価する。その値は,関数でなければならない。この関数を

ンドラ関数 (handler function) と呼ぶ。このハンドラ関数は活性ハンドラ(21.2 参照)として設定され,そ

の後 form*が左から右に順に評価される。すべての form の評価が正常に終了した場合,最後の form の値を

返す。form がない場合は,nil を返す。

21.3

例外オブジェクトに付随するデータ  ISLISP で定義される例外状態クラスの幾つかに対しては,例

外オブジェクトの生成時にそのオブジェクトに付随するデータを与え,後で取り出すことができる。その

ようなクラスに対する初期化引数及びアクセス関数を,ここで定義する。

21.3.1

算術エラー

<arithmetic-error> operation

operation

 operands

operands

ここで,operation は実行されていた関数であり,operands は受け取った

引数のリストとする。

(arithmetic-error-operation arithmetic-error)  →<function>

関数


92

X 3012 : 1998 (ISO/IEC 13816 : 1997)

(arithmetic-error-operands arithmetic-error)  →<list>

関数

これらの関数は,arithmetic-error 生成時に,データとして与えられた operation 及び operands をそれぞれ

返す。arithmetic-error がクラス<arithmetic-error>の例外状態でない場合は,エラーが発生する(エラー名

domain-error

21.3.2

定義域エラー

<domain-error> object

object

 expected-class

expected-class

ここで,object は実際に与えられたオブジェクトであり,expected-class

は期待されるクラスとする。

(domain-error-object domain-error)  →<object>

関数

(domain-error-expected-class domain-error)  →<class>

関数

これらの関数は,domain-error 生成時に,データとして与えられた object 及び expected-class をそれぞれ

返す。domain-error がクラス<domain-error>の例外状態でない場合は,エラーが発生する(エラー名

domain-error

21.3.3

構文解析エラー

<parse-error> string

string

 expected-class

expected-class

ここで,string は構文解析中の文字列であり,expected-class は string 中の

テキストが表現することを期待されるクラスとする。

(parse-error-string parse-error)  →<string>

関数

(parse-error-expected-class parse-error)  →<class>

関数

これらの関数は,parse-error 生成時に,データとして与えられた string 及び expected-class をそれぞれ返

す。

parse-error

がクラス<parse-error>の例外状態でない場合は,

エラーが発生する

(エラー名 domain-error

21.3.4

単純なエラー

<simple-error> format-string

format-string

 format-arguments

format-arguments

ここで,format-string 及び format-arguments は,エラーメッセージを作成

するために format に渡される文字列及びオブジェクトのリストとする。

format-arguments

として与えられたリスト中の各オブジェクトは,format

の呼出しに対する個別の引数となる。

(simple-error-format-string simple-error)  →<string>

関数

(simple-error-format-arguments simple-error)  →<list>

関数

これらの関数は,simple-error 生成時に,データとして与えられた format-string 及び format-arguments 

それぞれ返す。simple-error がクラス<simple-error>の例外状態でない場合は,エラーが発生する(エラー名

domain-error

21.3.5

ストリームエラー


93

X 3012 : 1998 (ISO/IEC 13816 : 1997)

<stream-error> stream

stream

ここで,stream は,エラーが生じたストリームとする。

(stream-error-stream stream-error)  →<stream>

関数

関数 stream-error-stream は,stream-error 生成時に,データとして与えられた stream を返す。stream-error

がクラス<stream-error>の例外状態でない場合は,エラーが発生する(エラー名 domain-error

21.3.6

未定義実体のエラー

<undefined-entity> name

name

 namespace

namespace

ここで,name は,未定義であった識別子を表す記号とする。namespace

は,記号 variable,dynamic-variable,function 又は class のいずれかとする。

(undefined-entity-name undefined-entity)  →<symbol>

関数

(undefined-entity-namespace undefined-entity)  →<symbol>

関数

これらの関数は,undefined-entity 生成時に,データとして与えられた name 及び namespace を返す。

undefined-entity

が ク ラ ス <undefined-entity> の 例 外 状 態 で な い 場 合 は , エ ラ ー が 発 生 す る ( エ ラ ー 名

domain-error

undefined-entity-namespace の結果は,記号 variable,dynamic-variable,function 又は class のいずれかとす

る。

21.4

エラー名  この規格で名前を付けたエラー及びその意味を次に示す。

arity-error

関数の定義で許容されるパラメタ数に適合しない個数の引数を使って関

数が起動される場合に,このエラーが発生する。このエラーは,クラス

<program-error>の例外状態として表される。

cannot-create-array

このエラーは,割り当てることができない配列を割り当てる場合に,発

生する。このエラーは,クラス<storage-exhausted>の例外状態として表さ

れる。

cannot-create-cons

このエラーは,割り当てることができないコンスを割り当てる場合に,

発生する。このエラーは,クラス<storage-exhausted>の例外状態として表

される。

cannot-create-list

このエラーは,割り当てることができないリストを割り当てる場合に,

発生する。このエラーは,クラス<storage-exhausted>の例外状態として表

される。

cannot-create-sequence

このエラーは,列を生成する関数(例えば,subseq)がその列を割り当

てられない場合に,発生する。このエラーは,クラス<storage-exhausted>

の例外状態として表される。

cannot-create-string

このエラーは,割り当てることができない文字列を割り当てる場合に,

発生する。このエラーは,クラス<storage-exhausted>の例外状態として表

される。

cannot-create-vector

このエラーは,割り当てることができないベクタを割り当てる場合に,


94

X 3012 : 1998 (ISO/IEC 13816 : 1997)

発生する。このエラーは,クラス<storage-exhausted>の例外状態として表

される。

cannot-parse-number

このエラーは,parse-number 関数が受け取った stirng 引数が数値のテキス

ト表現でない場合に,発生する。このエラーは,クラス<parse-error>の例

外状態として表される。

control-error

このエラーは,ブロックから 2 回以上出ようとした場合,又は捕そくタ

グに対する catch 形式がない場合に,発生する。このエラーは,クラス

<control-error>の例外状態として表される。

division-by-zero

このエラーは,ゼロで割ろうとした場合に発生する。このエラーは,ク

ラス<division-by-zero>の例外状態として表される。

domain-error

このエラーは,引数クラスの制約をもつ標準関数に,引数として与えら

れたオブジェクトが,要求されるクラスのインスタンスでない場合に,

発生する。このエラーは,クラス<domain-error>の例外状態として表され

る。

end-of-stream  eos-error-p

引数が真のときに,ストリームの終端で文字若しくはバイト

を読もうとした場合,又は read や read-line がオブジェクトを読もうとし

ており,かつそのオブジェクトの読込みが終わる前にストリームの終端

が現れた場合に,このエラーは,発生する。このエラーは,クラス

<end-of-stream>の例外状態として表される。

immutable-binding

このエラーは,変更不可能な束縛を変更しようとする場合に,発生する。

このエラーは,クラス<program-error>の例外状態として表される。

improper-argument-list

このエラーは,apply 関数に与えられた最後の引数が nil で終わるリスト

でない場合に,発生する。このエラーは,クラス<program-error>の例外

状態として表される。

index-out-of-range

このエラーは,(elt のような)列中の要素をアクセスする関数に与えら

れた添字が,列の範囲を超えた整数である場合に,発生する。このエラ

ーは,クラス<program-error>の例外状態として表される。

not-an-input-stream

このエラーは,入力ストリームでないストリームから入力しようとした

場合に,発生する。このエラーは,クラス<domain-error>の例外状態とし

て表される。

not-an-output-stream

このエラーは,出力ストリームでないストリームに出力しようとした場

合に,発生する。このエラーは,クラス<domain-error>の例外状態として

表される。

unbound-variable

このエラーは,未束縛の変数をアクセスした場合に,発生する。このエ

ラーは,クラス<unbound-variable>の例外状態として表される。

undefined-entity

このエラーは,識別子によって示される実体が存在しないときに,その

実 体 を ア ク セ ス し た 場 合 に , 発 生 す る 。 こ の エ ラ ー は , ク ラ ス

<undefined-entity>の例外状態として表される。

undefined-function

このエラーは,関数がその起動時点で存在しない場合に,発生する。こ

のエラーは,クラス<undefined-function>の例外状態として表される。


95

X 3012 : 1998 (ISO/IEC 13816 : 1997)

発生しうる幾つかのエラーは,この規格では名前を付けていない。また,処理系によって追加されるエ

ラーもある。上のエラーが,起こりうるエラーのすべてではない。

22.

その他の機能

(identity obj)  →<object>

関数

関数 identity は,obj と eql であるオブジェクトを返す。obj は,いかなる ISLISP オブジェクトでもよい。

例  (identity ’(a b c))

⇒ (a b c)

(get-universal-time)  →<integer>

関数

関数 get-universal-time は,世界標準時の形で“現在の時刻”の近似値を返す。単位は秒とする。世界標

準時は,1900 年 1 月 1 日の始まり(すなわち,午前 0 時)からの秒数(うるう秒は無視する。

)を表す整

数とする。get-universal-time が 2 回呼び出される場合,最初の値は 2 回目の値以下とする。

処理系は,返される時刻が正しいことを確認する方法を備える必要はない。しかし,返される時刻が正

しくないと処理系が判断できる(例えば,時計がまだ初期化されていないことを決定できる)場合は,エ

ラーが発生する。

例  (get-universal-time)

⇒ 2901312000

(get-internal-real-time)  →<integer>

関数

(get-interna1-run-time)  →<integer>

関数

関数 get-internal-real-time は,現在の時刻を表す整数を返す。この値は,ある基準時刻からの相対時間と

し,単位は内部時間単位(internal-time-units-per-second 参照)とする。この関数を 2 回呼び出したときの値

の差は,2 回の呼出しの間の実際の経過時間とする。

関数 get-internal-run-time は,現在の実行時間を表す整数を返す。単位は内部時間単位とする。この時間

の正確な意味は,処理系定義とする。この関数を 2 回呼び出したときの値の差は,その間にプログラム実

行のために費やされた時間とする。

(internal-time-units-per-second)  →<integer>

関数

関数 internal-time-units-per-second は,処理系の内部時間単位の 1 秒当たりの個数を返す。


96

X 3012 : 1998 (ISO/IEC 13816 : 1997)

プログラミング言語 ISLISP JIS 原案作成委員会  構成表(敬称略・順不同)

氏名

所属

(委員長)

湯  淺  太  一

京都大学

(幹事)

岸  田  克  己

日本電信電話株式会社

(委員)

浅  井      登

株式会社富士通静岡エンジニアリング

伊  藤  貴  康

東北大学

梅  村  恭  司

豊橋技術科学大学

橋  爪  邦  隆

工業技術院

黒  川  利  明

日本アイ・ビー・エム株式会社

徳  永  英  二

TOK

長  坂      篤

沖電気工業株式会社

橋  本  繁  晴

財団法人日本規格協会

橋  本  ユキ子

日本電気株式会社

山  崎  憲  一

日本電信電話株式会社

(事務局)

三  田  真  弓

社団法人情報処理学会

(オブザーバ)

白  倉  悟  子

津田塾大学