COMMON LISP JP > Archives > 2011/02/12

2011/02/12 09:55:13 UTCg000001
#
識者の方に質問なのですが、
#
(let ((alist '((a . 1) (b . 2))))
  (setf (cdr (assoc 'a alist)) 10)
  (setf (cdr (assoc 'b alist)) 20)

  (list (cdr (assoc 'a alist))
        (cdr (assoc 'b alist))))
;=> (1 2)
#
というSBCLの挙動は、定数への代入した結果が〜、ということで説明できるんでしょうか
#
コピーすれば問題はなしですが…
#
(let ((alist (copy-alist '((a . 1) (b . 2)))))
  (setf (cdr (assoc 'a alist)) 10)
  (setf (cdr (assoc 'b alist)) 20)

  (list (cdr (assoc 'a alist))
        (cdr (assoc 'b alist))))
;=> (10 20)
#
ちなみに、cdrを取らない場合は、
#
(let ((alist '((a . 1) (b . 2))))
  (setf (cdr (assoc 'a alist)) 10)
  (setf (cdr (assoc 'b alist)) 20)
  alist)
;=> ((A . 10) (B . 20))
2011/02/12 10:00:18 UTCshiro
#
alistが定数なんで、オプティマイザが (cdr (assoc 'a alist)) も定数になると判断してコンパイル時に計算してしまっているとか?
2011/02/12 10:01:33 UTCg000001
#
なるほど!ちょっと調べてみます
2011/02/12 10:03:10 UTCshiro
#
ちなみにGaucheでもassqを使えばそうなります (結果をコンパイル時に計算)
2011/02/12 10:20:50 UTCg000001
#
ありがとうございます。SBCLでも最適化でこういう結果になってるみたいです。勉強になりました!