Whatever is on your mind, whether Lisp related or not.
-
luk10ppp
- Posts: 1
- Joined: Mon Feb 06, 2012 10:19 am
Post
by luk10ppp » Mon Feb 06, 2012 10:47 am
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)))))
Last edited by
nuntius on Tue Feb 07, 2012 5:30 pm, edited 1 time in total.
Reason: add code tag, tweak whitespace
-
Kompottkin
- Posts: 94
- Joined: Mon Jul 21, 2008 7:26 am
- Location: München, Germany
-
Contact:
Post
by Kompottkin » Tue Feb 07, 2012 1:09 am
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.