Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
Niidae Wiki
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Common Lisp
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Example using a macro to define a new control structure=== Macros allow Lisp programmers to create new syntactic forms in the language. One typical use is to create new control structures. The example macro provides an <code>until</code> looping construct. The syntax is: <syntaxhighlight lang="text"> (until test form*) </syntaxhighlight> The macro definition for ''until'': <syntaxhighlight lang="lisp"> (defmacro until (test &body body) (let ((start-tag (gensym "START")) (end-tag (gensym "END"))) `(tagbody ,start-tag (when ,test (go ,end-tag)) (progn ,@body) (go ,start-tag) ,end-tag))) </syntaxhighlight> ''tagbody'' is a primitive Common Lisp special operator which provides the ability to name tags and use the ''go'' form to jump to those tags. The backquote ''`'' provides a notation that provides code templates, where the value of forms preceded with a comma are filled in. Forms preceded with comma and at-sign are ''spliced'' in. The tagbody form tests the end condition. If the condition is true, it jumps to the end tag. Otherwise, the provided body code is executed and then it jumps to the start tag. An example of using the above ''until'' macro: <syntaxhighlight lang="lisp"> (until (= (random 10) 0) (write-line "Hello")) </syntaxhighlight> The code can be expanded using the function ''macroexpand-1''. The expansion for the above example looks like this: <syntaxhighlight lang="lisp"> (TAGBODY #:START1136 (WHEN (ZEROP (RANDOM 10)) (GO #:END1137)) (PROGN (WRITE-LINE "hello")) (GO #:START1136) #:END1137) </syntaxhighlight> During macro expansion the value of the variable ''test'' is ''(= (random 10) 0)'' and the value of the variable ''body'' is ''((write-line "Hello"))''. The body is a list of forms. Symbols are usually automatically upcased. The expansion uses the TAGBODY with two labels. The symbols for these labels are computed by GENSYM and are not interned in any package. Two ''go'' forms use these tags to jump to. Since ''tagbody'' is a primitive operator in Common Lisp (and not a macro), it will not be expanded into something else. The expanded form uses the ''when'' macro, which also will be expanded. Fully expanding a source form is called ''code walking''. In the fully expanded (''walked'') form, the ''when'' form is replaced by the primitive ''if'': <syntaxhighlight lang="lisp"> (TAGBODY #:START1136 (IF (ZEROP (RANDOM 10)) (PROGN (GO #:END1137)) NIL) (PROGN (WRITE-LINE "hello")) (GO #:START1136)) #:END1137) </syntaxhighlight> All macros must be expanded before the source code containing them can be evaluated or compiled normally. Macros can be considered functions that accept and return [[S-expression]]s β similar to [[abstract syntax tree]]s, but not limited to those. These functions are invoked before the evaluator or compiler to produce the final source code. Macros are written in normal Common Lisp, and may use any Common Lisp (or third-party) operator available.
Summary:
Please note that all contributions to Niidae Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Encyclopedia:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
Common Lisp
(section)
Add topic