Newsgroups: comp.lang.lisp Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!barmar From: barmar@think.com (Barry Margolin) Subject: Re: macro misbehaviour Message-ID: <1991Jun9.141232.25632@Think.COM> Sender: news@Think.COM Reply-To: barmar@think.com Organization: Thinking Machines Corporation, Cambridge MA, USA References: <16456.285261a2@levels.sait.edu.au> Date: Sun, 9 Jun 91 14:12:32 GMT Lines: 40 In article <16456.285261a2@levels.sait.edu.au> Jenny.Rowland@levels.sait.edu.au writes: > (DEFMACRO TRY (X) (LET ((A (EVAL X))) `(TT ,(MAPCAR #'ADD-1 A)))) > (DEFUN ADD-1 (X) (1+ X)) > (DEFMACRO TT (X) `(FORMAT T "~a ~%" ',X)) > (dotimes (n 3) > (let ((a (list n n n))) > (try a))) > >I get the following results: > > (1 1 1) > (1 1 1) > (1 1 1) > >when I would expect: > > (1 1 1) > (2 2 2) > (3 3 3) The problem is your use of EVAL. I'm surprised you didn't get an unbound variable error regarding A; I suspect you had previously done (setq a '(0 0 0)) Unless you proclaim A special, LET binds it as a lexical variable. EVAL operates in the null lexical environment, so it isn't affected by this binding. However, even if you were to proclaim it special you might see this kind of behavior. Compilers must, and some interpreters do, expand macros before executing any of the code. Thus, the macro would be evaluated prior to binding the variable in the LET. This is why it is almost always wrong to use EVAL in macros. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar