*** 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, [EMAIL PROTECTED]

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@lispniks.com
http://www.lispniks.com/mailman/listinfo/cl-faq

Reply via email to