Page 1 of 1

Avoiding evaluation without quote

Posted: Sat Nov 01, 2008 4:50 pm
by jordan
Hello,

I was wondering if there is a way to define a function/macro that can accept arbitrary forms as arguments, without having to QUOTE said forms in the calling code. (Basically, I'm looking to replicate the behavior of many built-in functions/macros that let you say things like (foo (x y) ... ) without having to say (my-foo '(x y) ... ) ... hopefully that makes sense.)

Thanks!

Re: Avoiding evaluation without quote

Posted: Sat Nov 01, 2008 5:14 pm
by Paul Donnelly
That's what macros do. They recieve their arguments as read (which is usually the same text you typed*), without any evaluation. You want to read up on macro writing first, because there are pitfalls to keep in mind, such as unintentional variable capture and accidentally evaluating arguments multiple times.

If you want to do something interesting in your macro, a good approach is to implement the guts as a function, then use the macro to implement the easier syntax:

Code: Select all

(defun my-foo-guts (quoted-list) ...)
(defmacro my-foo (unquoted-list) `(my-foo-guts ',unquoted-list))
The macro, when expanded, returns a properly formed call to MY-FOO-GUTS, which will be substituted for the macro.


* This will be either a list or an atom—not a string of characters. So if I called MY-FOO on (A B C), an alternate body would be able to use CAR, CDR, and other list manipulation functions on UNQUOTED-LIST.

Re: Avoiding evaluation without quote

Posted: Sat Nov 01, 2008 6:10 pm
by jordan
Thank you :) I believe my mental hangup was being caused by not understanding how multiple levels of quoting/commas worked (like the ',unquoted-list in your example).

Re: Avoiding evaluation without quote

Posted: Mon Nov 03, 2008 8:50 am
by findinglisp
jordan wrote: I was wondering if there is a way to define a function/macro that can accept arbitrary forms as arguments, without having to QUOTE said forms in the calling code. (Basically, I'm looking to replicate the behavior of many built-in functions/macros that let you say things like (foo (x y) ... ) without having to say (my-foo '(x y) ... ) ... hopefully that makes sense.)
jordan,

Only macros let you do what you want. The Lisp evaluation function (EVAL), built into the heart of the interpreter/compiler, is wired to view any list that is not quoted as a function call. It's also hard-wired to treat any symbol as a reference to a variable. QUOTE is simply the mechanism that tells EVAL that the following form is literal data and to treat it as such, not as something to be evaluated further.

The reason that macros don't do this is because they operate on the code as data. Quite literally, a macro simply sees that "code" as a list of symbols and such. After the macro transforms the code, manipulating it however it wants, then EVAL operates on the results. At that point, as Paul pointed out, all the quoting has to be correct.

I'd caution you not to use the technique Paul showed you in much code that is going to be ready by anybody else. Other Lisp programmers will intuitively know when quoting is required and they'll be thrown off if they don't have to do it. :)

Re: Avoiding evaluation without quote

Posted: Mon Nov 03, 2008 3:03 pm
by Paul Donnelly
findinglisp wrote:I'd caution you not to use the technique Paul showed you in much code that is going to be ready by anybody else. Other Lisp programmers will intuitively know when quoting is required and they'll be thrown off if they don't have to do it. :)
I think you misunderstand the circumstances under which I was suggesting doing that. I assume he has a good reason for wanting special syntax, such as writing a DOTIMES-style iteration function.

Re: Avoiding evaluation without quote

Posted: Mon Nov 03, 2008 10:46 pm
by findinglisp
Paul Donnelly wrote:
findinglisp wrote:I'd caution you not to use the technique Paul showed you in much code that is going to be ready by anybody else. Other Lisp programmers will intuitively know when quoting is required and they'll be thrown off if they don't have to do it. :)
I think you misunderstand the circumstances under which I was suggesting doing that. I assume he has a good reason for wanting special syntax, such as writing a DOTIMES-style iteration function.
Yes, indeed. I wasn't faulting you for describing the basic mechanism. I was only trying to say that such a technique should be used sparingly and not as a way to simply bypass standard quoting mechanisms for the sake of removing QUOTEs in function calls. It's quite instructive to understand what the various mechanisms are that Lisp provides the programmer, but it's also important to learn standard idioms and where such techniques should be applied.

In short, my only intent was to say that using that style for every function in a program, for instance, would be highly non-idiomatic and quite annoying to a knowledgeable Lisp programmer trying to read the code.

Re: Avoiding evaluation without quote

Posted: Tue Nov 04, 2008 1:54 pm
by Paul Donnelly
findinglisp wrote:In short, my only intent was to say that using that style for every function in a program, for instance, would be highly non-idiomatic and quite annoying to a knowledgeable Lisp programmer trying to read the code.
Yes indeed. 8-)