next up previous contents index
: 関数呼び出しのための関数 : 制御構造 : 制御構造   目次   索引

定数と変数

nil 【変数】

nilの値は空リスト ()である.
t 【変数】

tの値は #tである.

(quote 《データ》) 【特殊フォーム】

《データ》 を評価せずにそのまま返す.

(quote《データ》)

'《データ》

と入力してもよい. 例えば,

'(a . b)

(quote (a . b))

と入力するのと同じことである.

例:

(quote (1 2 3)) $\Rightarrow$ (1 2 3)
'(1 2 3) $\Rightarrow$ (1 2 3)
'a $\Rightarrow$ a
''(a b c) $\Rightarrow$ '(a b c)

(quasiquote 《データ》) 【特殊フォーム】

《データ》 中に unquote または unquote-splicing を第$1$要素とするリストがなければ, quoteと同様に 《データ》 を評価せずにそのまま返す. unquoteを第$1$要素とするリストがあれば, その第$2$要素を評価した値をその位置に埋める. また, unquote-splicingを第$1$要素とするリストがあれば, その第$2$要素を評価した値をリストとみなし,その各要素をその位置に埋める.

(quasiquote《データ》)
(unquote《データ》)
(unquote-splicing《データ》)

をそれぞれ

`《データ》
,《データ》
,@《データ》

と入力してもよい.

例:


(let ((name 'a)) `(list ,name ',name))  

$\Rightarrow$ (list a 'a)
`#(1 ,(+ 1 1) ,@(cdr '(2 3 4)) 5)
$\Rightarrow$ #(1 2 3 4 5)
`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
$\Rightarrow$(a `(b ,(+ 1 2) ,(foo 4 d) e) f)

(lambda (《λリスト》)《本体》) 【特殊フォーム】

関数閉包と呼ばれる関数データを生成して返す. 《λリスト》 が関数の仮引数を与え, 《本体》 が関数本体である. この関数閉包が呼び出されると,関数閉包が生成された時点の変数環境に, 各仮引数を局所変数として加え,その変数環境のもとに 《本体》 を 実行する. 《本体》 は define式とフォームからなるリストであり, 各フォームを順に評価してゆき,最後のフォームの値を関数の値として返す. もし 《本体》 にフォームが1つもなければ ()を値として返す.

例:
((lambda ())) $\Rightarrow$ ()
((lambda () (cons 1 2))) $\Rightarrow$ (1 . 2)

《λリスト》 は次のいずれかの形である.

《変数》$\cdots$《変数》
《変数》$\cdots$《変数》.《変数》

前者の場合, lambda式の定義する関数は,与えられた《変数》と同じ個数の 引数を受け取る.後者の場合は,少なくとも`` .''以前の《変数》と 同じ個数の引数を受け取り,残りの引数は1本のリストとなって最後の《変数》 にバインドされる. また後者の場合,ドットの前に 《変数》 がなくてもよい. そのようなラムダ・リストを持つ lambda式は,

(lambda《変数》《本体》)

という形をしている.

例:

((lambda (x y) (list x y)) 1 2) $\Rightarrow$ (1 2)

((lambda (x y . z) (list x y z)) 1 2)
$\Rightarrow$ (1 2 ())
((lambda (x y . z) (list x y z)) 1 2 3)
$\Rightarrow$ (1 2 (3))
((lambda (x y . z) (list x y z)) 1 2 3 4)
$\Rightarrow$ (1 2 (3 4))

((lambda x x)) $\Rightarrow$ ()
((lambda x x) 1) $\Rightarrow$ (1)
((lambda x x) 1 2) $\Rightarrow$ (1 2)

> (define square (lambda (x) (* x x)))
square
> (square 3)
9

(call-with-current-continuation 〈関数〉) 【関数】

(call/cc 〈関数〉) 【関数】

現在の「継続」を引数として$1$引数の 〈関数〉 を呼び出す. 呼び出された関数の返す値がこの式の返す値となる. 継続とは$1$引数の関数であり,ここで得られた継続を関数として呼び出すと, この式に続く部分の実行が再開される. その際,継続に与えられた引数がこの式の返す値となる.

例:

> (define x 0)     

x
> (define c #f)
c
> (list (set! x (+ x 1))
(call/cc
(lambda (cont)
(set! c cont)
(set! x (+ x 1))))
(set! x (+ x 1)))
(1 2 3)
> x
3
> c
#<function>
> (c 100)
(1 100 4)
> x
4
> c
#<function>
> (c 200)
(1 200 5)
> x
5
> c
#<function>

(call-with-indefinite-one-time-continuation 〈関数〉) 【関数】

(call/ioc 〈関数〉) 【関数】

現在のindefinite one-time continuation (IOC)を引数として$1$引数の 〈関数〉 を呼び出す. 呼び出された関数の返す値がこの式の返す値となる. IOCとは 〈関数〉 の実行が終了していなければ, いつどこからでも1回だけ呼び出すことができる継続である. ここで得られたIOCを関数として呼び出すと, この式に続く部分の実行が再開される. その際,IOCに与えられた引数がこの式の返す値となる.

(let/cc 《変数》《本体》) 【マクロ】

これは


(call/cc (lambda (《変数》)《本体》))

と等価である.

(set! 《変数》《式》) 【特殊フォーム】

《式》 を評価してその値を 《変数》 に代入する. TUTSchemeでは,評価した 《式》 の値を返す.

例:
> (define x 0)
x
> x
0
> (set! x 1)
1
> x
1

(setf 《場所》《式》) 【マクロ】

《式》 を評価してその値を 《場所》 に代入する. 《場所》 としては以下のものが許される.

例:
> (define x '(foo bar baz))
x
> x
(foo bar baz)
> (setf (cadr x) 'aho)
(aho baz)
> x
(foo aho baz)

(defsetf 《記号》《関数名》) 【マクロ】

(defsetf 《記号》(《λリスト》) (《変数》) 《本体》) 【マクロ】

《記号》 で始まるリストが``場所''として使えることを宣言し, setf式の展開形を定義する. defsetf式は上のように2つの形があり,はじめの
(defsetf 《記号》 《関数名》)
で定義すれば, setf
(setf (《記号》 《式$_1$$\cdots$《式$_n$》) 《式》)
(《関数名》 《式$_1$$\cdots$《式$_n$》 《式》)
と展開される.もう一方の
(defsetf 《記号》 (《λリスト》) (《変数》) 《本体》)
で定義すれば, setf
(setf (《記号》 《式$_1$$\cdots$《式$_n$》) 《式》)

((lambda (《λリスト》)   

(let ((《変数》 《式》)) 《本体》))
《式$_1$$\cdots$《式$_n$》)
の値となるフォームに展開される.

例:

> (defsetf getprop (sym prop) (x) `(putprop ,sym ,prop ,x))
getprop
> (setf (getprop 'elephant 'favorite-movie) 'dumbo)
dumbo
> (getprop 'elephant 'favorite-movie)
dumbo

(bound? 〈記号〉) 【関数】

〈記号〉を印字名とする大域変数が値を持っていれば #tを返す. 持っていなければ #fを返す.

next up previous contents index
: 関数呼び出しのための関数 : 制御構造 : 制御構造   目次   索引
Tsuneyasu KOMIYA 平成14年2月22日