SICP読書女子会 2.3.1 (#25)


せっかく勉強会の度に毎回まとめてるので、
勉強会中のためになった会話とか、
結局わかってない部分とかを追加で書いてみましたヽ(=´▽`=)ﾉ

コードはこちら
[SICP/2.3.1.scm at master · cocodrips/SICP](https://github.com/cocodrips/SICP/blob/master/2.3/2.3.1.scm)


# 2.3.1

```lisp
(print "===2.3記号データ===")
(print "===2.3.1クォート===")

(define a 1)
(define b 2)

(print (list a b))
(print (list 'a 'b))

(newline)

(print "--'(a b c)")
(define quote-list '(a b c))
(print (car quote-list))
(print (cdr quote-list))
;a  

(print "--空リスト")
(print '())

(print "--memq")
(define (memq item x)
    (cond 
        ((null? x) #f)
        ((eq? item (car x)) x)
        (else (memq item (cdr x)))
    ))

(print (memq 'apple '(pear banana prune)))
(print (memq 'apple '(x (apple sauce) y apple pear)))
```

'a の aのことを、symbolって言うらしい

```lisp
gosh> (symbol? 'a)
#t
```


### (おまけ)シンボルについての会話

シンボルの使いみちがわかんなかった私と参加者の会話めも

```txt

しんぼるどんなときに使うんですか？

> 例えばハッシュのキーとか。

ほえー？

> 文字列だと、メモリ列をずずずーっとみて一致調べないとだけど、
  シンボルは内部的には基本ただの整数値になってる

シンボルだとすぐ飛べる？
つまりdefine的な?


> そんなかんじー

'aがなにであるかは
とくに定義はどこにもしないんですよね？
かってに好きな値を割り当ててくれて
かぶらないようになる？

> そう〜
  'a と 'b はかならず別の値になるようにしてくれるし、
  'a と 'a なら、別のモジュールで使ってても同じ値になってくれる
  
  ちなみに Perl は、文字列に対して内部でハッシュ値を計算して持ってたりする。
  ハッシュキーにするときとか。
  
文字列をハッシュキーにするときに
その文字列を一旦ハッシュ化して、どこかにペアをつくっておいて、そのハッシュでアクセスする？

> そうそう。

ほえー！ おもしろい！！
```


めも：
[Gauche ユーザリファレンス: ペアとリスト](http://practical-scheme.net/gauche/man/gauche-refj/peatorisuto.html#pair_30af_30e9_30b9_3068null_30af_30e9_30b9)

## ex 2.53

```lisp

(print "===Ex 2.53===")
(print (list 'a 'b 'c))                     ;(a b c)
(print (list (list 'george)))               ;((george))
(print (cdr '((x1 x2) (y1 y2))))            ;((y1 y2))
(print (cadr '((x1 x2) (y1 y2))))           ;(y1 y2)
(print (pair? (car '(a short list))))       ;#f
(print (memq 'red '((red shoes) (blue socks)))) ;#f
(print (memq 'red '(red shoes blue socks))) ;(red shoes blue socks)
```

## ex 2.54

```lisp
(print "===Ex 2.54===")
; 再帰的なequal?を定義する
(define _equal? equal?)

(print "もとからあるequal?")
(print (equal? '(this is a list) '(this (is a) list)))

(print "自作のequal?")
(define (equal? a b)
    (cond 
        ((and (null? a) (null? b)) #t)
        ((or (null? a) (null? b)) #f)
        ((and (pair? (car a)) (pair? (car b)))
            (if 
                (equal? (car a) (car b))
                (equal? (cdr a) (cdr b))
                #f
            ))
        ((or (pair? (car a)) (pair? (car b))) #f)
        (else 
            (if 
                (eq? (car a) (car b))
                (equal? (cdr a) (cdr b))
                #f
            )
        )
    )
)


(print "hioさんのみて書き直し")
(define (equal? a b)
    (cond 
        ((eq? a b) #t) ; 追加
        ((and (null? a) (null? b)) #t)
        ((or (null? a) (null? b)) #f)
        ((and (pair? (car a)) (pair? (car b)))
            (and (equal? (car a) (car b)) (equal? (cdr a) (cdr b))))
        ;((or (pair? (car a)) (pair? (car b))) #f) <= これはいらない。下のelseで吸収可能
        (else 
            (and (eq? (car a) (car b)) (equal? (cdr a) (cdr b))))
    )
)

(print (equal? '(this is a list) '(this (is a) list)))  ;#f
(print (equal? '(this is a list) '(this is a list)))    ;#t
(print (equal? (list (list 2 3) 'a) (list (list 2 3) 'b))) ;#f
(print (equal? 'a 'a))
```


めも:
pairとpairじゃないものは、勝手にeq?ではじける

```lisp
gosh> (eq? (list 2) 1)
#f
gosh> (eq? (list 1) (list 1))
#f
```

|:--|:--|:---|
|

## ex 2.55

```lisp
(print (car ''abracadabra)) ; quote
; 'a => (quote a)

(print (quote a))                   ;a
(print (quote (quote a)))           ;'a
(print (car (quote (quote a))))     ;quote
```

`'a`の意味は`(quote a)` (脚注より)

### (おまけ)クォートに関する会話めも

クォートとリスト

```txt

'(a b c) っていうのはシンボルなのに
(car (quote (a b c)))だとちゃんとaがとれてpairになってるんですねえ。

> `(a b c)` はシンボルじゃなくてリストかとおもう〜
  (list? (quote (a b c))) は #t
  
ええ
じゃあ'(a b c)は、(list 'a 'b 'c) ???

> そんなかんじとおもう〜
  けど教科書ばさばさよみかえしてみたけれど、詳しいことかいてないっぽい…
  '(a "A" 1 (b "B" 2)) だと シンボル値になるところだけ適用してくれる感じ
```

数字のシンボル？

```txt
> gosh> (+ '1 '2)
  3
  
  何事もなく数字・ｘ・
  
えええええ〜

> 挙動不思議…ッ＞ω＜；
```