From ... From: Erik Naggum Subject: Re: Question about Lisp Macros Date: 1997/12/21 Message-ID: <3091672847538179@naggum.no>#1/1 X-Deja-AN: 309018092 References: <67hl2g$n8g$1@agate.berkeley.edu> mail-copies-to: never Organization: Naggum Software; +47 8800 8879; http://www.naggum.no Newsgroups: comp.lang.lisp * Travis C. Porco | Many of us are occasionally puzzled by the behavior of Lisp macros. uhm, that introduction left me thinking that it is a bad idea to respond. | For instance, I recently was puzzled by a macro which seems to work | when called from the top level, but which does not work properly when | called from within a function. Here is the code block: | | (defstruct point x y) | (setf p1 (make-point :x 0 :y 0)) | (defmacro change (inp ex newval) | (let ((g (gensym))) | `(let ((,g (copy-point ,inp))) | (setf (,ex ,g) ,newval) | ,g))) | (defun chf (inp1 ex1 ne1) | (change inp1 ex1 ne1)) | | The idea is that the argument ex to the macro change will be the name | of a structure slot accessor. your macro `change' is naive, but working. your function `chf' is just hopeless. it is not, as you seem to think, that macros "can't be called from a function" that is confusing you, you have yet to understand when and how evaluation of arguments take place, and macros are the least of your problems at this time. in `chf', you introduce three new variables, inp1, ex1, and ne1. when you called (change p1 point-x 2), you gave `change' three _literals_ to work on, but in (change inp1 ex1 nei1), you give `change' three _variables_ whose _values_ you want it to work on. how, pray tell, should `change' know that you had changed your mind? or anybody else for that matter? on top of that, you quote _one_ of the values in the call to `chf', but not another. how did you _ever_ believe this could work? | Somehow, the formal parameter ex1 of the function chf does not get set | to point-x. yes, it does. (of course it does!) a bigger problem is that inp1 gets the _value_ of p1, which is no longer a valid argument to `copy-point'. | Macros provide a considerable amount of power in Lisp, but it's always | tempting to avoid them to avoid this sort of behavior, so frustrating to | a beginning writer of macros. this line of reasoning is baffling. you try to do something you do not understand how to do and then you get unexpected results (it is not clear that your expectations are consistent, either), and then you go on to make false claims about parts of the system that behave correctly since you get an error message you fail to investigate, only to wind up _avoiding_ the tools that don't comply with your wishful thinking? really, now. I think the only course of action for you is to explain to yourself why you thought this would work, not just type random code and see whether it works or not. it is literally impossible to unwind your guesswork to the point where a precise answer will help you, not the least because you don't seem to realize that you _are_ guessing at random. BTW, macros _are_ hard to write right. it takes a good grasp of the many different evaluation times in Common Lisp to get them exactly right. #\Erik -- If you think this year is number 97, | Help fight MULE in GNU Emacs 20! _you_ are not "Year 2000 Compliant". | http://sourcery.naggum.no/emacs/