CLHS: 22.1.3.5: Printing Lists and Conses

リスト構造を Common Lisp の構造体で作って試している。リスト構造をきれいに表示するのができなくて試行錯誤していたのだが、HyperSpec にちゃんと書いてあった。


最初普通に再帰的にリスト構造を表示しようとしたのだが、ドットが多くなって見辛く、また、既存の処理系とは違っていた。
調べてみたところ、HyperSpec(http://www.lisp.org/HyperSpec/Body/sec_22-1-3-5.html)にちゃんとリストを表示するためのアルゴリズムが書いてあった。おそらく自分が最初に実装したのが dot notation で、下が list notation か?改良リスト表現(http://www.geocities.jp/m_hiroi/xyzzy_lisp/abclisp02.html)というものかも。

(defstruct (cell
	    (:constructor make-cell (car cdr)))
  "cons cell"
  car
  cdr)

(defmethod print-object ((cell cell) stream)
  "print cons cell. see CLHS 22.1.3.5"
  (let ((x cell))
    (princ "(" stream)
    (loop
      (princ (cell-car x) stream)
      (cond
       ((cell-p (cell-cdr x))
	(princ " " stream)
	(setq x (cell-cdr x)))
       (t
	(when (cell-cdr x)
	  (princ " . " stream)
	  (princ (cell-cdr x) stream))
	(return))))
    (princ ")" stream)))

例。

toy(46): (make-cell 1 nil)
(1)
toy(47): (make-cell 1 (make-cell 2 nil))
(1 2)
toy(48): (make-cell 1 (make-cell 2 3))
(1 2 . 3)
toy(49): (make-cell (make-cell 1 (make-cell 2 nil)) (make-cell 2 3))
((1 2) 2 . 3)
toy(50): (make-cell (make-cell 1 (make-cell 2 nil)) (make-cell 3 (make-cell 4 nil)))
((1 2) 3 4)

きれいに出力されて嬉しい。HyperSpec は読み込むべきだなぁ。
TODO; 循環リストへの対応。