*** 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