[racket-dev] syntax-property guards? (was: Re: The Stepper strikes again)

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Aug 13 12:20:03 EDT 2011

An hour ago, John Clements wrote:
> Adding dev to followups, hope that's okay with all three of you.
> On Aug 12, 2011, at 7:15 PM, Eli Barzilay wrote:
> > The stepper has some function that annotates syntaxes with a
> > stepper specific value.  Stephen wanted to use this function but
> > couldn't because there was a dependency cycle.  So to "resolve"
> > it, he copied the function into `racket/private/promise' -- so now
> > there's a bit of stepper code that is duplicated in the core.  The
> > duplication is obvious problem #1.  The more subtle problem is the
> > existence of code in the core that has no meaning without the
> > stepper.
> I'm coming a bit late to this party, but I disagree with at least
> some of this.
> Actually, I want to disagree mostly with the "more subtle problem."

The problem is definitely there.  It starts with code that adds syntax
properties under a 'stepper-properties key, which is easy to
un-subtle.  If, for example, the stepper implementation changes to
have 'stepper-attributes holding a hash table, then that change would
lead to a change in the core -- showing the backward dependency.
Another aspect of this: the 'stepper-properties is now exposed to the
world, say that you want to protect it by using a unique key -- you
can't do that because it will re-introduce the dependency cycle.

> To start with, here's the basic motivating change to the code (lots
> like this):
> -  (defsubst (~and x ...) (~ (and (! x) ...)) ~and *and)
> +  (defsubst (~and x ...) (hidden-~ (and (hidden-! x) ...)) ~and *and)

I'm talking about `stepper-syntax-property' in
`racket/private/promise'.  How is this related?

> That is, the code for lazy racket contains the knowledge about which
> things should be hidden by the stepper.

Yes, that's also a bad dependency (lazy -> stepper), which we've
talked about in the past, but not as bad as duplicating code into the

> I would argue, in fact, that this is the *right* place for such
> knowledge.  In particular, suppose you're developing the lazy
> stepper, and you want to say, "this thing here is hidden."

(Then you add something generic that could be used by similar tools,
and you make it independent of some 'stepper-properties which also
involves documenting it in a way that is useful for similar tools.
However, at this level there is much more cyclic feedback between the
stepper and the lazy language, which makes it more fine to develop
them together until it's clear what the independent property should
look like -- and this is why this is all a parenthetical comment.)

> Thing two: I agree that the duplication of code is a terrible idea.
> However, I don't think that using syntax-track-origin is going to
> help at all.

I suggested something like `syntax-track-origin', which could be
useful by itself, independently of the stepper.  I don't think that
`syntax-track-origin' can be used by itself to resolve that.  (But
that's because of yet another problematic result of this dependency: I
have no idea what `unwind-promise' is supposed to do there...)

> The code that was duplicated here was basically a simple
> syntax-track-property, along with a dynamic check that ensures that
> the specified value is a legal one.  It's this dynamic check that's
> the added value, and I think that the choice between
> syntax-track-origin and syntax-property is orthogonal.

(Yeah, that looks like you're talking about that
`stepper-hide-operator', in the lazy language.)

> Basically, what we really want is a way to register a guard for
> particular syntax-property keys, and thinking about this, I can
> imagine this being pretty widely useful. I suppose the hard part is
> deciding who's allowed to attach a guard to a particular value's use
> as a syntax-property key, without compromising security.

The easy to do this is to use existing tools: use a struct for the
property value or make the key a hidden value.  (But like I said
above, both will make the conceptual connection a concrete one.)

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

Posted on the dev mailing list.