[plt-scheme] exception in local variable access from augmented method

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Dec 6 13:38:59 EST 2008

At Sat, 6 Dec 2008 13:26:52 -0500 (EST), Dimitris Vyzovitis wrote:
> On Sat, 6 Dec 2008, Matthew Flatt wrote:
> 
> > At Sat, 6 Dec 2008 12:42:10 -0500 (EST), Dimitris Vyzovitis wrote:
> >>    (define-syntax (~set! stx)
> >>      (syntax-case stx ()
> >>        ((_ tgt v)
> >>         (and (identifier? #'tgt)
> >>              (set!-transformer? (syntax-local-value #'tgt (lambda () #f))))
> >>         ((set!-transformer-procedure (syntax-local-value #'tgt)) stx))
> >>
> >> [...]
> >>
> >>
> >> It seems the culprit here is the set! renaming breaking the transformer
> >> syntax-id-rules (they match with free-identifier=?, don't they?)
> >
> > Yes, that's right. The transformer procedure is expecting a syntax
> > object that matches
> >
> >    (set! id ....) ; where `set!' is free-identifier=? to the usual one
> >
> > but it's getting an object that matches
> >
> >    (~set! id ....) ; where `~set!' is not free-identifier=? to `set!'
> >
> > In other words, you're breaking a contract (that should be) on the
> > procedure of a `set!-transformer'.
> 
> So what is a custom set! expander to do here? It cannot judge smudge the 
> syntax to use the built-in set! by passing #'(set! tgt v), 

Yes, it should.

> since the 
> transformer may be from a context where set! is itself (the 
> custom expander) and/or does a recursive expansion.

No, `set!' transformers are called at the point where the normal `set!'
is expanded. If a different `set!' wants to cooperate with transformers
different from ones that expect `set!', then it should introduce its
own kind of transformer (e.g., `make-~set!-transformer').

> > For the particular transformer procedure inside the class system, since
> > the `set!' pattern doesn't match, the transformer assumes that it must
> > be getting a pattern of the form `(id ....)', and so it expands to a
> > procedure application.
> 
> So, why isn't this the fault of the class systems set!-transformer? 

Because it's intended to have a contract that allows only `set!' (the
usual one) expressions, applications of the transformer's identifier,
and the transformer's identifier by itself.

> It 
> lifts code out of user code, so by matching the builtin set! (and not 
> the context's set!) it changes the semantics of the lifted code. In a 
> sense it breaks a contract by not respecting the context specific set!
> [modulo the elusive 'set!-transformer contract']

Hopefully it's clearer now that a transformer created with
`make-set!-transformer' is intended (by the caller of
`make-set!-transformer) to work specifically with the usual `set!'. We
don't currently have anything like `make-set!-transformer' that is
intended to work with context-specific notions of `set!'.


Matthew



Posted on the users mailing list.