星田さんの記事に対するコメント。
今回は小粒ネタ。
ここ、(set~ のところと `(you~ のところって複文ってことにならないのかな?Beginいらんのかい?というのが気になって・・。
うん。要らんです(笑)。
ええと、全くその通りでそこは「複文」です。
で。
Lispのcondと言うのには「暗黙のprogn」(Scheme/Racketでは「暗黙のbegin」)と言うのが含まれます・・・・・・。
実はLispの原作者、マッカーシー博士は「設計を失敗した」とか言ってたみたいですが(笑)。
つまり、ifにはそんなモノはなくって、ifなら
(define (pickup object)
(if (memv object (objects-at *location* *objects* *object-locations*))
(begin (set! *object-locations* (cons `(,object body) *object-locations*))
`(you are now carrying the ,object))
`(you cannot get that.)))
と書かなきゃなんないトコをcondだと
(define (pickup object)
(cond ((memv object (objects-at *location* *objects* *object-locations*))
(set! *object-locations* (cons `(,object body) *object-locations*))
`(you are now carrying the ,object))
(else `(you cannot get that.))))
と書くことだけで済む、と。
(define (cond-test arg)
(cond ((eq? arg 'Japanese)
'hoge
'fuga
'piyo)
(else
'foo
'bar
'baz)))
> (cond-test 'Japanese)
'piyo
> (cond-test 'English)
'baz
>
condは上の実行例を見れば分かりますが、各節はまるでbegin(ANSI Common Lispではprogn)を含んでるように、複文を逐次実行して、返り値は複文の「最後の式の返り値」になります。
そういう風に設計してる、ってのがifとの大きな違いです。
だから、この実行部分に複文を含むケースで、かつ分岐が二つしかない場合、ifを使うかcondを使うか、ってのはbegin(ないしはprogn)を書きたいか書きたくないか、と言う個人の好みになります。
なお、case構文も「暗黙のprogn」ないしは「暗黙のbegin」を含んでますね。
従って、Lispの条件分岐は、
- if -> 暗黙のprogn/beginを含まないもっとも単純な条件分岐
- それ以外 -> 暗黙のprogn/beginを含む
と言った設計になってます。
「GPS」ってコレ、概念的なプログラムの構造を説明するための仮想的なコードですよね?
いや、一応ホンマモンの「プログラム」です。
1957年に作られた、っつーんで、パソコンが無い時代、つまり今で言うスパコン、メインフレーム、ミニコンとかそのテの「巨大なコンピュータ」で動くソフトウェアで、総初期の「人工知能研究」の研究成果ですね。