1
0
Fork 0
cl-sites/guile.html_node/Syntax-Parameters.html

151 lines
7.3 KiB
HTML
Raw Normal View History

2024-12-17 12:49:28 +01:00
<!DOCTYPE html>
<html>
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- This manual documents Guile version 3.0.10.
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
Inc.
Copyright (C) 2021 Maxime Devos
Copyright (C) 2024 Tomas Volf
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the section entitled "GNU Free
Documentation License." -->
<title>Syntax Parameters (Guile Reference Manual)</title>
<meta name="description" content="Syntax Parameters (Guile Reference Manual)">
<meta name="keywords" content="Syntax Parameters (Guile Reference Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content=".texi2any-real">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Concept-Index.html" rel="index" title="Concept Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Macros.html" rel="up" title="Macros">
<link href="Eval-When.html" rel="next" title="Eval When">
<link href="Identifier-Macros.html" rel="prev" title="Identifier Macros">
<style type="text/css">
<!--
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
div.example {margin-left: 3.2em}
span:hover a.copiable-link {visibility: visible}
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
-->
</style>
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
</head>
<body lang="en">
<div class="subsection-level-extent" id="Syntax-Parameters">
<div class="nav-panel">
<p>
Next: <a href="Eval-When.html" accesskey="n" rel="next">Eval-when</a>, Previous: <a href="Identifier-Macros.html" accesskey="p" rel="prev">Identifier Macros</a>, Up: <a href="Macros.html" accesskey="u" rel="up">Macros</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<h4 class="subsection" id="Syntax-Parameters-1"><span>6.8.7 Syntax Parameters<a class="copiable-link" href="#Syntax-Parameters-1"> &para;</a></span></h4>
<p>Syntax parameters<a class="footnote" id="DOCF16" href="#FOOT16"><sup>16</sup></a> are a
mechanism for rebinding a macro definition within the dynamic extent of
a macro expansion. This provides a convenient solution to one of the
most common types of unhygienic macro: those that introduce a unhygienic
binding each time the macro is used. Examples include a <code class="code">lambda</code>
form with a <code class="code">return</code> keyword, or class macros that introduce a
special <code class="code">self</code> binding.
</p>
<p>With syntax parameters, instead of introducing the binding
unhygienically each time, we instead create one binding for the keyword,
which we can then adjust later when we want the keyword to have a
different meaning. As no new bindings are introduced, hygiene is
preserved. This is similar to the dynamic binding mechanisms we have at
run-time (see <a class="pxref" href="SRFI_002d39.html">parameters</a>), except that the dynamic binding
only occurs during macro expansion. The code after macro expansion
remains lexically scoped.
</p>
<dl class="first-deffn">
<dt class="deffn" id="index-define_002dsyntax_002dparameter"><span class="category-def">Syntax: </span><span><strong class="def-name">define-syntax-parameter</strong> <var class="def-var-arguments">keyword transformer</var><a class="copiable-link" href="#index-define_002dsyntax_002dparameter"> &para;</a></span></dt>
<dd><p>Binds <var class="var">keyword</var> to the value obtained by evaluating
<var class="var">transformer</var>. The <var class="var">transformer</var> provides the default expansion
for the syntax parameter, and in the absence of
<code class="code">syntax-parameterize</code>, is functionally equivalent to
<code class="code">define-syntax</code>. Usually, you will just want to have the
<var class="var">transformer</var> throw a syntax error indicating that the <var class="var">keyword</var>
is supposed to be used in conjunction with another macro, for example:
</p><div class="example">
<pre class="example-preformatted">(define-syntax-parameter return
(lambda (stx)
(syntax-violation 'return &quot;return used outside of a lambda^&quot; stx)))
</pre></div>
</dd></dl>
<dl class="first-deffn">
<dt class="deffn" id="index-syntax_002dparameterize"><span class="category-def">Syntax: </span><span><strong class="def-name">syntax-parameterize</strong> <var class="def-var-arguments">((keyword transformer) &hellip;) exp &hellip;</var><a class="copiable-link" href="#index-syntax_002dparameterize"> &para;</a></span></dt>
<dd><p>Adjusts <var class="var">keyword</var> &hellip; to use the values obtained by evaluating
their <var class="var">transformer</var> &hellip;, in the expansion of the <var class="var">exp</var>
&hellip; forms. Each <var class="var">keyword</var> must be bound to a syntax-parameter.
<code class="code">syntax-parameterize</code> differs from <code class="code">let-syntax</code>, in that the
binding is not shadowed, but adjusted, and so uses of the keyword in the
expansion of <var class="var">exp</var> &hellip; use the new transformers. This is
somewhat similar to how <code class="code">parameterize</code> adjusts the values of
regular parameters, rather than creating new bindings.
</p>
<div class="example">
<pre class="example-preformatted">(define-syntax lambda^
(syntax-rules ()
[(lambda^ argument-list body body* ...)
(lambda argument-list
(call-with-current-continuation
(lambda (escape)
;; In the body we adjust the 'return' keyword so that calls
;; to 'return' are replaced with calls to the escape
;; continuation.
(syntax-parameterize ([return (syntax-rules ()
[(return vals (... ...))
(escape vals (... ...))])])
body body* ...))))]))
;; Now we can write functions that return early. Here, 'product' will
;; return immediately if it sees any 0 element.
(define product
(lambda^ (list)
(fold (lambda (n o)
(if (zero? n)
(return 0)
(* n o)))
1
list)))
</pre></div>
</dd></dl>
</div>
<div class="footnotes-segment">
<hr>
<h4 class="footnotes-heading">Footnotes</h4>
<h5 class="footnote-body-heading"><a id="FOOT16" href="#DOCF16">(16)</a></h5>
<p>Described in the paper <cite class="cite">Keeping it Clean
with Syntax Parameters</cite> by Barzilay, Culpepper and Flatt.</p>
</div>
<hr>
<div class="nav-panel">
<p>
Next: <a href="Eval-When.html">Eval-when</a>, Previous: <a href="Identifier-Macros.html">Identifier Macros</a>, Up: <a href="Macros.html">Macros</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>