★このブログ来週一週間お休みします★
Emacs Lispで遊ぼうの連載。
最初に、Emacs Lisp、Emacs Lispと連呼するのは面倒なので、今後はElispと呼ぶ。
読みかけていた「初めての人のためのLISP」は挫折した。
Emacs Lispで遊ぼうの連載。
最初に、Emacs Lisp、Emacs Lispと連呼するのは面倒なので、今後はElispと呼ぶ。
読みかけていた「初めての人のためのLISP」は挫折した。
第7講で「今は使われていないprog」という構文が「もしあったら」という前提で延々プログラム例が出てくるのには少々びっくり。
脳内で実行しなければならないのである。
結構大変だ。
この本を褒めている人は、よく考えたら「他の本でLISPを極めている人が、楽しみのために読み返しているケースが多いのではないか。
ぼくも他の本で勉強したら、またこの本を再読することを期して、とりあえず本書は自宅のスミソニアン博物館に貯蔵しておくことにする。
しかし、ちょこちょこ警句が書いてあって、示唆に富む本ではあると思った。
次に「Scheme手習い(The Little Schemer)」を読み始めた。
本書は、以前読んで感銘を受けた山本和彦さんの「リスト遊び」の「あとがき」で、本書を読んだ後に読むべき本として挙げていた。
さっそく読んでみようと思ったのだが、問題が一つあって、プラットフォームがSchemeなのだ。
ぼくの勉強したいのはElispである。
しかし、ここは両方勉強し、移植してみて、どういう齟齬が起きるか、発見するのも一方だと思った。
SchemeとElispの違いが分かって、いいのではないか。
The Little Elisperだ!
たとえば
ところが、Gaucheでatom?を使ってみると、使えないのである。
前途遼遠である。
'()のcarを取ることは出来ない、と書いている。
しかしElispでは
アトムの場合は、ドットリストを返す。
これは、訳注にも「実際には出来る」的なことが書いている。
その後に、本文に「Consの掟」というものが書いているが、ということで、実際には例外がある。
Elispではnil、Gaucheでは#fを返す。
また、アトムとリストを比較できないと書いているが、実際には、出来る。
まったく同じリストを比較すると真を返す。
違うリストを比較すると偽を返す。
リストとアトムを比較すると偽を返す。
まとめると:
「Scheme手習い」には使えると書いているが、実際には定義しなければならない:
・atom?(「はじめに」に書いている)
「Scheme手習い」にはできないと書いているが、実際には出来る(脚注に、実際には出来ると書いている):
・第2引数にアトムを取るcons関数=>ドットリストを返す
・アトムを引数に取るnull?関数=>偽(Elisp、Clispではnil、Schemeでは#f)を返す
・アトムとリストを引数に取るeq?関数=>偽を返す
SchemeとElispの仕様の違いによって、Schemeでは出来ないが、Elisp/Clispでは出来る:
・nilのcar
・nilのcdr
=>両方ともSchemeではエラー、Elisp/Clispではnil
という注意点がある。
★
このブログの下書きを書いているのはずいぶん前であって、「Scheme手習い」はだいぶ読み進んでいる。
この本は面白い!
ゲーミフィケイションにあふれた、実用的な脳トレのようなものである。
この本のすばらしさを今後おいおい紹介していく。
やさしい本なので、万人におすすめである。
脳内で実行しなければならないのである。
結構大変だ。
この本を褒めている人は、よく考えたら「他の本でLISPを極めている人が、楽しみのために読み返しているケースが多いのではないか。
ぼくも他の本で勉強したら、またこの本を再読することを期して、とりあえず本書は自宅のスミソニアン博物館に貯蔵しておくことにする。
しかし、ちょこちょこ警句が書いてあって、示唆に富む本ではあると思った。
次に「Scheme手習い(The Little Schemer)」を読み始めた。
本書は、以前読んで感銘を受けた山本和彦さんの「リスト遊び」の「あとがき」で、本書を読んだ後に読むべき本として挙げていた。
さっそく読んでみようと思ったのだが、問題が一つあって、プラットフォームがSchemeなのだ。
ぼくの勉強したいのはElispである。
しかし、ここは両方勉強し、移植してみて、どういう齟齬が起きるか、発見するのも一方だと思った。
SchemeとElispの違いが分かって、いいのではないか。
The Little Elisperだ!
たとえば
ELISP> (atom 'atom)である。Elisp(およびCommon Lisp)はこれでいいのだが、Schemeの場合はatom?という関数を使えと書いている。
t
ところが、Gaucheでatom?を使ってみると、使えないのである。
gosh> (atom? 'atom)これは実は「はじめに」に書いていることであって、このように定義する。
*** ERROR: unbound variable: atom?
Stack Trace:
_______________________________________
gosh> (define atom?実行してみる。
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
atom?
gosh> (atom? 'atom)出来たー。
#t
前途遼遠である。
'()のcarを取ることは出来ない、と書いている。
しかしElispでは
ELISP> (car '())となる。Clispでも
nil
[1]> (car nil)となる。しかしGaucheでは、果たして
NIL
gosh> (car '())となった。
*** ERROR: pair required, but got ()
Stack Trace:
_______________________________________
(Scheme手習いより)
Carの掟
関数carは空でないリストに対してのみ定義される。
(初めての人のためのLispより)また、
ワシは少なくともnilのcarがnilになるのはどうも好かん。
~
実際のプログラムを書くとき、nilのcdrがnilになってくれたほうが、プログラムがちょっと短くなってうれしいときもあるが、nilのcarを取るという行為はそもそもプログラムの論理の誤りであることが圧倒的に多いからじゃ。
Cdrの掟と書いている。実際Schemeでは
関数cdrは空でないリストについてのみ定義される。
空でないリストのcdrは常に別のリストとなる。
gosh> (cdr '())とある。ところがElispでは、nilのcdrも取れて、nilになる。
*** ERROR: pair required, but got ()
Stack Trace:
_______________________________________
ELISP> (cdr '())さて、「Scheme見習い」にはcons関数の第2引数はリストでなければならないとあるが、実際にはアトムでも良い。
nil
アトムの場合は、ドットリストを返す。
ELISP> (cons 'love 'peace)
(love . peace)
gosh> (cons '((a b c)) 'b)
(((a b c)) . b)
これは、訳注にも「実際には出来る」的なことが書いている。
その後に、本文に「Consの掟」というものが書いているが、ということで、実際には例外がある。
Consの掟また、アトムのnullを取ることは出来ないと書いているが、実際には取ることが出来る。
関数consは2つの引数を取る。
consの第2引数はリストでなければならない。
結果はリストとなる。
=>実際には第2引数はアトムであっても良い。結果はドットリストとなる。
Elispではnil、Gaucheでは#fを返す。
ELISP> (null 'spaghetti)
nil
gosh> (null? 'spaghetti)ということで
#f
Nullの掟これも脚注に書いている。
関数null?はリストに対してのみ定義される。
=>実際にはアトムに対して掛けることも出来る。この場合nilや#fを返す。
また、アトムとリストを比較できないと書いているが、実際には、出来る。
まったく同じリストを比較すると真を返す。
違うリストを比較すると偽を返す。
リストとアトムを比較すると偽を返す。
ELISP> (eq '() '(strawberry))
nil
gosh> (eq? '() '(strawberry))
#f
ELISP> (eq (cdr '(soured milk)) 'milk)
nil
gosh> (eq? (cdr '(soured milk)) 'milk)
#f
ELISP>(eq '(love kiss) '(love kiss))
nil
ELISP> (setq lovekiss '(love kiss))
(love kiss)
ELISP> (eq lovekiss lovekiss)
t
gosh> (define lovekiss '(love kiss))ということで
lovekiss
gosh> (eq? lovekiss lovekiss)
#t
Eq?の掟これも脚注にも書いてある。
関数eq?は2つの引数を取る。
どちらも数でないアトムでなければならない。
=>実際はリストも比較できる。
まとめると:
「Scheme手習い」には使えると書いているが、実際には定義しなければならない:
・atom?(「はじめに」に書いている)
「Scheme手習い」にはできないと書いているが、実際には出来る(脚注に、実際には出来ると書いている):
・第2引数にアトムを取るcons関数=>ドットリストを返す
・アトムを引数に取るnull?関数=>偽(Elisp、Clispではnil、Schemeでは#f)を返す
・アトムとリストを引数に取るeq?関数=>偽を返す
SchemeとElispの仕様の違いによって、Schemeでは出来ないが、Elisp/Clispでは出来る:
・nilのcar
・nilのcdr
=>両方ともSchemeではエラー、Elisp/Clispではnil
という注意点がある。
★
このブログの下書きを書いているのはずいぶん前であって、「Scheme手習い」はだいぶ読み進んでいる。
この本は面白い!
ゲーミフィケイションにあふれた、実用的な脳トレのようなものである。
この本のすばらしさを今後おいおい紹介していく。
やさしい本なので、万人におすすめである。