この規格ページの目次
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オブジェクトでもよい。
――――― [JIS X 3012 pdf 21] ―――――
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参照)で本体から抜け出ない場合には,本体の最後の評
価形式の評価結果が値として返る。
関数が残余パラメタをもつ場合,残余パラメタに束縛されるリストであるL1は,無制限の存在期間をも
つ。L1は,新しく生成されるリストとする。ただし,関数がapplyで呼び出され,残余パラメタがその最
後の引数L2又はL2の後ろの一部分に束縛される場合,L1とL2とがリストを共有するかどうかは,処理系
――――― [JIS X 3012 pdf 22] ―――――
18
X 3012 : 1998 (ISO/IEC 13816 : 1997)
定義とする。
例 ((lambda (x y) (+ (* x x) (* y y))) 3 4) ⇒ 25
((lambda (x y &rest z) ) 3 4 5 6) ⇒ (5 6)
((lambda (x y :rest 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-obj* list) →<object> 関数
関数applyは,functionで指定された関数を呼び出す。その引数は,listで指定されたリストの要素をobj*
の後に追加したものとする。functionで指定された関数の返り値が,全体の値となる。
functionが関数でない場合は,エラーが発生する(エラー名domain-error)。各objは,いかなるISLISP
――――― [JIS X 3012 pdf 23] ―――――
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番目の引数 (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 () ) ⇒ f
(f) ⇒ 2.7182818284590451
(defglobal name form) →<symbol> 定義演算子
defglobal形式は,最上位有効範囲の変数名前空間に識別子を定義する。nameの有効範囲は,formの部
――――― [JIS X 3012 pdf 24] ―――――
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 () oday) ⇒ 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) と呼ぶ。
――――― [JIS X 3012 pdf 25] ―――――
次のページ PDF 26
JIS X 3012:1998の引用国際規格 ISO 一覧
- ISO/IEC 13816:1997(IDT)
JIS X 3012:1998の国際規格 ICS 分類一覧
- 35 : 情報技術.事務機械 > 35.060 : 情報技術に使用される言語