From: Pascal J. Bourguignon on 24 Mar 2010 15:36 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 24 Mar 2010 18:46 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 24 Mar 2010 20:27 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 24 Mar 2010 20:35 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 24 Mar 2010 20:39 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
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: the rise and fall of t Next: emacs lisp tutorial: Count Words and Chars |