ド素人が始めるCommon Lisp 6. EVAL表記

Common Lisp ド素人

"Common Lisp: A Gentle Introduction to Symbolic Computation"を読んで自分の理解をまとめていく。

やっとよく見るコードの形で議論が進んでいくようだ。

Contents

EVAL notaition

今まではブロック図表記で考えてきたがEVALで評価できる書き方で考えていく。文字で書くと何やら難しいことを言っているようだが、要は(+ 1 2)EVAL3と評価されるという話。
自分でコードを書く際はEVALと入力する必要はない、基本的には。

(+ 1 2)     ; => 3

基本的な評価ルールは、

  • 数値、文字列、TNILはそれ自身に評価される。
  • リストは先頭要素を関数として評価し、残りの要素をその関数の引数とする。
  • 引数も評価したうえで関数に渡される。
    例えば(+ (+ 1 2) 4)は引数(+ 1 2)3に評価され、その34が最初の+の引数として渡されるということ。
  • シンボルはシンボルが指している変数の値へと評価される。
  • シンボルやリストを評価せずデータとして扱うためにはquote'(シングルクォート)する。

 いろいろevalしてみる

+, -, *, /

特に悩むところはなし。引数は左側から評価されていく。

(+ 1 2)         ; => 3
(+ 1 2 3 4 5)   ; => 15
(- 1 2)         ; => -1
(- 1 2 3 4 5)   ; => -13
(* 1 2)         ; => 2
(* 1 2 3 4 5)   ; => 120
(/ 1 2)         ; => 1/2
(/ 1 2 3 4 5)   ; => 1/120

 ABS, SQRT

これも特に悩むところはなし。
SQRTは返り値は整数ではなく浮動小数点のようだ。負の値を入れても複素数で返してくる。複素数をプログラム中で使う方法はまた後日考えよう。

(abs 100)       ; => 100
(abs -100)      ; => 100
(sqrt 100)      ; => 10.0
(sqrt -100)     ; => #C(0.0 10.0)

Predicates

例えばnumberp

(numberp 10)    ; => T
(numberp a)     ; => ERROR!
(numberp 'a)    ; => NIL

先に述べたように引数も評価されてから関数に渡される。2行目のようにaをクォートしないと評価しようとしてエラーとなる。(まだシンボルaになにも束縛していないためUNBOUND-VARIABLEとなる。)
ほかのPredicatesも特に悩むところはない。

リストの評価

先に述べたようにリストは基本的には一つ目の要素を関数、残りを引数として評価されてしまう。ただのデータとしてリストを扱うには上でシンボルをクォートしたようにリストもクォートする必要がある。

(a b c d)           ; => ERROR!
'(a b c d)          ; => (A B C D)
('a 'b 'c 'd)       ; => ERROR!
(list 'a 'b 'c 'd)  ; => (A B C D)

1行目はaというfunctionはないというエラーになる。3行目も'aというfunctionはないというエラーになる。自分の環境ではvlimeのREPLで'(a b c d)を上記のようには評価できずエラーとなった。sbclのREPLに打ち込んだ場合は上記通り動いていた。今のところ理由はわからない。
上記を踏まえて(a b c d)から一つ目の要素を取り出す場合は、

(first '(a b c d))  ; => A

のようにクォートする。

まとめ

  • 数値、文字列、TNILはそれ自身に評価される。
  • リストは一つ目の要素を関数、残りを引数として評価される。
  • シンボルは束縛されている値、関数に評価される。
  • 束縛されていないシンボルを評価しようとするとエラー
  • リスト、シンボルを評価せずデータとして渡すためにはクォート'する。

補足

"Common Lisp: A Gentle Introduction to Symbolic Computation"ではシンボルに対して束縛(bounded)という言葉を使うのは正しくないと言っているようだ。。束縛されるのはシンボルが参照している変数(variable)だとということなのだろうか。

コメント

タイトルとURLをコピーしました