Xref: utzoo comp.lang.lisp:624 comp.emacs:2442 Path: utzoo!mnetor!uunet!husc6!uwvax!ai!neves From: neves@ai.WISC.EDU (David M. Neves) Newsgroups: comp.lang.lisp,comp.emacs Subject: Re: A CL iteration macro, "while". Message-ID: <4935@spool.cs.wisc.edu> Date: 22 Dec 87 22:40:41 GMT References: <13639@beta.UUCP> Sender: news@spool.cs.wisc.edu Reply-To: neves@ai.WISC.EDU (David M. Neves) Organization: U of Wisconsin CS Dept Lines: 58 Keywords: Let's have a little non-flamable fun... Summary: misunderstanding macros [[When I see articles that have obvious errors I usually wait a few days because I know that others will most likely post responses. In this case I happened to have defined a while macro myself. So...]] In article <13639@beta.UUCP> dzzr@beta.UUCP (Douglas J Roberts) writes: > ... > >I thought it would be fun to write a CL while macro and then post it >for comment, etc. I'd be curious for anybody interested enough to >suggest other ways of writing it. > ... > >(defmacro while (test-form &rest forms) > "This macro evaluates test-form, and if the result is non-nil > all subsequent forms will be iteratively evaluated until > test-form evaluates to nil." > (prog () > again > (cond ( > (eval test-form) > (mapcar #'eval forms) > (go again) > )) > )) There are a couple of problems with this code. 1. You use mapcar to iterate through the forms. Mapcar is going to create a list as a result. Since you are not using the result of mapcar you have done unnecessary CONSing. This means your program will run slower because it will do more garbage collection. Use mapc instead. 2. Even more serious is the way you defined the macro. You are almost using it as we used to use fexprs or nlambdas[1]. A macro translates its input into another form, which then is evaluated. Your code will work if it is interpreted but not when it is compiled. The compiler will substitute the translation (in this case it will be nil, the value of the prog) for each call to "while". [1] (A reason for using macros rather than fexprs is to get the correct scoping when the forms are evaluated. I won't go more into this here.) Here is a correct definition of while in Common Lisp. (defmacro while (test &rest body) `(do nil (,test) ,@body)) "`" is the backquote character. "," evaluates the s-expression after it (within a backquote). ",@" is similar to "," in that it evaluates the s-expression that follows it. It is different in that the value of the s-expression is spliced into the existing list. David Neves, Computer Sciences Department, University of Wisconsin-Madison Usenet: {rutgers,ucbvax,ihnp4}!uwvax!neves Arpanet: neves@cs.wisc.edu