179 lines
13 KiB
HTML
179 lines
13 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<title>CLiki: Issue DEFMACRO-VALUES</title>
|
||
|
<link rel="alternate" type="application/atom+xml" title="ATOM feed of edits to current article"
|
||
|
href="https://www.cliki.net/site/feed/article.atom?title=Issue%20DEFMACRO-VALUES">
|
||
|
<link rel="stylesheet" href="static/css/style.css">
|
||
|
<link rel="stylesheet" href="static/css/colorize.css">
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<span class="hidden">CLiki - Issue DEFMACRO-VALUES</span>
|
||
|
<div id="content"><div id="content-area"><div id="article-title">Issue DEFMACRO-VALUES</div><div id="article"><a href="Issue.html" class="category">Issue</a>: DEFMACRO-VALUES<p>Forum:<p>References: <a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmacro.html" class="hyperspec">DEFMACRO</a>, <a href="https://www.cliki.net/site/HyperSpec/Body/speope_fletcm_scm_macrolet.html" class="hyperspec">MACROLET</a>, <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a>,
|
||
|
<a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND-1</a>, <a href="https://www.cliki.net/site/HyperSpec/Body/acc_macro-function.html" class="hyperspec">MACRO-FUNCTION</a>, the Glossary definition for
|
||
|
<a href="http://www.cliki.net/site/HyperSpec/Body/glo_v.html#value">value</a>.<p>Category:<p>Edit history:
|
||
|
2005-09-11, Version 1 by Kalle Olavi Niemitalo<p>Status: For CLiki consideration<p><dl>
|
||
|
<dt>Problem Description:
|
||
|
</dt>
|
||
|
<dd>According to the description of <a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmacro.html" class="hyperspec">DEFMACRO</a>,
|
||
|
"the value of the last <i>form</i> executed is returned as the
|
||
|
expansion of the macro." The glossary definition of
|
||
|
<a href="http://www.cliki.net/site/HyperSpec/Body/glo_v.html#value">value</a>
|
||
|
(1. b.) indicates that this means the primary value; any further
|
||
|
values are ignored. But does this truncation occur as part of the
|
||
|
expansion function defined by DEFMACRO, or as part of the
|
||
|
macroexpansion process? This matters if the user calls the expansion
|
||
|
function directly, or if the user's <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a> cares.<p> This also concerns <a href="https://www.cliki.net/site/HyperSpec/Body/speope_fletcm_scm_macrolet.html" class="hyperspec">MACROLET</a>, which uses "the same format used
|
||
|
by <a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmacro.html" class="hyperspec">defmacro</a>."<p></dd>
|
||
|
<dt>Proposal (DEFMACRO-VALUES:PRIMARY):
|
||
|
</dt>
|
||
|
<dd>The expansion functions defined by DEFMACRO or MACROLET always return
|
||
|
exactly one value, even if the body attempts to return multiple values
|
||
|
(as the values of the last form, or by using <a href="https://www.cliki.net/site/HyperSpec/Body/speope_return-from.html" class="hyperspec">RETURN-FROM</a>).
|
||
|
With SETF <a href="https://www.cliki.net/site/HyperSpec/Body/acc_macro-function.html" class="hyperspec">MACRO-FUNCTION</a>, the user can specify a
|
||
|
macro function that returns multiple values; but only the primary value
|
||
|
matters when the macro function is being called by <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND</a>,
|
||
|
<a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND-1</a>, or whatever the implementation uses to expand
|
||
|
macros.<p> The function that is the value of <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a> is not
|
||
|
required to preserve multiple values returned by the macro function,
|
||
|
and it might not even see all the values if another hook has
|
||
|
interposed itself.<p></dd>
|
||
|
<dt>Rationale (DEFMACRO-VALUES:PRIMARY):
|
||
|
</dt>
|
||
|
<dd>According to the description of <a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmacro.html" class="hyperspec">DEFMACRO</a>,
|
||
|
"the expansion function returns a
|
||
|
<a href="http://www.cliki.net/site/HyperSpec/Body/glo_f.html#form">form</a>."
|
||
|
Make it behave that way.<p></dd>
|
||
|
<dt>Proposal (DEFMACRO-VALUES:ALL):
|
||
|
</dt>
|
||
|
<dd>The expansion functions defined by DEFMACRO or MACROLET return all the
|
||
|
values of the body, but only the primary value matters when the expansion
|
||
|
function is being called by <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND</a>, <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND-1</a>,
|
||
|
or whatever the implementation uses to expand macros.<p> The function that is the value of <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a> is not
|
||
|
required to preserve multiple values returned by the macro function,
|
||
|
and it might not even see all the values if another hook has
|
||
|
interposed itself.<p></dd>
|
||
|
<dt>Rationale (DEFMACRO-VALUES:ALL):
|
||
|
</dt>
|
||
|
<dd>This seems to be what the implementations do now, and is helpful if
|
||
|
users want to use MACROLET as a general way to add information to the
|
||
|
lexical environment.<p></dd>
|
||
|
<dt>Proposal (DEFMACRO-VALUES:EXPLICITLY-VAGUE):
|
||
|
</dt>
|
||
|
<dd>It is unspecified whether the expansion functions defined by
|
||
|
DEFMACRO or MACROLET return all the values of the body, or just the
|
||
|
primary value. With SETF <a href="https://www.cliki.net/site/HyperSpec/Body/acc_macro-function.html" class="hyperspec">MACRO-FUNCTION</a>, the user can
|
||
|
specify a macro function that returns multiple values. In any case,
|
||
|
only the primary value matters when the expansion function is being
|
||
|
called by <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND</a>, <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND-1</a>, or whatever
|
||
|
the implementation uses to expand macros.<p> The function that is the value of <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a> is not
|
||
|
required to preserve multiple values returned by the macro function,
|
||
|
and it might not even see all the values if another hook has
|
||
|
interposed itself.<p></dd>
|
||
|
<dt>Rationale (DEFMACRO-VALUES:EXPLICITLY-VAGUE):
|
||
|
</dt>
|
||
|
<dd>Clarify the spec without requiring implementations to change.<p></dd>
|
||
|
<dt>Proposal (DEFMACRO-VALUES:THROUGHOUT):
|
||
|
</dt>
|
||
|
<dd>The expansion functions defined by DEFMACRO and MACROLET return all the
|
||
|
values of the body, but only the primary value matters when the expansion
|
||
|
function is being called by <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND</a>, <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND-1</a>,
|
||
|
or whatever the implementation uses to expand macros.<p> The function that is the value of <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a> will see
|
||
|
all the values returned by the macro function, and must preserve
|
||
|
them. Because it cannot normally know how the extra values will be
|
||
|
used, it should pass them through unchanged.<p></dd>
|
||
|
<dt>Rationale (DEFMACRO-VALUES:THROUGHOUT):
|
||
|
</dt>
|
||
|
<dd>If users define macros that return multiple values, then the
|
||
|
implementation and user-defined hooks should propagate them as far as
|
||
|
possible, in case some hook somewhere knows what to do with them.
|
||
|
Admittedly, this is rather far-fetched: because <a href="https://www.cliki.net/site/HyperSpec/Body/fun_macroexpa_acroexpand-1.html" class="hyperspec">MACROEXPAND-1</a>
|
||
|
will discard the extra values anyway, users are unlikely to call it
|
||
|
on such macros, and then the value of <a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a> won't
|
||
|
get called either.<p></dd>
|
||
|
<dt>Test case:
|
||
|
</dt>
|
||
|
<dd></dd>
|
||
|
</dl><pre>
|
||
|
(defmacro foo ()
|
||
|
(values 1 2 3))
|
||
|
(multiple-value-list (funcall (macro-function 'foo) '(foo) nil))
|
||
|
;; returns (1) for DEFMACRO-VALUES:PRIMARY,
|
||
|
;; returns (1 2 3) for DEFMACRO-VALUES:ALL or DEFMACRO-VALUES:THROUGHOUT,
|
||
|
;; returns either for DEFMACRO-VALUES:EXPLICITLY-VAGUE.
|
||
|
|
||
|
(let ((*macroexpand-hook*
|
||
|
#'(lambda (function form env)
|
||
|
(let ((values (multiple-value-list (funcall function form env))))
|
||
|
(format *trace-output* "~&Values:~{ ~S~}~%" values)
|
||
|
(values-list values)))))
|
||
|
(macroexpand-1 '(foo)))
|
||
|
;; outputs "Values: 1" for DEFMACRO-VALUES:PRIMARY,
|
||
|
;; outputs "Values: 1 2 3" for DEFMACRO-VALUES:THROUGHOUT,
|
||
|
;; outputs either for DEFMACRO-VALUES:ALL or DEFMACRO-VALUES:EXPLICITLY-VAGUE,
|
||
|
;; always returns 1 and T.
|
||
|
</pre><p><dt>Rationale:
|
||
|
</dt><dd><p></dd><dt>Current practice:
|
||
|
</dt><dd>
|
||
|
<a href="SBCL.html" class="internal">SBCL</a> 0.9.3.51, <a href="CLISP.html" class="internal">CLISP</a> 2.34, and Allegro CL 6.2 seem to
|
||
|
implement DEFMACRO-VALUES:ALL.<p></dd><dt>Cost to Implementors:
|
||
|
</dt><dd>DEFMACRO-VALUES:EXPLICITLY-VAGUE is intended not to require any
|
||
|
changes in implementations.<p> It seems possible that all current implementations support
|
||
|
DEFMACRO-VALUES:ALL, in which case that would not require changes
|
||
|
either. Some implementations may currently support
|
||
|
DEFMACRO-VALUES:PRIMARY instead. Switching from either one to the
|
||
|
other would require some effort, and might make macros expand a
|
||
|
little slower.<p> DEFMACRO-VALUES:THROUGHOUT would additionally require implementors to
|
||
|
examine and correct all of the functions they place in
|
||
|
<a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a>.<p></dd><dt>Cost to Users:<p></dt><dd>DEFMACRO-VALUES:EXPLICITLY-VAGUE might make users' programs less
|
||
|
portable, if all current implementations support DEFMACRO-VALUES:ALL
|
||
|
and the programs have come to rely on that and some future implementation
|
||
|
chooses to behave like DEFMACRO-VALUES:PRIMARY instead.<p> If all current implementations support DEFMACRO-VALUES:ALL, then making
|
||
|
this official would not hurt users, but we don't know that yet.<p> Requiring DEFMACRO-VALUES:PRIMARY would break programs that haven't been
|
||
|
careful about portability.<p> DEFMACRO-VALUES:THROUGHOUT would additionally require users to
|
||
|
examine and correct all of the functions they place in
|
||
|
<a href="https://www.cliki.net/site/HyperSpec/Body/var_stmacroexpand-hookst.html" class="hyperspec">*MACROEXPAND-HOOK*</a>.<p></dd><dt>Cost of Non-Adoption:
|
||
|
</dt><dd>Unclear spec. Users don't know what they can rely on, and may
|
||
|
assume too much in programs intended to be portable.<p></dd><dt>Benefits:
|
||
|
</dt><dd><p></dd><dt>Aesthetics:
|
||
|
</dt><dd><p></dd><dt>Discussion:
|
||
|
</dt><dd><p></dd></div></div>
|
||
|
<div id="footer" class="buttonbar"><ul><li><a href="Issue DEFMACRO-VALUES.html">Current version</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/history?article=Issue%20DEFMACRO-VALUES">History</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/backlinks?article=Issue%20DEFMACRO-VALUES">Backlinks</a></li><li><a href="https://www.cliki.net/site/edit-article?title=Issue%20DEFMACRO-VALUES&from-revision=3722748800">Edit</a></li><li><a href="https://www.cliki.net/site/edit-article?create=t">Create</a></li></ul></div>
|
||
|
</div>
|
||
|
<div id="header-buttons" class="buttonbar">
|
||
|
<ul>
|
||
|
<li><a href="https://www.cliki.net/">Home</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/recent-changes">Recent Changes</a></li>
|
||
|
<li><a href="CLiki.html">About</a></li>
|
||
|
<li><a href="Text Formatting.html">Text Formatting</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/tools">Tools</a></li>
|
||
|
</ul>
|
||
|
<div id="search">
|
||
|
<form action="https://www.cliki.net/site/search">
|
||
|
<label for="search_query" class="hidden">Search CLiki</label>
|
||
|
<input type="text" name="query" id="search_query" value="" />
|
||
|
<input type="submit" value="search" />
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="pageheader">
|
||
|
<div id="header">
|
||
|
<span id="logo">CLiki</span>
|
||
|
<span id="slogan">the common lisp wiki</span>
|
||
|
<div id="login"><form method="post" action="https://www.cliki.net/site/login">
|
||
|
<label for="login_name" class="hidden">Account name</label>
|
||
|
<input type="text" name="name" id="login_name" class="login_input" />
|
||
|
<label for= "login_password" class="hidden">Password</label>
|
||
|
<input type="password" name="password" id="login_password" class="login_input" />
|
||
|
<input type="submit" name="login" value="login" id="login_submit" /><br />
|
||
|
<div id="register"><a href="https://www.cliki.net/site/register">register</a></div>
|
||
|
<input type="submit" name="reset-pw" value="reset password" id="reset_pw" />
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body></html>
|