Gauche > Archives > 2020/11/13

2020/11/13 16:45:59 UTCtioner
#
(apply + '(1 2)) で 3 が返ってくるのに
(apply (car '(+)) '(1 2)) はエラーが返ってくるのは何故でしょうか。
2020/11/13 16:52:59 UTCshiro
#
(car '(+)) は単なる + というシンボル、(apply + '(1 2)) の + ha
#
(apply + '(1 2))の+はプログラム中に現れる変数で、デフォルトでは「足し算をする」という関数に束縛されている、からです。
#
"Land of Lisp" では「プログラムモード」と
#
「データモード」という説明をしていたんですが、Lisp/Schemeでは「地のプログラム」と「そのプログラムが扱うデータ」がほとんど同じ形で記されます。後者がプログラムに埋め込まれる時は、それがデータだよ、という記号としてクオートされます。
#
(「地のプログラム」というのは「地の文」と同じ意味です。「『もう帰って来い』と父が言った」という文で、「と父が言った」の部分が「地の文」です。『もう帰って来い』がクオートされたデータです)
2020/11/13 17:02:18 UTCtioner
#
(+ 1 2) は 3
#
ですが
((car '(+) 1 2)
は
(+ 1 2)
を評価している(そしてエラーが返る)のと同じこと、と言う理解で合っていますでしょうか。
#
いや、
(+ 1 2) は 3 が返ってきますので……
2020/11/13 17:07:13 UTCshiro
#
(+ 1 2) は 「+という変数を評価すると「引数の和を返す」という関数が得られる。1、2はそれぞれ評価すると1、2そのもの。1、2を引数として「引数の和を返す」という関数を呼び出す」という式になります。
2020/11/13 17:07:42 UTCtioner
#
('+ 1 2)
を評価しているのと同じ、で合っていますでしょうか。
2020/11/13 17:08:46 UTCshiro
#
((car '(+)) 1 2) では、 (car '(+)) は「+という記号(シンボル)」を返します。つまり ('+ 1 2) と同じことです。これは「+という記号を関数として、1、2という引数を伴って呼び出す」という式になります。でも記号は関数ではないのでエラーになります。
#
gosh$ +
#<subr (+ :rest args)>
gosh$ '+
+
2020/11/13 17:11:37 UTCtioner
#
日本語で言うと「1と2を足せ、そして返せ」と「1と2を『足せ』を返せ」の違い、と言うか……
2020/11/13 17:13:03 UTCshiro
#
そうそう、そんな感じです。
2020/11/13 17:13:54 UTCtioner
#
ありがとうございます。たぶん分かりました。
おそらくマクロを使わなくてはいけないと思います。
2020/11/13 17:33:25 UTCkaki
#
ところで、手続きのリストを作りたいなら (list +) や `(,+) 等できます。もしかしてやりたいことはこれなのではと思っただけなので、違ったら流してください。つい最近身の回りで、手続きのリストを作ろうとして '(+) って書いた人が居たもので。