さかもとのブログ

つらつらと

OnLisp第11章do-tuples/c

clispの組み込みのwith-gensymsを使って,do-tuples/cを定義する場合,OnLispに載っているままではエラーになってしまう.

[195]> (load "***.lsp")
;; Loading file ***.lsp ...

*** - CONCATENATE: SRC is not a SEQUENCE
The following restarts are available:
SKIP           :R1      skip (DEFMACRO DO-TUPLES/C # ...)
STOP           :R2      stop loading file /home/hoge/foo/bar/***.lsp
ABORT          :R3      Abort main loop

このエラーがわからなかったのだけど,clispのサイトを見ると,OnLispのwith-gensymsと微妙に違っていて,gensymの対象となるシンボルの前に文字列を入れなければいけないみたい.

なので,clispの組み込みのwith-gensymsを使う場合は,

(defmacro do-tuples/c (parms source &body body)
  (if parms
      (with-gensyms ("do-tulepls/c-" src rest bodfn)
        (let ((len (length parms)))
          `(let ((,src ,source))
             (when (nthcdr ,(1- len) ,src)
               (labels ((,bodfn ,parms ,@body))
                 (do ((,rest ,src (cdr ,rest)))
                     ((not (nthcdr ,(1- len) ,rest))
                      ,@(mapcar #'(lambda (args)
                                    `(,bodfn ,@args))
                                (dt-args len rest src))
                                nil)
                   (,bodfn ,@(map1-n #'(lambda (n)
                                         `(nth ,(1- n)
                                               ,rest))
                                     len))))))))))

としなければ,いけない.文字列をつけないといけないから,CONCATENATEのエラーがでていた.
文字列を付けたくない場合は,OnLispで定義されているwith-gensymsマクロをwith-our-gensymsとでもして,それを使えばエラーはでない.