SICPを読む(68) 問題 2.53 - 2.55 記号データ

2.3に入ります。記号データってのは、シンボルのこと?

問題 2.53

シンボルとmemqの問題。

(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)

先に回答を書いてからチェックした。こういう時にalign.vimが役に立つ。

eq?について。

実験。

(define a '(a b c))
(define b a)
(eq? a b)           ; #t
(set-car! b 'b)
(eq? a b)           ; #t
a                   ; (b b c)

(define a 1)
(define b a)
(eq? a b)           ; #t
(set! b 2)
(eq? a b)           ; #f
a                   ; 1
わかったこと
  • 数値の場合、(eq? a b)を比較してる訳じゃなくて、(eq? 1 2)というように、作用後の値を見てることになる。
  • リストの場合は、aを作用させたときに返ってくるのは、リストの先頭アドレスになる。だから、リストの値を無理矢理変更しても、アドレスは同じ所を指してるので、#t
  • リスト同士比較すると、アドレスが違うので、#f。文字列もいっしょ。
  • シンボルの比較は#t。

eq?は値を見る。

僕のSchemeの実装だとシンボルは単なる文字列なので、#fになるはず。しまった何かが違う。

問題 2.54

ムズすぎ。

findライクにやってしまったのが失敗の原因。リストなら比較出来たけど、ツリーと、(equal? 1 2)に対応出来ず(汗

回答を見て写経した。

(define (equal? a b)
  (cond ((and (pair? a) (pair? b))
         (and (equal? (car a) (car b))
              (equal? (cdr a) (cdr b))))
        ((and (not (pair? a)) (not (pair? b)))
         (eq? a b))
        (else #f)))

(and (equal? ...) (equal? ...))か・・・。そして、not pairを見る。

最初に(equal? 1 2)を作るべきだった。

問題 2.55

quoteの連鎖になってる。

(car (quote (quote abc)))

確認問題。

'''abc
; 秘密

へぇぇ。