From: Pascal J. Bourguignon on
Alan Malloy <alan.NO.SPAM(a)malloys.org> writes:

> As mentioned earlier, I'm a new Lisper (and taking up emacs as well
> now; thanks refun for re-suggesting it). I was trying to write a
> simple macro earlier tonight, and I'd written a long post to ask
> c.l.lisp to help me figure out what was wrong. But, afraid of looking
> too much like a newcomer, I spent an additional hour or two trying to
> understand what was happening and finally figured it out (so that's
> good, I guess). My question NOW is, does anyone have a reference, or
> even some general tips, on how to understand compiler/interpreter
> error messages?
>
> Tonight's message was "EVAL: #1=(SETF #:G3813 NIL) is not a function
> name; try using a symbol instead", and it took me forever to
> understand that I was misusing backquote as `((setf ,var nil) (more
> stuff) when what I really meant was `(progn (setf ,var nil) (more
> stuff). I've had lots of experiences like this in my week-long Lisp
> career already, and I hope that someone out there can tell me how to
> understand the compiler's feedback. If it matters, I'm using clisp
> 2.44 and emacs. Usually I use slime too, but the error messages it
> generates are even more obscure so I often fall back on entering stuff
> into clisp by hand.

The general problem here is that you have your own goal as a programmer,
or newbie programmer, and your goals cannot be infered by a CL
implementation just from the CL source code you give to it.

Your goal was to set a variable to nil.


What the implementation sees is only a tree of cons cells (a s-exp):

((SETF #:G3813 NIL) X Y Z)

and the only thing the implementation can do, what it _must_ do, is to
implement the evaluation rules. It cannot infer a mental model of you,
the programmer, to understand the s-exp, but you cann have a mental
model of what the implementation has to do, by learning the evaluation
rules.

Here, the rule that applies, is that a form which is a list, is
interpreted depending on the first element of that list. The meaning
of:

((SETF #:G3813 NIL) X Y Z)

depends on what (SETF #:G3813 NIL) is.

If it is a symbol denoting a special operator, then special rules apply.
If it is a symbol denoting a macro, then the macro function must be
called. This is not the case.
If it is a list starting with the symbol CL:LAMBDA, then an anonymous
function is to be called. But here, it is a list starting with the
symbol CL:SETF, so it won't do.
Finally, the only case remaining is that it should be a symbol that will
be fbound to a function at run-time, but it is not a symbol! So there's
an error, because it is not a function name.

The error message could have been clearer (longer) saying that it is not
a function name, and neither a lambda expression and neither a macro
name or a special operator name, and therefore the form where it appears
in first position is an invalid form.

But if you knew the evaluation rules, it would be obvious.

http://www.lispworks.com/documentation/HyperSpec/Body/03_.htm


--
__Pascal Bourguignon__
From: Alan Malloy on
Alex Mizrahi wrote:
> AM> was happening and finally figured it out (so that's good, I guess). My
> AM> question NOW is, does anyone have a reference, or even some general
> AM> tips, on how to understand compiler/interpreter error messages?
>
> 1. Of course, practice helps a lot.
> 2. Different implementations have different error messages, some might
> be more informative than the other. I don't know which is the best, but
> if you have particularly hard error, it might make sense to try in a
> different implementation(s) -- maybe rephrased error message will be
> easier to understand, or you can see something common, etc.
> I've heard commercial implementation have cool debuggers with
> stepping and stuff, but I've never used them myself...
> 3. I know it is hard to believe that, but often _attentive_ reading of
> error messages and documentation helps. If you don't know some concepts
> references in the error message, look them up in documentation.
> 4. Googling for some part of an error message might show messages of
> people having same error and, possibly, resolution. A trick is to pick a
> relevant part of the message, omitting unnecessary details.
> 5. If you're looking for a quick fix, try asking on IRC channel (#lisp
> on irc.freenode.net). People are wasting time on IRC anyway, so it is
> not a problem to ask even dumb questions.
>
> 6. If you're debugging macros, there are some tricks:
> * macroexpand it (duh!)
> * if you have problems only in certain context, or if you're debugging
> macrolet, macroexpand and print it _in that conext_.
> there is a magic macro for it:
>
> (defmacro mx1p (form &environment env)
> "Macroexpands form in context and prints it in macroexpansion time.
> Otherwise transparent"
> (print (macroexpand-1 form env))
> form)
>
> E.g. if you want to expansion of (foo 42) here:
>
> (macrolet ((foo (x) `(bar ,x)))
> (foo 42))
>
> Just wrap it with mx1p:
>
>
> (macrolet ((foo (x) `(bar ,x)))
> (mx1p (foo 42)))
>
> It prints (BAR 42) when you compile this.
>
> AM> Tonight's message was "EVAL: #1=(SETF #:G3813 NIL) is not a function
> AM> name; try using a symbol instead",
>
> Well, it's rather simple. Where is function name used? In a function
> call. It usually looks like (function_name function parameters).
> And indeed, it is usually a symbol. What it tells you is that you have
> (SETF something) instead of function name. That is, you have ((setf ...)
> function parameters).
> Quite a weird form...
> Where do you have SETF in your macro? Can it generate this weird
> function call? How it should look?
>
> LIkewise, you could use macroexpansion to see that `((setf ...) (more
> stuff)) looks weird.
> If it doesn't, then maybe you need to read a chapter about semantics of
> evaluation in Common Lisp.

Thanks for suggesting #lisp! I always forget IRC exists, and when I
dropped in today I got some helpful answers to my quick-and-stupid
questions.

By the way, I do understand the evaluation semantics; but I haven't yet
internalized them to the degree that I can produce code that means what
I want it to all the time. I tried macroexpand-1, too, but I forgot I
needed to quote the list so it was giving me the same error. I was
writing (macroexpand-1 (mymacro args)) instead of (macroexpand-1
'(mymacro args))

--
Cheers,
Alan (San Jose, California, USA)
From: Alberto Riva on
Alan Malloy wrote:
> Alex Mizrahi wrote:
>> AM> was happening and finally figured it out (so that's good, I
>> guess). My
>> AM> question NOW is, does anyone have a reference, or even some general
>> AM> tips, on how to understand compiler/interpreter error messages?
>>
>> 1. Of course, practice helps a lot.
>> 2. Different implementations have different error messages, some might
>> be more informative than the other. I don't know which is the best,
>> but if you have particularly hard error, it might make sense to try in
>> a different implementation(s) -- maybe rephrased error message will be
>> easier to understand, or you can see something common, etc.
>> I've heard commercial implementation have cool debuggers with
>> stepping and stuff, but I've never used them myself...
>> 3. I know it is hard to believe that, but often _attentive_ reading of
>> error messages and documentation helps. If you don't know some
>> concepts references in the error message, look them up in documentation.
>> 4. Googling for some part of an error message might show messages of
>> people having same error and, possibly, resolution. A trick is to pick
>> a relevant part of the message, omitting unnecessary details.
>> 5. If you're looking for a quick fix, try asking on IRC channel (#lisp
>> on irc.freenode.net). People are wasting time on IRC anyway, so it is
>> not a problem to ask even dumb questions.
>>
>> 6. If you're debugging macros, there are some tricks:
>> * macroexpand it (duh!)
>> * if you have problems only in certain context, or if you're debugging
>> macrolet, macroexpand and print it _in that conext_.
>> there is a magic macro for it:
>>
>> (defmacro mx1p (form &environment env)
>> "Macroexpands form in context and prints it in macroexpansion time.
>> Otherwise transparent"
>> (print (macroexpand-1 form env))
>> form)
>>
>> E.g. if you want to expansion of (foo 42) here:
>>
>> (macrolet ((foo (x) `(bar ,x)))
>> (foo 42))
>>
>> Just wrap it with mx1p:
>>
>>
>> (macrolet ((foo (x) `(bar ,x)))
>> (mx1p (foo 42)))
>>
>> It prints (BAR 42) when you compile this.
>>
>> AM> Tonight's message was "EVAL: #1=(SETF #:G3813 NIL) is not a function
>> AM> name; try using a symbol instead",
>>
>> Well, it's rather simple. Where is function name used? In a function
>> call. It usually looks like (function_name function parameters).
>> And indeed, it is usually a symbol. What it tells you is that you have
>> (SETF something) instead of function name. That is, you have ((setf
>> ...) function parameters).
>> Quite a weird form...
>> Where do you have SETF in your macro? Can it generate this weird
>> function call? How it should look?
>>
>> LIkewise, you could use macroexpansion to see that `((setf ...) (more
>> stuff)) looks weird.
>> If it doesn't, then maybe you need to read a chapter about semantics
>> of evaluation in Common Lisp.
>
> Thanks for suggesting #lisp! I always forget IRC exists, and when I
> dropped in today I got some helpful answers to my quick-and-stupid
> questions.
>
> By the way, I do understand the evaluation semantics; but I haven't yet
> internalized them to the degree that I can produce code that means what
> I want it to all the time. I tried macroexpand-1, too, but I forgot I
> needed to quote the list so it was giving me the same error. I was
> writing (macroexpand-1 (mymacro args)) instead of (macroexpand-1
> '(mymacro args))

And do you understand why it gives you that error when you omit the quote?

Alberto
From: Alan Malloy on
Alberto Riva wrote:
> Alan Malloy wrote:
>> Alex Mizrahi wrote:
>>> AM> was happening and finally figured it out (so that's good, I
>>> guess). My
>>> AM> question NOW is, does anyone have a reference, or even some general
>>> AM> tips, on how to understand compiler/interpreter error messages?
>>>
>>> 1. Of course, practice helps a lot.
>>> 2. Different implementations have different error messages, some
>>> might be more informative than the other. I don't know which is the
>>> best, but if you have particularly hard error, it might make sense to
>>> try in a different implementation(s) -- maybe rephrased error message
>>> will be easier to understand, or you can see something common, etc.
>>> I've heard commercial implementation have cool debuggers with
>>> stepping and stuff, but I've never used them myself...
>>> 3. I know it is hard to believe that, but often _attentive_ reading
>>> of error messages and documentation helps. If you don't know some
>>> concepts references in the error message, look them up in documentation.
>>> 4. Googling for some part of an error message might show messages of
>>> people having same error and, possibly, resolution. A trick is to
>>> pick a relevant part of the message, omitting unnecessary details.
>>> 5. If you're looking for a quick fix, try asking on IRC channel
>>> (#lisp on irc.freenode.net). People are wasting time on IRC anyway,
>>> so it is not a problem to ask even dumb questions.
>>>
>>> 6. If you're debugging macros, there are some tricks:
>>> * macroexpand it (duh!)
>>> * if you have problems only in certain context, or if you're
>>> debugging macrolet, macroexpand and print it _in that conext_.
>>> there is a magic macro for it:
>>>
>>> (defmacro mx1p (form &environment env)
>>> "Macroexpands form in context and prints it in macroexpansion time.
>>> Otherwise transparent"
>>> (print (macroexpand-1 form env))
>>> form)
>>>
>>> E.g. if you want to expansion of (foo 42) here:
>>>
>>> (macrolet ((foo (x) `(bar ,x)))
>>> (foo 42))
>>>
>>> Just wrap it with mx1p:
>>>
>>>
>>> (macrolet ((foo (x) `(bar ,x)))
>>> (mx1p (foo 42)))
>>>
>>> It prints (BAR 42) when you compile this.
>>>
>>> AM> Tonight's message was "EVAL: #1=(SETF #:G3813 NIL) is not a function
>>> AM> name; try using a symbol instead",
>>>
>>> Well, it's rather simple. Where is function name used? In a function
>>> call. It usually looks like (function_name function parameters).
>>> And indeed, it is usually a symbol. What it tells you is that you
>>> have (SETF something) instead of function name. That is, you have
>>> ((setf ...) function parameters).
>>> Quite a weird form...
>>> Where do you have SETF in your macro? Can it generate this weird
>>> function call? How it should look?
>>>
>>> LIkewise, you could use macroexpansion to see that `((setf ...) (more
>>> stuff)) looks weird.
>>> If it doesn't, then maybe you need to read a chapter about semantics
>>> of evaluation in Common Lisp.
>>
>> Thanks for suggesting #lisp! I always forget IRC exists, and when I
>> dropped in today I got some helpful answers to my quick-and-stupid
>> questions.
>>
>> By the way, I do understand the evaluation semantics; but I haven't
>> yet internalized them to the degree that I can produce code that means
>> what I want it to all the time. I tried macroexpand-1, too, but I
>> forgot I needed to quote the list so it was giving me the same error.
>> I was writing (macroexpand-1 (mymacro args)) instead of (macroexpand-1
>> '(mymacro args))
>
> And do you understand why it gives you that error when you omit the quote?
>
> Alberto

Yes. Without the quote it expands the macro and tries to execute it,
before macroexpand-1 can have a go at it (which, when my macro was
broken, caused an error). I assume this means macroexpand-1 is a
function, which surprised me, but I guess makes sense. I assumed it
would be a macro, in which case (I think?) it could intercept its
argument list coming in, and quote it before passing it to some
behind-the-scenes macro expander. I don't quite see why this isn't the
standard behavior for macroexpand-1, but I understand why, with the
function defined as it is, it behaves this way.

--
Cheers,
Alan (San Jose, California, USA)
From: Alberto Riva on
Alan Malloy wrote:
> Alberto Riva wrote:
>> Alan Malloy wrote:
>>> By the way, I do understand the evaluation semantics; but I haven't
>>> yet internalized them to the degree that I can produce code that
>>> means what I want it to all the time. I tried macroexpand-1, too, but
>>> I forgot I needed to quote the list so it was giving me the same
>>> error. I was writing (macroexpand-1 (mymacro args)) instead of
>>> (macroexpand-1 '(mymacro args))
>>
>> And do you understand why it gives you that error when you omit the
>> quote?
>>
>> Alberto
>
> Yes. Without the quote it expands the macro and tries to execute it,
> before macroexpand-1 can have a go at it (which, when my macro was
> broken, caused an error). I assume this means macroexpand-1 is a
> function, which surprised me, but I guess makes sense. I assumed it
> would be a macro, in which case (I think?) it could intercept its
> argument list coming in, and quote it before passing it to some
> behind-the-scenes macro expander. I don't quite see why this isn't the
> standard behavior for macroexpand-1, but I understand why, with the
> function defined as it is, it behaves this way.

Right. That's why I asked the question, I think it helps clarify the
distinction between macroexpansion time and execution time. It seems you
passed the test :)

Alberto