Gauche:object-applyの例

Gauche:object-applyの例

object-applyの例

Lispを初めてさわったのは何かの演習のときだったと思いますが、

 リスト(1 2 3 4 5)の先頭を取り出してください。
 > (car (1 2 3 4 5))
 ERROR
 
 こういうときはリストにクォートをつけます。
 > (car '(1 2 3 4 5))
 1
 
 次はx=100,y=200,z=300のとき、リスト(x y z)の先頭を取り出してください。
 > (setq x 100)
 > (setq y 200)
 > (setq z 300)
 > (car '(x y z))
 x
 
 文字が出てきてしまった。クォートがいらないのか?
 > (car (x y z))
 ERROR
 
 やっぱりエラーか~。だめだ... (しばらくして...) もうこの文字xを数値に無理やり変換したらよいのでは?
 > (eval (car '(x y z)))
 100
 
 何とかできた。でもこれで複雑なプログラムを作るのは。。。

という感じで数字になったり、文字になったり、エラーになったりするリストにえらく苦労した記憶があります。

時は流れて、Gaucheではobject-applyを使って任意のオブジェクトを適用可能にできるため、

 > (car (1 2 3 4 5))
 1

ということも、

 > (define x 100)
 > (define y 200)
 > (define z 300)
 > (car (x y z))
 100

ということも、object-applyにメソッドを定義すれば可能になると分かりました。
実装してみたモジュールが以下になります。
https://github.com/Hamayama/noqlist
それで、結論としてはそのページにも書いたように、デバッグが困難になるのでだめそうな感じでした。

ただ、それだったら、変数に思っていない型のデータが入ってもエラーにならなかったりとか、
データのつもりがプログラムと解釈されてもエラーにならなかったりとか、
そういうケースもありえるので、どこまでならエラーにならなくても許されるのかというのは、
人それぞれのような気もします。

なぜLispやSchemeの仕様が広く受け入れられて、皆がそれに従っているのか?
疑問を持つ人はいないのか? いまひとつ釈然としない感じは今もしています。
hamayama(2014/09/09 19:29:12 UTC)

quoteについて

Shiro(2014/09/09 23:58:30 UTC): quoteとは何か、というのは実はLispのアイデンティティの 根幹に関わってくる話で、誰か有名なCLerも quoteがわかったとき始めてLispが何かわかった、みたいなことを言ってたような。 普通の言語として見た場合、リストをquoteするよりも、むしろリストコンストラクタ構文を用意するのが 自然なんですね。例えば {} をリストコンストラクタとすれば、

(define a {1 2 3})  => (1 2 3)

(define b {4 a 5})  => (4 (1 2 3) 5)  ; {}はコンストラクタ呼び出しなので中も評価される

もちろん一歩進めて、リストの表記が(1 2 3)なんだからコンストラクタも()にしたらいいじゃん、 と議論してもいいんですが(例えばHaskellなら表記もコンストラクタも[]ですね)、 そうすると構文に使う()とぶつかってしまいます。

つまり、「他の言語」でリスト表記とリストコンストラクタを同じに出来るのは、 言語の構成要素としての構文、いわゆる「コード部分」がリストじゃないからなんです。

逆に、LispがLispたる所以は、コード部分がリストであること、なんですね。

コードもデータもリストで、ただし住む世界が違う。そして、マクロやevalや言語処理系は、 コードvsデータ、という関係を一段ずらして、普通の「コード」の部分を「データ」に持ってきたり、 「データ」部分を「コード」にしたりする。

コード(program)とデータの関係を例えば⋉と書くと、コードを扱うコード、metaprogramと元の プログラムの間にも同じ関係が成り立ちます。

                   program ⋉ data

    metaprogram ⋉ program

この「同じ関係」が決定的に重要で、これによってプログラムを解釈するプログラムを解釈するプログラム… というふうに上の方向にも、またデータをプログラムとして見たときにそれが解釈するデータをプログラムとして見たときにそれが解釈するデータ… というふうに下の方向にもいくらでも積み重ねてゆけます。

   ... ⋉ a ⋉ b ⋉ c ⋉ d ⋉ ...

こういった無限に続く関係性が、一つの ⋉ という有限な関係で表現できる、というところが Lispの原点であり、quoteはこの関係の左右、異なる世界の住人を一緒の場所に 表記するための決定的な構文なのです。

Shiro(2014/09/14 19:25:52 UTC): (eval (手続き 引数 ...)) だと「(eval 何か)」の部分が依然として 「コード」ですよ。そこをリストで表現する、とやっていったら元の木阿弥じゃないですか? プログラムというのは実行するためにあるのだから、 「書かれていることをコードとして解釈する」という部分は絶対に必要で、そこは譲れない。 でも、その「プログラム」を、別のプログラムが扱う対象の 「データ」として見ることができると、「プログラムを扱うプログラム」が何ら特別なものではなくなる、 という経緯です。

Shiro(2014/09/16 03:09:21 UTC): 元々書かれているものがデータで、実行したいコード部分 だけを特別にマークする、という選択ももちろんあります。代表的なのは文書の中にちょっと 可変部分や実行部分を埋め込みたいというやつで、テンプレートプロセッサとか、 TeXも広い意味でそちらに属するでしょう。どちらの設計が良いかは、 データ部分とコード部分のどちらが多いかに依存するでしょうね。

More ...