User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:functions:macroexpand [2019/07/14 17:00]
cl:functions:macroexpand [2019/07/17 21:00] (current)
Line 1: Line 1:
 +====== Function MACROEXPAND,​ MACROEXPAND-1 ======
 +
 +====Syntax====
 +  * **macroexpand** //form ''&​optional''​ env// → //​expansion,​ expanded-p//​
 +  * **macroexpand-1** //form ''&​optional''​ env// → //​expansion,​ expanded-p//​
 +
 +====Arguments and Values====
 +  * //form// - a //​[[CL:​Glossary:​form]]//​.
 +  * //env// - an //​[[CL:​Glossary:​environment]]//​ //​[[CL:​Glossary:​object]]//​. The default is **[[CL:​Constant Variables:​nil]]**.
 +  * //​expansion//​ - a //​[[CL:​Glossary:​form]]//​.
 +  * //​expanded-p//​ - a //​[[CL:​Glossary:​generalized boolean]]//​.
 +
 +====Description====
 +**macroexpand** and **macroexpand-1** expand //​[[CL:​Glossary:​macros]]//​.
 +
 +If //form// is a //​[[CL:​Glossary:​macro form]]//, then **macroexpand-1** expands the //​[[CL:​Glossary:​macro form]]// call once.
 +
 +**macroexpand** repeatedly expands //form// until it is no longer a //​[[CL:​Glossary:​macro form]]//. In effect, **macroexpand** calls **macroexpand-1** repeatedly until the //​[[CL:​Glossary:​secondary value]]// it returns is **[[CL:​Constant Variables:​nil]]**.
 +
 +If //form// is a //​[[CL:​Glossary:​macro form]]//, then the //​expansion//​ is a //​[[CL:​Glossary:​macro expansion]]//​ and //​expanded-p//​ is //​[[CL:​Glossary:​true]]//​. Otherwise, the //​expansion//​ is the given //form// and //​expanded-p//​ is //​[[CL:​Glossary:​false]]//​.
 +
 +Macro expansion is carried out as follows. Once **macroexpand-1** has determined that the //form// is a //​[[CL:​Glossary:​macro form]]//, it obtains an appropriate expansion //​[[CL:​Glossary:​function]]//​ for the //​[[CL:​Glossary:​macro]]//​ or //​[[CL:​Glossary:​symbol macro]]//. The value of **[[CL:​Variables:​star-macroexpand-hook-star|*macroexpand-hook*]]** is coerced to a //​[[CL:​Glossary:​function]]//​ and then called as a //​[[CL:​Glossary:​function]]//​ of three arguments: the expansion //​[[CL:​Glossary:​function]]//,​ the //form//, and the //env//. The //​[[CL:​Glossary:​value]]//​ returned from this call is taken to be the expansion of the //form//.
 +
 +In addition to //​[[CL:​Glossary:​macro]]//​ definitions in the global environment,​ any local macro definitions established within //env// by **[[CL:​Special Operators:​macrolet]]** or **[[CL:​Special Operators:​symbol-macrolet]]** are considered. If only //form// is supplied as an argument, then the environment is effectively null, and only global macro definitions as established by **[[CL:​Macros:​defmacro]]** are considered.
 +
 +//​[[CL:​Glossary:​macro|Macro]]//​ definitions are shadowed by local //​[[CL:​Glossary:​function]]//​ definitions.
 +
 +====Examples====
 +These macros are defined in the three examples below:
 +
 +<​blockquote>​
 +;;; Helper macros
 +([[CL:​Macros:​defmacro]] expand (form &​environment env)
 +  ([[CL:​Macros:​multiple-value-bind]] (expansion expanded-p) (macroexpand form env) 
 +    `([[CL:​Functions:​values]] ',​expansion ',​expanded-p))) <​r>​EXPAND</​r>​
 +
 +([[CL:​Macros:​defmacro]] expand-1 (form &​environment env)
 +  ([[CL:​Macros:​multiple-value-bind]] (expansion expanded-p) (macroexpand-1 form env)
 +    `([[CL:​Functions:​values]] ',​expansion ',​expanded-p))) <​r>​EXPAND-1</​r>​
 +
 +;;; Sample macros
 +([[CL:​Macros:​defmacro]] alpha (x y) `(beta ,x ,y)) <​r>​ALPHA</​r>​
 +([[CL:​Macros:​defmacro]] beta (x y) `(gamma ,x ,y)) <​r>​BETA</​r>​
 +([[CL:​Macros:​defmacro]] delta (x y) `(gamma ,x ,y)) <​r>​DELTA</​r>​
 +</​blockquote>​
 +
 +==Simple examples involving just the global environment==
 +<​blockquote>​
 +(macroexpand-1 '​(alpha a b)) 
 +<​r>​(BETA A B)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +(expand-1 (alpha a b)) 
 +<​r>​(BETA A B)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +
 +(macroexpand '​(alpha a b))
 +<​r>​(GAMMA A B)
 + //​[[CL:​Glossary:​true]]//​ </r>
 +(expand (alpha a b)) 
 +<​r>​(GAMMA A B)
 +//​[[CL:​Glossary:​true]]//</​r>​
 +
 +(macroexpand-1 '​not-a-macro)
 +<​r>​NOT-A-MACRO
 +//​[[CL:​Glossary:​false]]//​ </r>
 +(expand-1 not-a-macro)
 +<​r>​NOT-A-MACRO
 +//​[[CL:​Glossary:​false]]//​ </r>
 +
 +(macroexpand '​(not-a-macro a b)) 
 +<​r>​(NOT-A-MACRO A B)
 +//​[[CL:​Glossary:​false]]//​ </r>
 +(expand (not-a-macro a b)) 
 +<​r>​(NOT-A-MACRO A B)
 +//​[[CL:​Glossary:​false]]//</​r>​
 +</​blockquote>​
 +
 +==Examples involving lexical environments==
 +<​blockquote>​
 +([[CL:​Special Operators:​macrolet]] ((alpha (x y) `(delta ,x ,y)))
 +  (macroexpand-1 '​(alpha a b))) 
 +<​r>​(BETA A B)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +
 +([[CL:​Special Operators:​macrolet]] ((alpha (x y) `(delta ,x ,y))) 
 +  (expand-1 (alpha a b))) 
 +<​r>​(DELTA A B)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​macrolet]] ((alpha (x y) `(delta ,x ,y))) 
 +  (macroexpand '​(alpha a b))) 
 +<​r>​(GAMMA A B)
 +//​[[CL:​Glossary:​true]]//</​r>​
 +  ​
 +([[CL:​Special Operators:​macrolet]] ((alpha (x y) `(delta ,x ,y))) 
 +  (expand (alpha a b))) 
 +<​r>​(GAMMA A B)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​macrolet]] ((beta (x y) `(epsilon ,x ,y))) 
 +  (expand (alpha a b))) 
 +<​r>​(EPSILON A B)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​let]] ((x ([[CL:​Functions:​list]] 1 2 3))) 
 +  ([[CL:​Special Operators:​symbol-macrolet]] ((a ([[CL:​Functions:​first]] x))) 
 +    (expand a))) 
 +<​r>​([[CL:​Functions:​first|FIRST]] X)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​let]] ((x ([[CL:​Functions:​list]] 1 2 3))) 
 +  ([[CL:​Special Operators:​symbol-macrolet]] ((a ([[CL:​Functions:​first]] x))) 
 +    (macroexpand '​a))) ​
 +<r>A
 +//​[[CL:​Glossary:​false]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​symbol-macrolet]] ((b (alpha x y))) 
 +  (expand-1 b)) 
 +<​r>​(ALPHA X Y)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​symbol-macrolet]] ((b (alpha x y))) 
 +  (expand b)) 
 +<​r>​(GAMMA X Y)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​symbol-macrolet]] ((b (alpha x y)) (a b)) 
 +  (expand-1 a)) 
 +<r>B
 +//​[[CL:​Glossary:​true]]//</​r> ​
 +  ​
 +([[CL:​Special Operators:​symbol-macrolet]] ((b (alpha x y)) (a b)) 
 +  (expand a)) 
 +<​r>​(GAMMA X Y)
 +//​[[CL:​Glossary:​true]]//​ </r>
 +</​blockquote>​
 +
 +==Examples of shadowing behavior==
 +<​blockquote>​
 +([[CL:​Special Operators:​flet]] ((beta (x y) (+ x y)))
 +  (expand (alpha a b))) 
 +<​r>​(BETA A B)
 +//​[[CL:​Glossary:​true]]//</​r>​
 +
 +([[CL:​Special Operators:​macrolet]] ((alpha (x y) `(delta ,x ,y)))
 +  ([[CL:​Special Operators:​flet]] ((alpha (x y) (+ x y))) 
 +    (expand (alpha a b)))) 
 +<​r>​(ALPHA A B)
 +//​[[CL:​Glossary:​false]]//​ </r>
 +  ​
 +([[CL:​Special Operators:​let]] ((x ([[CL:​Functions:​list]] 1 2 3)))
 +  ([[CL:​Special Operators:​symbol-macrolet]] ((a ([[CL:​Functions:​first]] x))) 
 +    ([[CL:​Special Operators:​let]] ((a x)) 
 +      (expand a)))) 
 +<r>A
 +//​[[CL:​Glossary:​false]]//</​r>​
 +</​blockquote>​
 +
 +====Affected By====
 +**[[CL:​Macros:​defmacro]]**,​ **[[CL:​Macros:​setf]]** of **[[CL:​Macros:​macro-function]]**,​ **[[CL:​Special Operators:​macrolet]]**,​ **[[CL:​Special Operators:​symbol-macrolet]]**
 +
 +====Exceptional Situations====
 +None.
 +
 +====See Also====
 +**[[CL:​Variables:​star-macroexpand-hook-star|Variable *MACROEXPAND-HOOK*]]**,​ **[[CL:​Macros:​defmacro|Macro DEFMACRO]]**,​ **[[CL:​Macros:​setf|Macro SETF]]** of **[[CL:​Macros:​macro-function|Macro MACRO-FUNCTION]]**,​ **[[CL:​Special Operators:​macrolet|Special Operator MACROLET]]**,​ **[[CL:​Special Operators:​symbol-macrolet|Special Operator SYMBOL-MACROLET]]**,​ {\secref\Evaluation}
 +
 +====Notes====
 +Neither **macroexpand** nor **macroexpand-1** makes any explicit attempt to expand //​[[CL:​Glossary:​macro form|macro forms]]// that are either //​[[CL:​Glossary:​subform|subforms]]//​ of the //form// or //​[[CL:​Glossary:​subform|subforms]]//​ of the //​expansion//​. Such expansion might occur implicitly, however, due to the semantics or implementation of the //​[[CL:​Glossary:​macro function]]//​.
 +
 +\issue{MACROEXPAND-RETURN-VALUE:​TRUE} \issue{FUNCTION-TYPE:​X3J13-MARCH-88} \issue{ISO-COMPATIBILITY:​ADD-SUBSTRATE}