[racket] Again on bindings visibility in eval

From: Markku Rontu (markku.rontu at iki.fi)
Date: Thu Jul 14 14:49:27 EDT 2011

Hi again,

On Thu, Jul 14, 2011 at 6:23 PM, Eli Barzilay <eli at barzilay.org> wrote:

> Two hours ago, Markku Rontu wrote:
> > > this is not really true. The domain specific languages of
> > > syntax-rules and syntax-case macro transformers exist purely for
> > > your convenience.  You can always manipulate syntax objects
> > > directly, all the necessary procedures are available and
> > > documented in section 11 of the Racket reference manual.
> > >
> > I'm sure the section 11 does go through the relevant issues, but
> > doesn't feel like a good introduction to the matter.
>
> It's a reference, it's not supposed to be an introduction.  For a more
> in-depth introduction than my blog post, see the chapter in the racket
> guide:
>
>  http://docs.racket-lang.org/guide/macros.html
>
>
I feel reference material tends to require some other material as support.
Your blog posting was a good start. Maybe it's wishful thinking, but many
other languages have a lot of screencasts and talks online that I can watch.
And also articles where I can see how people build stuff from scratch using
their favourite environment. That's really cool stuff and I wish there was
more on Racket as well.


> > I can theorise that I can manipulate these syntax objects with plain
> > old functions but nowhere does it seem to show a complete useful
> > case. What I'm missing is an example that contains all the bits but
> > that is not as complicated like the Racket sources themselves. Maybe
> > I just didn't find it?
>
> Note that usually you start with `syntax-rules' because it's simple
> and covers many cases.  But running straight to the macro system
> bowels can be confusing since it's not just "lists and symbols".  So
> the main tool that is used is `syntax-case', which can be used in a
> very similar way to `syntax-rules':
>
>  (define def
>    (syntax-rules (=)
>      [(def x = y) (define x y)]))
>
> gets translated to
>
>  (define (def stx)
>    (syntax-case stx (=)
>      [(def x = y) #'(define x y)]))
>
> It looks similar, but there are important differences:
>
> * `syntax-rules' is creating a macro function (=> it is itself a
>  macro) for you, abstracting all of the details out.  The translation
>  defines `def' as a function directly -- se we have a name for the
>  input syntax, `stx' is often used by convention.
>
> * We then use `syntax-case' which has the same kind of pattern
>  language you know from `syntax-rules', but it needs to have its
>  input specified directly.  It's common to pass `stx', the input to
>  the macro, but you can really give it anything you want.
>
> * And the most important change is that #' in the result.  With
>  `syntax-rules', the results are actually templates for plugging
>  pattern variables in.  But since we're writing plain racket code
>  here, the results can be any racket expression.  In this case, I use
>  #'(define x y) which is actually short for (syntax (define x y)).
>  This `syntax' thing is very similar to `quote', or actually more
>  like a kind of a quasiquote since pattern matched variables are
>  plugged into it -- so it's not really `x' and `y' that will be in
>  the result, it will instead be what the `x' and `y' variables
>  matched over when `stx' was fed into `syntax-case'.
>
> Again, see that blog post for an introduction that explains more from
> this POV.
>
> (This kind of explanations were also made countless times; it's easy
> to fall into the syntax-rules-only trap though.)
>
>
Fortunately, I didn't fall for that one. I've been using syntax-case
successfully for a long time because I quite soon needed to start breaking
hygiene. I mostly write macros as sugar for various DSLs. There I need to
often introduce new variables and avoid repetition.


>
> > It's simple, it's been explained countless times, it works in many
> > cases.
>
> No, it's broken in pretty much all cases.  Give me a single symbolic
> macro and I'll show you how it's broken.  (And point out how CL
> bypasses the problem...)
>
>
I think it's a bit disingenuous to say they are broken. People made
successful systems using their simple but broken tools, yes? People are
making successful systems in crippled languages such as Java and CL. And
some people even like it :-) Sure they can only build a limited thing with
the broken tool, but if you stay within its limits it doesn't matter, does
it? Nobody is trying to implement Typed Clojure on top of the macro system,
I hope :-) But as syntactic sugar for a DSL, where's the big problem that
makes it entirely broken?

>From a theoretical point of view, I think you are absolutely correct that
the symbolic macros are broken. From a practical point of view, you can
prove Racket macro superiority only by implementing superior systems and
showing in practice that the choices you made were superior.

-Markku


> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110714/9ac2be5c/attachment.html>

Posted on the users mailing list.