Re: defmacro
- From: Pascal Bourguignon <pjb@xxxxxxxxxxxxxxxxx>
- Date: Mon, 22 May 2006 19:29:23 +0200
"Kim Russell" <kimrru@xxxxxxxxx> writes:
Hi,
I'm writing a defmacro which expands to a do loop and calls an
iterator. I think I have most of it done but the do syntax is kind of
confusing.
Any help would be appreciated. I apologize if it's not the best syntax.
(defmacro doloop (vars &body body)
(let ((arg (gensym))
(itr (gensym)))
`(let ((,arg ',(car vars))
(,itr ',(cadr vars)))
(do ((,arg() (funcall (iter-n ,itr)))
((,v ,arg) ((null (funcall (iter-has-n ,itr)) arg))))
,@body))))
You can use macroexpand and macroexpand-1:
[77]> (defmacro doloop (vars &body body)
(let ((arg (gensym))
(itr (gensym)))
`(let ((,arg ',(car vars))
(,itr ',(cadr vars)))
(do ((,arg() (funcall (iter-n ,itr)))
((,v ,arg) ((null (funcall (iter-has-n ,itr)) arg))))
,@body))))
DOLOOP
[78]> (macroexpand '(doloop (n (list-itr '(a 2 3 4)))
(format t "~A~%" n)))
*** - EVAL: variable V has no value
The following restarts are available:
USE-VALUE :R1 You may input a value to be used instead of V.
STORE-VALUE :R2 You may input a new value for V.
ABORT :R3 ABORT
Break 1 [79]>
You can give names to gensym to make it more readable, and I removed
the comma before V to obtain the following to try to understand what
you're doing.
[87] (defmacro doloop (vars &body body)
(let ((arg (gensym "ARG-"))
(itr (gensym "ITR-")))
`(let ((,arg ',(car vars))
(,itr ',(cadr vars)))
(do ((,arg() (funcall (iter-n ,itr)))
((v ,arg) ((null (funcall (iter-has-n ,itr)) arg))))
,@body))))
DOLOOP
[88]> (macroexpand '(doloop (n (list-itr '(a 2 3 4)))
(format t "~A~%" n)))
(LET ((#:ARG-5244 'N) (#:ITR-5245 '(LIST-ITR '(A 2 3 4))))
(DO
((#:ARG-5244 NIL (FUNCALL (ITER-N #:ITR-5245)))
((V #:ARG-5244) ((NULL (FUNCALL (ITER-HAS-N #:ITR-5245)) ARG))))
(FORMAT T "~A~%" N))) ;
T
I'm still puzzled. To write a macro, instead of showing the result
of "calling" the macro, you should show an example of what the macro
should expand to:
(doloop (n '(a b c)) (print n))
--(expands-to)-->
(do ((n '() (first ,itr))
(,itr '(a b c) (rest ,itr)))
((null ,itr))
(print n))
(showing with , the gensymed variables for example).
Then we could easily write a macro to do that:
(defmacro doloop ((var init-value) &body body)
(let ((itr (gensym "ITR-")))
`(do ((,var '() (first ,itr))
(,itr ,init-value (rest ,itr)))
((null ,itr))
,@body)))
If you want something else, we need more explanations...
--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
.
- References:
- defmacro
- From: Kim Russell
- defmacro
- Prev by Date: unable to catch simple-error, debugger is not nice in server
- Next by Date: Re: unable to catch simple-error, debugger is not nice in server
- Previous by thread: Re: defmacro
- Next by thread: Re: defmacro
- Index(es):
Relevant Pages
|
Loading