SSブログ

S式の不可解さについて [Lisp]

Lisp:S式の理由 [1] というページから。

Lispの括弧は特殊形式か関数適用である、というのが大原則なんですが、 Lispにはそれ以外の意味で括弧が使われる場合があります。letの変数のグループ化や、condの節の区切りですね。 個人的には、このような意味の違うものは別に見えていて欲しいです。 ...

以前にも少し書いたのだけど私の場合むしろ「意味の違うものは別に見えていて欲しい」というのを cond などの特殊形式の存在そのものについても思う。何故同じ形なのに中の要素が展開されるかされないかということに個別の例外がいくつも存在するのだろうか。

例えば Tcl では条件分岐などの制御構文と普通のプロシージャで「引数が展開されるかされないか」という規則に区別はない。

puts [read stdin] とするとまず read stdin が解釈されてその結果を引数として puts が呼び出される。一方で if $flag {read stdin} と書いた場合は read stdin を解釈した結果が if に渡されるのではなく read stdin というコードブロックが if の第2引数となる。

でもこれは if というコマンドの特殊性からくるのではない。もし if $flag [read stdin] と書いていた場合は read stdin が先に解釈されてその結果が if の引数になる。一方でもし puts {read stdin} と書けば read stdin はコマンドとして実行されずに read stdin という文字列が puts の引数になるだろう。つまり展開されるかされないかということは大括弧と中括弧との違いからきていて、意味解釈が違うので違う形式が与えられている。

言い換えると Tcl の if はプリミティブではあるけれど特殊形式ではない。言語にプリミティブなオペレーションが必要であるということは自明だけど、その中のいくつかが特殊形式でなければならないということは自明ではないと思う。解釈方法の異なる表現を同じシンタクスにまとめてオペレータの種類で解釈しわけるという Lisp のデザインは私には相当乱暴に映ってしまう。こんな疑問を持つ人は少ないのだろうか。

[1] http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Lisp%3aS%e5%bc%8f%e3%81%ae%e7%90%86%e7%94%b1


Lisp の special forms [Lisp]

私がずっと Lisp の学習を始めてはわからんといってすぐに辞め、何かに釈然としていなかったこと(のひとつ)は special form だったのだと最近ようやく分かった。
(+ x 3) は x を置き換えるけど (define x 3) は x を置き換えない。
SICP のオンライン版をつらつらと眺めていたら「(define x 3) is not a combination」と書いてあってなんだそんなことかと思った。
多分 Lisp の特徴として喧伝される最小文法ということが先に頭にあるので形は同じでも意味解釈が異なる何通りもの special forms があるというのを頭が受け付けなかったのだ。

そしてもうひとつは先に Tcl を知っていたせいかもしれない。Tcl の構文は本当にひとつしかなくて、その意味解釈も set も if も while も含めて一貫している。Scheme で x にシンボル a が束縛されているときに (define x 3) とやっても a に 3 が結びつくわけではないけど Tcl で x に文字列 a が入っているときに set $x 3 とやれば変数 a に 3 が入る。一方通常の set x 3 なら x に 3 が入る。この置き換えルールは通常のコマンドと同様で set に対しても公平に適用されている。

でも Lisp でも (define 'x 3) が通常の変数定義の方法で (define x 3) が x を置き換える方法だとしてはいけないのだろうか?タイプが面倒。それはあるかもしれない。でもミニマルな文法を志向する考えからはそちらのほうが好ましい気もする。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。