CLでSRFI-51 — #:g1

Posted 2012-01-28 20:18:00 GMT

CLでSRFI、今回は、SRFI-51の「Handling rest list」です。
SRFIには、可変/オプショナル/キーワード引数を取り回すための仕組みが幾つがありますが、SRFI-51もその一つです。

動作

CL標準のオプショナル引数の扱いだと順番は左から右ですが、SRFI-51だと指定した関数で判定して適切なものを拾うのでオプションを指定することによって不定にもできます(順番を確定することもできます)
(defun my-read-line (&rest stream-eof)
  (multiple-value-bind (stream eof-value)
                       (rest-values stream-eof
                                    T
                                    (cons *standard-input*
                                          (lambda (s)
                                            (and (streamp s)
                                                 (input-stream-p s))))
                                    (list :eof nil))
    (read-line stream nil eof-value)))

(with-input-from-string (*standard-input* "foo bar baz") (list (my-read-line) (my-read-line))) ;=> ("foo bar baz" :EOF) (with-input-from-string (*standard-input* "foo bar baz") (list (my-read-line) (my-read-line nil))) ;=> ("foo bar baz" NIL) (with-input-from-string (in "foo bar baz") (list (my-read-line in :eof) (my-read-line in :eof))) ;=> ("foo bar baz" :EOF) (with-input-from-string (in "foo bar baz") (list (my-read-line :eof in) (my-read-line :eof in))) ;=> ("foo bar baz" :EOF)

移植について

SRFI-51では、+や、-を動作切り替えに利用していて、Schemeでは、+や、-は関数なので、クォートする必要なく記述できたりして絶妙なのですが、CLでは、それだと、#'-と書かなくてはならないので、:-という風にキーワードにしました。

comments powered by Disqus