[cl-faq] faq answer: What's the difference between a function, a macro, and a special form?
Vijay Lakshminarayanan
liyer.vijay at gmail.com
Thu Jun 22 22:07:39 CDT 2006
I think this is a very good explanation (though my opinion doesn't
carry much weight, I'll admit :-).
One thing, IMHO, is you could explain why a special form (such as IF)
cannot be written using a macro. I remember reading about that in a
book or a tutorial and I think it would be apt here too.
Cheers
Vijay
On 6/22/06, Larry Clapp <larry at theclapp.org> wrote:
> *** What's the difference between a function, a macro, and a special
> form?
>
> Functions, Macros, and Special Forms
> ------------------------------------
>
> When a function is called, all of its arguments are evaluated. A
> function can be FUNCALL'ed or APPLY'ed. Anybody can write a function:
> the programmer or the compiler writer.
>
> When a macro is called, none of its arguments are evaluated, but are
> instead passed directly to the macro as lists (or whatever). A macro
> cannot be FUNCALL'ed or APPLY'ed. Anybody can write a macro: the
> programmer or the compiler writer.
>
> When a special form is called, the evaluation of its arguments depends
> on the special form in question. For example, IF evaluates its first
> argument, and depending in its outcome, then evaluates either the
> second or third of its arguments. LET does something different.
> PROGN does something different still. Only the compiler writer can
> write a special form, and the list of special forms is pre-defined and
> fixed; see section 3.1.2.1.2.1 Special Forms in the CLHS. Special
> forms can also do other strange and interesting things that neither
> functions nor macros can do, like EVAL-WHEN or THE. Each special form
> defines its own semantics.
>
> Functions & Macros
> ------------------
>
> "Variables abstract over values, functions abstract over behavior,
> macros abstract over syntax."
> -- Joe Marshall, 23 Mar 2004, 7jxb5yls.fsf at ccs.neu.edu
>
> Abstracting behavior: Instead of writing the same code over and over,
> you write a function and call it. You've abstracted the behavior of
> the code into a function.
>
> Say you have a window with a button. You want another window to pop
> up when the user presses the button. You write a function to make the
> window pop up, and when the user presses the button, you call the
> function. You can call the function from other places, and the same
> window will pop up.
>
> Abstracting syntax: Instead of writing the same *looking* code over
> and over, you write a macro and call it. You've abstracted the syntax
> of the code, or the way the code looks, into a macro.
>
> Say you find yourself saying this a lot:
>
> (let ((x (do-something)))
> (if x
> (do-something-with x)
> (let ((y (do-something-else)))
> (if y
> (do-something-with y)
> ...))))
>
> and you think, "Too much repetition! Too much boilerplate! There's
> got to be a better way!" And there is. You write a WHEN-LET macro,
> and your code changes to
>
> (when-let ((x (do-something))
> (do-something-with x))
> ((y (do-something-else))
> (do-something-with y))
> (...))
>
> No boilerplate, no repetition. You've added new syntax. You can use
> the same syntax somewhere else, and your code will behave the same
> way.
>
> -- L
>
>
> _______________________________________________
> cl-faq mailing list
> cl-faq at lispniks.com
> http://www.lispniks.com/mailman/listinfo/cl-faq
>
More information about the cl-faq
mailing list