SICP 2.3 Symbolic Data
『シンボル』
All the compound data objects we have used so far were constructed ultimately from numbers.
これまで数しか扱って来なかった、と書いてあるが実は数と手続きを扱った気が。
C言語から入った人にとってシンボルはちょっと分かりにくい。変数や関数の名前がそれとも言えるけど完全にデータとして扱える訳ではないので。C言語でシンボルの配列は作れないし(型が邪魔しているか?)、仮に出来たとしてサーチとか無理。#defineで定義した名前もコンパイルしてしまえば消えてしまいデータとしては扱えない。enumで作った名前も結局の所、整数に変換されてしまうし。シンボルは文字列リテラルとも異なる。C言語ではコンパイルした出力にシンボルテーブルが出来てリンクの際に使用されるのが少し似ているかも知れないが、任意に付けられる名前ではないし結局それに相当するものは存在しないか。。。
ノート
2.3.1 Quotation
『引用』ではなくてリストのリテラルを作る事。プログラムの中に出て来るリストは評価されてしまうが(先頭の要素は関数として、残りは引数として)、データとしてのリストを表現する手段。
DrRacketでR5RSモードで実行してみる。
> (define a 1) > (define b 2) > (list a b) (1 2) > (list 'a 'b) (a b) > (list 'a b) (a 2) >
ちなみにracketモードだと出力が少し変わる。
> (define a 1) > (define b 2) > (list a b) '(1 2) > (list 'a 'b) '(a b) > (list 'a b) '(a 2) >
プログラムを出力してそれをまた解釈させるにはこの方が便利なのか?
続き
> (car '(a b c)) a > (cdr '(a b c)) (b c) >
memqはR5RSに定義されたライブラリ関数。
> (memq 'apple '(pear banana prune)) #f > (memq 'apple '(x (apple sauce) y apple pear)) (apple pear) >
最初の(apple sauce)には引っ掛からない。
Exercise 2.53
> (list 'a 'b 'c) (a b c) > (list (list 'george)) ((george)) > (cdr '((x1 x2) (y1 y2))) ((y1 y2)) > (cadr '((x1 x2) (y1 y2))) (y1 y2) > (pair? (car '(a short list))) #f > (memq 'red '((red shoes) (blue socks))) #f > (memq 'red '(red shoes blue socks)) (red shoes blue socks) >
Exercise 2.54
> (eq? null null) #t > (eq? '() '()) #t >
空のリストはそのままeq?でチェック出来るので、二つのリストの先頭が両方ともペアであればcarとcdrをそれそれequal?でチェックして両方trueであればtrue、ペアでない場合はeq?でチェックで行けそう。片方がペアでない時点でfalseは確定するがそれはeq?でチェックしても結果は同じ。
(define (equal? a b) (if (and (pair? a) (pair? b)) (and (equal? (car a) (car b)) (equal? (cdr a) (cdr b))) (eq? a b)))
実行結果
> (equal? '(this is a list) '(this is a list)) #t > (equal? '(this is a list) '(this (is a) list)) #f > (equal? '(this (is a) list) '(this (is a) list)) #t > (equal? null null) #t > (equal? '() '()) #t >
Exercise 2.55
DrRacketのR5RSモードで実行。
> (car ''abracadabra) quote >
脚注34に書いてある通り
(car ''abracadabra)
は
(car (quote (quote abracadabra)))
と等価。従って最初のquoteがcarの結果として返される。