Subject: Re: Question about Lisp Macros
From: Erik Naggum <clerik@naggum.no>
Date: 1997/12/21
Newsgroups: comp.lang.lisp
Message-ID: <3091672847538179@naggum.no>


* 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/