Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!rpi!zaphod.mps.ohio-state.edu!casbah.acns.nwu.edu!ils.nwu.edu!krulwich From: krulwich@ils.nwu.edu (Bruce Krulwich) Newsgroups: comp.lang.lisp Subject: Re: macro misbehaviour Message-ID: <2034@anaxagoras.ils.nwu.edu> Date: 10 Jun 91 15:39:09 GMT References: <16456.285261a2@levels.sait.edu.au> Sender: news@ils.nwu.edu Reply-To: krulwich@ils.nwu.edu (Bruce Krulwich) Organization: Institute for the Learning Sciences, Northwestern University, Evanston, IL 60201 Lines: 56 In-reply-to: Jenny.Rowland@levels.sait.edu.au Two recently posted macro questions suffer from the same problem: In article <16456.285261a2@levels.sait.edu.au>, Jenny.Rowland@levels 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)) >and the following code: > (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) >It appears that the first call is evaluated, but further calls are >'recognised' as being the same as previous calls (despite the fact that the >value of n and therefore a has changed), bypasses evaluation of the mapcar >form, and sends the previous result to macro tt. In article <30996@hydra.gatech.EDU>, gt4084c@prism (SRINIVASAN,K) writes: >During any single iteration, the three calls to "read" read three >succesive symbols from the file as you would expect. However, during >successive iterations, the same set of three symbols are read repeatedly. >So, I get the same class defined 4 times instead of defining 4 different >classes. > >(defmacro class-from-file (file-name) > (with-open-file (input-stream file-name > :direction :input) > `(do ((q 4 (- q 1))) ((= q 0) nil) > (Define-Class ,(read input-stream) ,(read input-stream) > .,(read input-stream))))) In each case there is some code that is only run once that "should" be run several times. The problem in each case is that computation is done at the time the macro is expanded that should be done at the time the macro result is executed. In other words, the code for a DEFMACRO (i.e., the code which takes arguments and returns a list which is later executed) can and should only be executed once, and the list which it returns is then plugged into the program and executed as often as desired. In the above macros, the code which is only executed once (the MAPCAR in the first example, and the WITH-OPEN-FILE / READ in the second) is executed at the time the code is compiled (or parsed by the interpreter), and the result (the result of MAPCARing at compile-time, or the thing read from the file at compile-time) is plugged into the loops. Hope this helps. Bruce Krulwich krulwich@ils.nwu.edu