Page 1 of 1

macro

Posted: Mon Feb 06, 2012 10:47 am
by luk10ppp
Hi everybody, I am he beginner in Lisp. One of my first aim is to do dotimes macro with DO loop. Can anybody help to to modify my code? This is it:

Code: Select all

(defmacro dotimes2 (lista &body body)
  (let ((second lista) 0)
    `(progn
      (do ((,(first lista) ,(second lista (2+ ,(first lista))))
           ((>= ,(first lista) ,(second lista)) ,return-value)
           ,@body)))))

Re: macro

Posted: Tue Feb 07, 2012 1:09 am
by Kompottkin
You're quite close!

Some remarks:
  • (let ((second lista) 0) ...) tries to bind a variable called (second lista) to the value 0 at macro expansion time. That does not make sense, and you don't need it.
  • Your binding list (the thing right after do) is probably supposed to read ((,(first lista) 0 (+ 2 ,(first lista)))), since you want to generate code like (do ((x 0 (+ 2 x))) ...). The parentheses are a bit confused, too.
  • return-value is not declared anywhere. You probably meant (third lista).
  • (OPTIONAL) The progn is unnecessary (but it doesn't hurt either).
  • (OPTIONAL) You can simplify the handling of lista by using the destructuring facilities of macro lambda lists. defmacro permits you to write things like: (defmacro dotimes2 ((var count &optional result-value) &body body) ...)
  • (ADVANCED/BONUS—ignore for now) Note that the code represented by (second lista) is inserted at a position that will make it be evaluated on each iteration of the loop. You can avoid this by wrapping the do with a let of a gensym'd variable.