[racket-dev] generalized `begin-for-syntax'

From: Eli Barzilay (eli at barzilay.org)
Date: Thu Sep 8 19:19:14 EDT 2011

50 minutes ago, Matthew Flatt wrote:
> At Thu, 8 Sep 2011 17:48:46 -0400, Eli Barzilay wrote:
> > Does this mean that `define-for-syntax' becomes as deprecated as
> > `require-for-syntax' etc, right?
> At the moment, `define-for-syntax' seems like a more useful
> shorthand than `require-for-syntax', but maybe not if `for-syntax'
> works as `begin-for-syntax'.
> I changed the use of `define-for-syntax' in the Guide to
> `begin-for-syntax', though.

(Yeah, that's why I asked...)

> > Also, does `provide' work fine in a `begin-for-syntax'?
> Yes.

So, the last cute thing is if it were allowed in non-toplevel contexts
too, which is related to the below.

> > Assuming that it is, it could have been nice to have it called just
> > `for-syntax', since
> > 
> >   (for-syntax (require foo))
> > 
> > becomes equivalent to
> > 
> >   (require (for-syntax foo))
> Overloading `for-syntax' in that way reminds me of the `begin' pun
> (expression sequencing versus definition splicing).

(That's actually why I prefer getting rid of the `begin-' part, since
it sounds too much like the side-effect aspect, and not like the
splicing one.)

> But maybe this one is ok, because definitions and
> `require'/`provide' forms are completely distinct positions, unlike
> expressions and definition sequences.
> We'd have to keep `begin-for-syntax' for compatibility. Also, for
> layering reasons, I think it's best to keep `begin-for-syntax' as
> the core form.
> I'm ambivalent overall, so I'll wait for others to chime in.

Well, what I'd love to have (and have wanted for a *really* long time,
since more than a decade ago) is to "dump more" the `begin' aspect of
it.  Imagine that something like this worked:

  (for-syntax #'(+ 1 2))

then, the final step of making it all uniform is make `unsyntax' do
that when it's used outside of a `quasisyntax'...  Now you'd have a
choice between:

  (define-syntax foo ...)
  (foo 5)

which is doing some inter-phase magic, or a more explicit:

  #,(define foo ...)
  #,(foo #`5)

Here's some games I did with something like that back then.

  | ;; Constant definition
  | ,(define c 3)
  | (list ,c 5)
  | ;; Macro definition
  | ,(define inc! (lambda (x) `(set! ,x (+ ,x 1))))
  | ,(inc! `x)
  | ;; This applies the `macro' _function_ on some syntax
  | (,inc! `x)
  |   --> (set! x (+ x 1))
  | ;;*** Local macro
  | ,(let ((inc! (lambda (x) `(set! ,x (+ ,x 10)))))
  |    (inc! `x))
  | ;; Meta-meta-level simple game
  | ,,(define inc! (lambda (x) ``(set! ,,x (+ ,,x 1))))
  | (,,inc! ``x)
  |   --> `(set! ,`x (+ ,`x 1))
  | ,(,inc! ``x)
  |   --> (set! x (+ x 1))
  | ,,(inc! ``x)
  |   ; actually incrementing x
  | ;; The previous meta-meta macro
  | ,,(define make-inc-n
  |     (lambda (n)
  |       `(lambda (x)
  |          `(set! ,x (+ ,x ,,n)))))
  | ,(define inc3! ,(make-inc-n 3))

[I sent it to the scheme workshop; it got rejected because I didn't
say anything about hygiene -- but maybe now this becomes a more
obviously orthogonal issue...  What is relevant here, which I did in
my toy implementation, is having separate phases.  Later on I had
additional games where each phase could run in a different language.]

[So yeah, I'm very fun-biased about the whole thing.]

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.