* Syntax Parameters documentation for guile
@ 2011-12-23 15:46 Ian Price
2011-12-31 7:44 ` Eli Barzilay
0 siblings, 1 reply; 11+ messages in thread
From: Ian Price @ 2011-12-23 15:46 UTC (permalink / raw)
To: Guile Mailing List; +Cc: Eli Barzilay
Hello guilers,
I've taken the liberty of writing documentation for the syntax
parameters that were added to master a short while back. Comments kindly
requested. It is in org mode format, as I do not know texinfo at this
moment, but I will look into that shortly. It is also missing an
example, but I have to go and buy one last Christmas present, and will
do it this evening :).
Eli,
I'd especially appreciate it if you could clear up any misconceptions I
may have, or may be unintentionally imparting on others.
* Syntax Parameters
Syntax parameters[fn:1] are a mechanism for rebinding a macro definition
within the dynamic extent of a macro expansion. It provides a
convenient solution to one of the most common types of unhygienic
macro: those that introduce a special binding each time the macro is
used. Examples include an 'if' form that binds the result of the test
to an 'it' binding, or class macros that introduce a special 'self'
binding.
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 like parameters[fn:2] or fluids[fn:3].
** define-syntax-parameter keyword transformer [syntax]
Binds keyword to the value obtained by evaluating transformer as a
syntax-parameter. The transformer provides the default expansion for
the syntax parameter, and in the absence of syntax-parameterize, is
functionally equivalent to define-syntax.
** syntax-parameterize ((keyword transformer) ...) exp ... [syntax]
(note, each keyword must be bound to a syntax-parameter
Adjusts each of the keywords to use the value obtained by evaluating
their respective transformer, in the expansion of the exp forms. It
differs from let-syntax, in that the binding is not shadowed, but
adjusted, and so uses of the keyword in the expansion of exp forms use
the new transformers.
** TODO example
if it, loop escape?, class?
* Footnotes
[fn:1] Eli Barzilay, Ryan Culpepper and Matthew Flatt. Keeping it
Clean with Syntax Parameters. In Proc. Workshop on Scheme and
Functional Programming, October 2011.
[fn:2] Marc Feeley. SRFI 39: Parameter objects, 2003.
http://srfi.schemers.org/srfi-39/.
[fn:3] https://www.gnu.org/software/guile/manual/guile.html#Fluids-and-Dynamic-States
--
Ian Price
"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2011-12-23 15:46 Syntax Parameters documentation for guile Ian Price
@ 2011-12-31 7:44 ` Eli Barzilay
2012-01-03 23:04 ` Ian Price
0 siblings, 1 reply; 11+ messages in thread
From: Eli Barzilay @ 2011-12-31 7:44 UTC (permalink / raw)
To: Ian Price; +Cc: Guile Mailing List
More than a week ago, Ian Price wrote:
>
> Eli,
> I'd especially appreciate it if you could clear up any misconceptions I
> may have, or may be unintentionally imparting on others.
(And that I'm kind of on the list I can reply...)
> * Syntax Parameters
>
> Syntax parameters[fn:1] are a mechanism for rebinding a macro
> definition within the dynamic extent of a macro expansion. It
> provides a convenient solution to one of the most common types of
> unhygienic macro: those that introduce a special binding each time
I'd explicitly say "unhygienic" here rather than "special".
> the macro is used. Examples include an 'if' form that binds the
> result of the test to an 'it' binding, or class macros that
> introduce a special 'self' binding.
The `abort' example is also popular, probably even more than `it'. I
think that there are practical uses of that (eg, a function with a
`return' keyword), whereas anaphoric conditionals are more of an
academic exercise that I don't think gets used in practice (at least
in Schemes).
[As a sidenote, when I worked on that paper I've asked our local Perl
guru about the problem of shadowing the implicit `it' in Perl -- he
said that in practice it's considered bad style to use it in perl
code, and referred me to some book that talks about the pitfalls of
using it... I found it amusing that this perl-ism has become such a
popular example for unhygienic macros where perl hackers actually try
to avoid it.]
> 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 like parameters[fn:2] or fluids[fn:3].
An important note to add here is that there is no "dynamic scope" in
the usual sense here -- it's rather a dynamic scope during macro
expansion, and for macro-bound identifiers. The resulting expanded
code is of course as lexical as always. (We've had some discussions
at #scheme where this was a confusing point.)
> ** define-syntax-parameter keyword transformer [syntax]
> Binds keyword to the value obtained by evaluating transformer as a
> syntax-parameter.
The keyword is bound to the value of the `transformer' expression.
(Evaluated at the syntax level, in Racket's case, I don't know if
Guile has separate phases yet...) It's not evaluated as a syntax
parameter, just like parameters.
> The transformer provides the default expansion for the syntax
> parameter, and in the absence of syntax-parameterize, is
> functionally equivalent to define-syntax.
A good note to add here is that it is usually bound to a transformer
that throws a syntax error like "`foo' must be used inside a `bar'".
It immediately clarifies the use of syntax parameters in the common
case.
> ** syntax-parameterize ((keyword transformer) ...) exp ... [syntax]
> (note, each keyword must be bound to a syntax-parameter
>
> Adjusts each of the keywords to use the value obtained by evaluating
> their respective transformer, in the expansion of the exp forms. It
> differs from let-syntax, in that the binding is not shadowed, but
> adjusted, and so uses of the keyword in the expansion of exp forms
> use the new transformers.
A possibly useful analogy is with `fluid-let' which doesn't create new
bindings, but rather `set!'s them. But IMO `fluid-let' should die, so
using parameters is a better example...
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2011-12-31 7:44 ` Eli Barzilay
@ 2012-01-03 23:04 ` Ian Price
2012-01-04 0:33 ` Eli Barzilay
0 siblings, 1 reply; 11+ messages in thread
From: Ian Price @ 2012-01-03 23:04 UTC (permalink / raw)
To: Eli Barzilay; +Cc: Guile Mailing List
Eli Barzilay <eli@barzilay.org> writes:
>> Syntax parameters[fn:1] are a mechanism for rebinding a macro
>> definition within the dynamic extent of a macro expansion. It
>> provides a convenient solution to one of the most common types of
>> unhygienic macro: those that introduce a special binding each time
>
> I'd explicitly say "unhygienic" here rather than "special".
Good point, I've changed it.
>> the macro is used. Examples include an 'if' form that binds the
>> result of the test to an 'it' binding, or class macros that
>> introduce a special 'self' binding.
>
> The `abort' example is also popular, probably even more than `it'. I
> think that there are practical uses of that (eg, a function with a
> `return' keyword), whereas anaphoric conditionals are more of an
> academic exercise that I don't think gets used in practice (at least
> in Schemes).
I mentioned it mostly because it is a traditional example, but I've
swapped it for the lambda with return.
I'm not sure how popular aif is in general (I prefer a clojure style
if-let), but I do know it is in the popular miscmacros egg for chicken.
>> is preserved. This is similar to the dynamic binding mechanisms we
>> have at run-time like parameters[fn:2] or fluids[fn:3].
>
> An important note to add here is that there is no "dynamic scope" in
> the usual sense here -- it's rather a dynamic scope during macro
> expansion, and for macro-bound identifiers. The resulting expanded
> code is of course as lexical as always. (We've had some discussions
> at #scheme where this was a confusing point.)
Ok, I've cleared this up.
>> ** define-syntax-parameter keyword transformer [syntax]
>> Binds keyword to the value obtained by evaluating transformer as a
>> syntax-parameter.
>
> The keyword is bound to the value of the `transformer' expression.
> (Evaluated at the syntax level, in Racket's case, I don't know if
> Guile has separate phases yet...) It's not evaluated as a syntax
> parameter, just like parameters.
This is a case of syntactic ambiguity in English, I meant it as
"Binds keyword to (the value obtained by evaluating transformer) as a
syntax-parameter."
I've just dropped the "as a syntax-parameter" part.
>> The transformer provides the default expansion for the syntax
>> parameter, and in the absence of syntax-parameterize, is
>> functionally equivalent to define-syntax.
>
> A good note to add here is that it is usually bound to a transformer
> that throws a syntax error like "`foo' must be used inside a `bar'".
> It immediately clarifies the use of syntax parameters in the common
> case.
Done. I've also added an example that does this.
>> ** syntax-parameterize ((keyword transformer) ...) exp ... [syntax]
>> (note, each keyword must be bound to a syntax-parameter
>>
>> Adjusts each of the keywords to use the value obtained by evaluating
>> their respective transformer, in the expansion of the exp forms. It
>> differs from let-syntax, in that the binding is not shadowed, but
>> adjusted, and so uses of the keyword in the expansion of exp forms
>> use the new transformers.
>
> A possibly useful analogy is with `fluid-let' which doesn't create new
> bindings, but rather `set!'s them. But IMO `fluid-let' should die, so
> using parameters is a better example...
I've made the comparison with regular parameters more explicit.
Thanks a lot, Eli.
In case anyone else has any comments, the modified version is included
below. Now I'm off to learn about texinfo :)
* Syntax Parameters
Syntax parameters[fn:1] are a mechanism for rebinding a macro
definition within the dynamic extent of a macro expansion. It 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 'lambda' form with a 'return' keyword , or
class macros that introduce a special 'self' binding.
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 like parameters[fn:2] or fluids[fn:3], except that the
dynamic binding only occurs during macro expansion. The code after
macro expansion remains lexically scoped.
** define-syntax-parameter keyword transformer [syntax]
Binds keyword to the value obtained by evaluating transformer. The
transformer provides the default expansion for the syntax parameter,
and in the absence of syntax-parameterize, is functionally equivalent
to define-syntax. Usually, you will just want to have the transformer
throw a syntax error indicating that the keyword is supposed to be
used in conjunction with another macro. (see example)
** syntax-parameterize ((keyword transformer) ...) exp ... [syntax]
Adjusts each of the keywords to use the value obtained by evaluating
their respective transformer, in the expansion of the exp forms. Each
keyword must be bound to a syntax-parameter. syntax-parameterize
differs from let-syntax, in that the binding is not shadowed, but
adjusted, and so uses of the keyword in the expansion of exp forms use
the new transformers. This is somewhat similar to how parameterize
adjusts the values of regular parameters, rather than creating new
bindings.
** example
A short example, showing how you can use syntax parameters to create a
variant of 'lambda' that allows early return from the function via the
'return' keyword.
#+begin_src scheme
(define-syntax-parameter return
;; by default we bind 'return' to a macro that merely raises a syntax error
(lambda (stx)
(syntax-violation 'return "return used outside of a lambda^" stx)))
(define-syntax lambda^
(syntax-rules ()
[(lambda^ argument-list body bodies ...)
(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
bodies ...))))]))
;; 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)))
#+end_src
* Footnotes
[fn:1] Eli Barzilay, Ryan Culpepper and Matthew Flatt. Keeping it
Clean with Syntax Parameters. In Proc. Workshop on Scheme and
Functional Programming, October 2011.
[fn:2] Marc Feeley. SRFI 39: Parameter objects, 2003.
http://srfi.schemers.org/srfi-39/.
[fn:3] https://www.gnu.org/software/guile/manual/guile.html#Fluids-and-Dynamic-States
--
Ian Price
"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-03 23:04 ` Ian Price
@ 2012-01-04 0:33 ` Eli Barzilay
2012-01-06 18:47 ` Andy Wingo
0 siblings, 1 reply; 11+ messages in thread
From: Eli Barzilay @ 2012-01-04 0:33 UTC (permalink / raw)
To: Ian Price; +Cc: Guile Mailing List
An hour and a half ago, Ian Price wrote:
> Eli Barzilay <eli@barzilay.org> writes:
>
> >> the macro is used. Examples include an 'if' form that binds the
> >> result of the test to an 'it' binding, or class macros that
> >> introduce a special 'self' binding.
> >
> > The `abort' example is also popular, probably even more than `it'.
> > I think that there are practical uses of that (eg, a function with
> > a `return' keyword), whereas anaphoric conditionals are more of an
> > academic exercise that I don't think gets used in practice (at
> > least in Schemes).
> I mentioned it mostly because it is a traditional example, but I've
> swapped it for the lambda with return.
>
> I'm not sure how popular aif is in general (I prefer a clojure style
> if-let), but I do know it is in the popular miscmacros egg for
> chicken.
(I suspect that its popularity comes from these examples...)
> >> ** define-syntax-parameter keyword transformer [syntax]
> >> Binds keyword to the value obtained by evaluating transformer as
> >> a syntax-parameter.
> >
> > The keyword is bound to the value of the `transformer' expression.
> > (Evaluated at the syntax level, in Racket's case, I don't know if
> > Guile has separate phases yet...) It's not evaluated as a syntax
> > parameter, just like parameters.
> This is a case of syntactic ambiguity in English, I meant it as
> "Binds keyword to (the value obtained by evaluating transformer) as a
> syntax-parameter."
Yeah, I figured that. It's generally pretty hard to describe such
things accurately because of natural language conventions. I run into
such problems in my course very frequently.
> I've just dropped the "as a syntax-parameter" part.
That works fine.
> In case anyone else has any comments, the modified version is
> included below. Now I'm off to learn about texinfo :)
(Ugh, medieval programming...)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-04 0:33 ` Eli Barzilay
@ 2012-01-06 18:47 ` Andy Wingo
2012-01-07 2:05 ` Ian Price
2012-01-07 2:30 ` Eli Barzilay
0 siblings, 2 replies; 11+ messages in thread
From: Andy Wingo @ 2012-01-06 18:47 UTC (permalink / raw)
To: Ian Price; +Cc: Eli Barzilay, Guile Mailing List
Hi Ian,
Thanks for writing these docs, and thanks to Eli for commenting on them.
I have pushed a couple commits to Guile that provide
define-syntax-parameter and syntax-parameterize on the stable-2.0
branch, in addition to the support that was already there on master.
Unlike the implementation on master, which correctly restricts
syntax-parameterize to operate only on syntax parameters, stable-2.0's
syntax-parameterize works on all bindings, for back compatibility with
`fluid-let-syntax'.
The point, of course, is to allow Guile 2.0 code to use the syntax
parameter API, even if the implementation is only fully landed in Guile
2.2. That way when users upgrade, they don't have to change their code.
I have deprecated fluid-let-syntax, so let's please not speak of it any
more :-)
On Wed 04 Jan 2012 01:33, Eli Barzilay <eli@barzilay.org> writes:
>> In case anyone else has any comments, the modified version is
>> included below. Now I'm off to learn about texinfo :)
>
> (Ugh, medieval programming...)
Goes along with the "guild" stuff, I guess :)
Ian, just edit doc/ref/api-macros.texi. You don't need to know very
much in the way of formatting; just follow the examples there and you'll
be good.
Thanks again!
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-06 18:47 ` Andy Wingo
@ 2012-01-07 2:05 ` Ian Price
2012-01-07 17:37 ` Ian Price
2012-01-07 2:30 ` Eli Barzilay
1 sibling, 1 reply; 11+ messages in thread
From: Ian Price @ 2012-01-07 2:05 UTC (permalink / raw)
To: Andy Wingo; +Cc: Guile Mailing List
[-- Attachment #1: Type: text/plain, Size: 594 bytes --]
Andy Wingo <wingo@pobox.com> writes:
> I have pushed a couple commits to Guile that provide
> define-syntax-parameter and syntax-parameterize on the stable-2.0
> branch, in addition to the support that was already there on master.
Excellent
> Ian, just edit doc/ref/api-macros.texi. You don't need to know very
> much in the way of formatting; just follow the examples there and you'll
> be good.
Yes, dsmith and ludovic assured me as much on IRC :)
--
Ian Price
"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: documentation for syntax parameters --]
[-- Type: text/x-patch, Size: 4471 bytes --]
From 3d1426ec8c0b8f1b1524a87fdeb2d17a6580c928 Mon Sep 17 00:00:00 2001
From: Ian Price <ianprice90@googlemail.com>
Date: Sat, 7 Jan 2012 01:59:33 +0000
Subject: [PATCH] document syntax parameters
* doc/ref/api-macros.texi (Macros): Add subsection for "Syntax Parameters"
---
doc/ref/api-macros.texi | 76 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index 92816ad..7a15e82 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -40,6 +40,7 @@ languages}, or EDSLs.}.
* Syntax Case:: Procedural, hygienic macros.
* Defmacros:: Lisp-style macros.
* Identifier Macros:: Identifier macros.
+* Syntax Parameters:: Syntax Parameters
* Eval When:: Affecting the expand-time environment.
* Internal Macros:: Macros as first-class values.
@end menu
@@ -861,6 +862,81 @@ wrapping in @code{#'} syntax forms.
@end deffn
+@node Syntax Parameters
+@subsection Syntax Parameters
+
+Syntax parameters@footnote{Described in the paper @cite{Keeping it Clean with
+Syntax Parameters} by Barzilay, Culpepper and Flatt.} are a mechanism for rebinding a macro
+definition within the dynamic extent of a macro expansion. It 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{lambda} form with a @code{return} keyword, or
+class macros that introduce a special @code{self} binding.
+
+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 like @ref{SRFI-39, parameters} or
+@ref{Fluids and Dynamic States, fluids}, except that the dynamic
+binding only occurs during macro expansion. The code after macro
+expansion remains lexically scoped.
+
+@deffn {Syntax} define-syntax-parameter keyword transformer
+Binds @var{keyword} to the value obtained by evaluating @var{transformer}. The
+@var{transformer} provides the default expansion for the syntax parameter,
+and in the absence of @code{syntax-parameterize}, is functionally equivalent
+to @code{define-syntax}. Usually, you will just want to have the @var{transformer}
+throw a syntax error indicating that the @var{keyword} is supposed to be
+used in conjunction with another macro, for example:
+@example
+(define-syntax-parameter return
+ (lambda (stx)
+ (syntax-violation 'return "return used outside of a lambda^" stx)))
+@end example
+@end deffn
+
+@deffn {Syntax} syntax-parameterize ((keyword transformer) @dots) exp @dots
+Adjusts @var{keyword} @dots to use the values obtained by evaluating
+their @var{transformer} @dots, in the expansion of the @var{exp} @dots
+forms. Each @var{keyword} must be bound to a
+syntax-parameter. @code{syntax-parameterize} differs from
+@code{let-syntax}, in that the binding is not shadowed, but adjusted,
+and so uses of the keyword in the expansion of exp forms use the new
+transformers. This is somewhatsimilar to how @code{parameterize}
+adjusts the values of regular parameters, rather than creating new
+bindings.
+
+@example
+(define-syntax lambda^
+ (syntax-rules ()
+ [(lambda^ argument-list body bodies ...)
+ (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
+ bodies ...))))]))
+
+;; 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)))
+@end example
+@end deffn
+
+
@node Eval When
@subsection Eval-when
--
1.7.7.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-06 18:47 ` Andy Wingo
2012-01-07 2:05 ` Ian Price
@ 2012-01-07 2:30 ` Eli Barzilay
1 sibling, 0 replies; 11+ messages in thread
From: Eli Barzilay @ 2012-01-07 2:30 UTC (permalink / raw)
To: Andy Wingo; +Cc: Ian Price, Guile Mailing List
8 hours ago, Andy Wingo wrote:
> On Wed 04 Jan 2012 01:33, Eli Barzilay <eli@barzilay.org> writes:
>
> > (Ugh, medieval programming...)
>
> Goes along with the "guild" stuff, I guess :)
(That was a scribble hint...)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-07 2:05 ` Ian Price
@ 2012-01-07 17:37 ` Ian Price
2012-01-08 0:06 ` Andy Wingo
0 siblings, 1 reply; 11+ messages in thread
From: Ian Price @ 2012-01-07 17:37 UTC (permalink / raw)
To: Andy Wingo; +Cc: Guile Mailing List
[-- Attachment #1: Type: text/plain, Size: 60 bytes --]
slight mistake in the last one, So I've sent another patch
[-- Attachment #2: ~/src/guile/0001-document-syntax-parameters.patch --]
[-- Type: message/external-body, Size: 104 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-07 17:37 ` Ian Price
@ 2012-01-08 0:06 ` Andy Wingo
2012-01-08 2:39 ` Ian Price
0 siblings, 1 reply; 11+ messages in thread
From: Andy Wingo @ 2012-01-08 0:06 UTC (permalink / raw)
To: Ian Price; +Cc: Guile Mailing List
On Sat 07 Jan 2012 18:37, Ian Price <ianprice90@googlemail.com> writes:
> slight mistake in the last one, So I've sent another patch
Sorry for being an idiot, but I'm not able to download this one. Can
you send it again as a plaintext attachment?
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-08 0:06 ` Andy Wingo
@ 2012-01-08 2:39 ` Ian Price
2012-01-08 13:47 ` Andy Wingo
0 siblings, 1 reply; 11+ messages in thread
From: Ian Price @ 2012-01-08 2:39 UTC (permalink / raw)
To: Andy Wingo; +Cc: Guile Mailing List
[-- Attachment #1: Type: text/plain, Size: 363 bytes --]
Andy Wingo <wingo@pobox.com> writes:
> On Sat 07 Jan 2012 18:37, Ian Price <ianprice90@googlemail.com> writes:
>
>> slight mistake in the last one, So I've sent another patch
>
> Sorry for being an idiot, but I'm not able to download this one. Can
> you send it again as a plaintext attachment?
I thought I had, but it looks like I'd made a mistake on my end.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: syntax parameters documentation --]
[-- Type: text/x-patch, Size: 4481 bytes --]
From b7d764179d5546698617993e5a648d6c1393b5c0 Mon Sep 17 00:00:00 2001
From: Ian Price <ianprice90@googlemail.com>
Date: Sat, 7 Jan 2012 01:59:33 +0000
Subject: [PATCH] document syntax parameters
* doc/ref/api-macros.texi (Macros): Add subsection for "Syntax Parameters"
---
doc/ref/api-macros.texi | 76 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index 92816ad..7ff5bf9 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -40,6 +40,7 @@ languages}, or EDSLs.}.
* Syntax Case:: Procedural, hygienic macros.
* Defmacros:: Lisp-style macros.
* Identifier Macros:: Identifier macros.
+* Syntax Parameters:: Syntax Parameters
* Eval When:: Affecting the expand-time environment.
* Internal Macros:: Macros as first-class values.
@end menu
@@ -861,6 +862,81 @@ wrapping in @code{#'} syntax forms.
@end deffn
+@node Syntax Parameters
+@subsection Syntax Parameters
+
+Syntax parameters@footnote{Described in the paper @cite{Keeping it Clean with
+Syntax Parameters} by Barzilay, Culpepper and Flatt.} are a mechanism for rebinding a macro
+definition within the dynamic extent of a macro expansion. It 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{lambda} form with a @code{return} keyword, or
+class macros that introduce a special @code{self} binding.
+
+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 like @ref{SRFI-39, parameters} or
+@ref{Fluids and Dynamic States, fluids}, except that the dynamic
+binding only occurs during macro expansion. The code after macro
+expansion remains lexically scoped.
+
+@deffn {Syntax} define-syntax-parameter keyword transformer
+Binds @var{keyword} to the value obtained by evaluating @var{transformer}. The
+@var{transformer} provides the default expansion for the syntax parameter,
+and in the absence of @code{syntax-parameterize}, is functionally equivalent
+to @code{define-syntax}. Usually, you will just want to have the @var{transformer}
+throw a syntax error indicating that the @var{keyword} is supposed to be
+used in conjunction with another macro, for example:
+@example
+(define-syntax-parameter return
+ (lambda (stx)
+ (syntax-violation 'return "return used outside of a lambda^" stx)))
+@end example
+@end deffn
+
+@deffn {Syntax} syntax-parameterize ((keyword transformer) @dots{}) exp @dots{}
+Adjusts @var{keyword} @dots{} to use the values obtained by evaluating
+their @var{transformer} @dots{}, in the expansion of the @var{exp} @dots{}
+forms. Each @var{keyword} must be bound to a
+syntax-parameter. @code{syntax-parameterize} differs from
+@code{let-syntax}, in that the binding is not shadowed, but adjusted,
+and so uses of the keyword in the expansion of exp forms use the new
+transformers. This is somewhatsimilar to how @code{parameterize}
+adjusts the values of regular parameters, rather than creating new
+bindings.
+
+@example
+(define-syntax lambda^
+ (syntax-rules ()
+ [(lambda^ argument-list body bodies ...)
+ (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
+ bodies ...))))]))
+
+;; 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)))
+@end example
+@end deffn
+
+
@node Eval When
@subsection Eval-when
--
1.7.7.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: Syntax Parameters documentation for guile
2012-01-08 2:39 ` Ian Price
@ 2012-01-08 13:47 ` Andy Wingo
0 siblings, 0 replies; 11+ messages in thread
From: Andy Wingo @ 2012-01-08 13:47 UTC (permalink / raw)
To: Ian Price; +Cc: Guile Mailing List
On Sun 08 Jan 2012 03:39, Ian Price <ianprice90@googlemail.com> writes:
> From b7d764179d5546698617993e5a648d6c1393b5c0 Mon Sep 17 00:00:00 2001
> From: Ian Price <ianprice90@googlemail.com>
> Date: Sat, 7 Jan 2012 01:59:33 +0000
> Subject: [PATCH] document syntax parameters
>
> * doc/ref/api-macros.texi (Macros): Add subsection for "Syntax Parameters"
Applied, thanks!
I committed some additional edits. I wanted to point them out to you,
as you might be interested in the tao of texinfo:
> +definition within the dynamic extent of a macro expansion. It provides
We use two spaces after periods in the Guile manual.
> +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{lambda} form with a @code{return} keyword, or
> +class macros that introduce a special @code{self} binding.
And, we try to keep things wrapped to 72 columns. M-q in emacs will
refill a paragraph for you.
> +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 like @ref{SRFI-39, parameters} or
> +@ref{Fluids and Dynamic States, fluids}, except that the dynamic
@ref in mid-sentence doesn't look very nice in print output:
http://www.gnu.org/savannah-checkouts/gnu/texinfo/manual/texinfo/html_node/ref.html#ref
I changed this to be (@pxref{...}).
> + ;; in the body we adjust the 'return' keyword so that calls
> + ;; to 'return' are replaced with calls to the escape continuation
Unless it's an inline comment, it's best to make whole sentences.
Lovely example, by the way. Thanks for the docs!
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2012-01-08 13:47 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-23 15:46 Syntax Parameters documentation for guile Ian Price
2011-12-31 7:44 ` Eli Barzilay
2012-01-03 23:04 ` Ian Price
2012-01-04 0:33 ` Eli Barzilay
2012-01-06 18:47 ` Andy Wingo
2012-01-07 2:05 ` Ian Price
2012-01-07 17:37 ` Ian Price
2012-01-08 0:06 ` Andy Wingo
2012-01-08 2:39 ` Ian Price
2012-01-08 13:47 ` Andy Wingo
2012-01-07 2:30 ` Eli Barzilay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).