gugamilare wrote:If you could post what you are trying to do, we could give you better ideas.
I have been reading Norvig's PAIP, and wanted to write some macros to better integrate pattern matching in to CL. Basically, I started with something based on
http://norvig.com/paip/patmatch.lisp and since then, this is pretty much what I have:
Code: Select all
(defun alist->let-list (alist)
"((foo . bar) (baz . bang)) -> ((foo bar) (baz bang))"
(mapcar #'(lambda (cons-cell)
(list (car cons-cell)
`',(cdr cons-cell)))
alist))
(defmacro let-match ((pattern input) &body body)
(let ((alist (pat-match pattern (eval input))))
`(let ,(alist->let-list alist)
(if (quote ,alist)
(values ,@body t)
(values nil nil)))))
And let-match works at the top level:
Code: Select all
CL-USER> (let-match ((?H . ?T) '(1 2 3 4))
(list ?H ?T))
(1 (2 3 4))
T
However, it fails when I use it inside of a function definition:
Code: Select all
CL-USER> (defun wont-work (lst)
(let-match ((1 2 ?foo) lst)
(list ?foo)))
WONT-WORK
CL-USER> (wont-work '(1 2 5))
Execution of a form compiled with errors.
Form:
(LET-MATCH ((1 2 ?FOO) LST) (LIST ?FOO))
Compile-time error:
(in macroexpansion of (LET-MATCH ((1 2 ?FOO) LST) (LIST ?FOO)))
(hint: For more precise location, try *BREAK-ON-SIGNALS*.)
The variable LST is unbound.
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [ABORT] Return to SLIME's top level.
2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" RUNNING {AFA10A9}>)
When I would expect a return value of (5).
After let-match, I want to next implement cond-match, and finally defun-match.
(Edit: formatting)