[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Syntax Parameters documentation for guile

From: Eli Barzilay
Subject: Re: Syntax Parameters documentation for guile
Date: Sat, 31 Dec 2011 02:44:53 -0500

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

> ** 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:
                             Maze is Life!

reply via email to

[Prev in Thread] Current Thread [Next in Thread]