Loading [MathJax]/extensions/tex2jax.js

2010年5月1日土曜日

LOL SEGMENT-READER

第3章。リードマクロよりSEGMENT-READER。
これも書くんなら、末尾再帰の方がエエんちゃうの?と思ったケース。

;;; SEGMENT-READER
;; Scheme-style
(defun segment-reader (stream ch n &optional (acc nil))
(labels ((iter (chars curr)
(if (char= ch curr)
(coerce (reverse chars) 'string)
(iter (cons curr chars) (read-char stream)))))
(if (< n 1)
(reverse acc)
(segment-reader stream ch (1- n)
(cons (iter nil (read-char stream)) acc)))))


Doug Hoyte氏は「効率」を考えてdoを使ってんのかな?と思わせておいて、いきなり普通に再帰する、と言うワケの分からん事をする。この人のスタイルは、ぶっちゃけ支離滅裂なんだよな(苦笑)。
例えば、まあ、冗談として聞いて欲しいんですが、マジメに効率考えてdoを使え、ってのなら徹底して次のようにして書く事も可能なんです。

;;; SEGMENT-READER with DO
(defun segment-reader (stream ch n)
(do ((n n (1- n))
(acc nil
(push
(do ((curr (read-char stream)
(read-char stream))
(chars nil (push curr chars)))
((char= ch curr) (coerce (nreverse chars) 'string)))
acc)))
((< n 1) (nreverse acc))))


冗談ですけどね(笑)。こんなコード読むの大変ですし。書くのも大変。ただ、分かって欲しいのは、そもそもdoの性質からしてletが要らないだろって事です。letが要らなければ本体部も要らない、っつー事です。

CL-USER> (segment-reader t #\/ 3)
あいう/えおか/きくけ/
("あいう" "えおか" "きくけ")
CL-USER>

0 件のコメント:

コメントを投稿