common lisp で OCaml 風の書き方をしたい。
common lisp初心者なのですが、誰か教えていただけないでしょうか。
CLISPで、Ocamlのように再帰関数を同一の関数名でラップしたい場合、どのようにするべきでしょうか。 たとえば、以下のreverseのような例です。
let rec reverse xs ys =
match xs with
| [] -> ys
| x::xs -> reverse xs (x::ys);;
let reverse xs = reverse xs [];;
この問題を解決しようと思い、自分でマクロを書いてみました。
(defconstant else t)
(defmacro defun* (sym bindings &body body)
(let ((temp (gensym))
(rest (gensym)))
`(setf (symbol-function ',sym)
(function
(lambda ,bindings
(let ((,temp (symbol-function ',sym)))
(flet ((,sym (&rest ,rest)
(apply ,temp ,rest)))
,@body)))))))
(defun my-reverse (xs ys)
(cond ((null xs) ys)
(else
(my-reverse (cdr xs) (cons (car xs) ys)))))
(defun* my-reverse (xs)
(my-reverse xs (list)))
しかし、これをSBCLで評価しようとするとエラーが出てしまいます。
* (my-reverse '(1 2 3))
debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR:
invalid number of arguments: 2
解決策を教えていただけませんでしょうか。