SICP 問題 2.53(クオートの動作確認)

問題

次の各式を評価した結果、解釈系は何を印字するか。


(list 'a 'b 'c)

(list (list 'george))

(cdr '((x1 x2) (y1 y2)))

(cadr '((x1 x2) (y1 y2)))

(pair? (car '(a short list)))

(memq 'red '((red shoes) (blue socks)))

(memq 'red '(red shoes blue socks))


解答

そのままgaucheに食わせるぜ。


gosh> (list 'a 'b 'c)
(a b c)
gosh> (list (list 'george))
( (george))
gosh> (cdr '((x1 x2) (y1 y2)))
( (y1 y2))
gosh> (cadr '((x1 x2) (y1 y2)))
(y1 y2)
gosh> (pair? (car '(a short list)))
#f
gosh> (memq 'red '((red shoes) (blue socks)))
#f
gosh> (memq 'red '(red shoes blue socks))
(red shoes blue socks)
gosh>

memqが何してるのかわからん。。
helpみたいなドキュメントが見れないかな〜と思っていじってみた。


gosh> memq
#
サブルーチンだよと言われる。うん、そりゃそうだろうな。
次に確か discribe とかいう手続きがあったように思ったので、試してみる。省略形は確か d だけ。

gosh> (d memq)
# is an instance of class
slots:
required : 2
optional : #f
locked : #f
info : "memq"
setter : #f
gosh>
おお〜、いろいろ情報が出てきた。でもこれだけじゃあ memq が何をする手続きなのかは分からん。
info ってのが怪しい。

gosh> (info memq)

ERROR: no info document for #

Stack Trace:
_______________________________________
0 (errorf "no info document for ~a" fn)
At line 100 of "/usr/share/gauche/0.8.13/lib/gauche/interactive/info.scm"
gosh>

#のドキュメントなんざねぇよと怒られた。
あ、ひょっとして info の第2引数を "memq" って文字列にしないとダメ?info に処理される前に、memq が評価されちゃって、info に渡るのが # になってるってことかしらん。


gosh> (info "memq")
6.4.5 Other list procedures

                                                    • -

-- Function: append list ...
[R5RS] Returns a list consisting of the elements of the first LIST
followed by the elements of the other lists. The resulting list
is always newly allocated, except that it shares structure with
the last list argument. The last argument may actually be any
object; an improper list results if the last argument is not a
proper list.

-- Function: append! list ...
[SRFI-1] Returns a list consisting of the elements of the first
LIST followed by the elements of the other lists. The cells in
the lists except the last one may be reused to construct the
result. The last argument may be any object.

-- Function: reverse list
[R5RS] Returns a newly allocated list consisting of the elements
of LIST in reverse order.

-- Function: reverse! list
[SRFI-1] Returns a list consisting of the elements of LIST in
reverse order. The cells of LIST may be reused to construct the
returned list.

-- Function: memq obj list
-- Function: memv obj list
-- Function: member obj list
[R5RS] Searches OBJ in the LIST. If `n'-th element of LIST equals
to OBJ (in the sense of `eq?' for `memq', `eqv?' for `memv', and
`equal?' for `member'), `(list-tail LIST N)' is returned.
Otherwise, `#f' is returned.

If you use SRFI-1 (*Note List library::), `member' is extended to
take optional argument for a equality procedure.
(memq 'a '(a b c)) => (a b c)
(memq 'b '(a b c)) => (b c)
(memq 'a '(b c d)) => #f
(memq (list 'a) '(b (a) c)) => #f
(memv 101 '(100 101 102)) => (101 102)

-- Function: assq obj list
-- Function: assv obj list
-- Function: assoc obj list
[R5RS] Each element in LIST must be a pair. These procedures
search a pair whose car matches OBJ (in the sense of `eq?' for
`assq', `eqv?' for `assv', and `equal?' for `assoc') from left to
right, and return the leftmost matched pair if any. If no pair
matches, these return `#f'.

If you use SRFI-1 (*Note List library::), `assoc' is extended to
take optional argument for a equality procedure.

gosh>

おおおおお!!超詳しそうなドキュメントが表示された!!英語だけど。
ざっと読んでみると、memq だけのドキュメントではない感じ。
表示されたドキュメントの途中に、memq, memv, member 手続きの記述があった。

3種で少し挙動が違うようだが、大まかに言うと、第1引数に指定した OBJ が、第2引数に指定した LIST に存在するかしないかを評価するっぽい。
存在した場合は出現した要素以降の全てをリストとして返し、存在しない場合は #f が返る。

ちなみに3種の手続きの挙動の違いは、等しいか等しくないかの判別をそれぞれ次のようにしているとのこと。

memqeq?
memveqv?
memberequal?
なるほどねぇ。