> On Oct 3, 2017, at 5:21 PM, Alexis King <[email protected]> wrote:
> 
> I realized I probably also ought to post my workaround, which I use in
> Hackett: I just don’t use preserved syntax properties at all (only
> unpreserved ones). I found that sticking syntax objects in preserved
> syntax properties was unreliable, probably for the reasons Matthew
> mentioned in the aforementioned email thread.
> 
> Instead of using preserved syntax properties, I just read the property
> earlier, then embed its value (or an expression that produces its value)
> in the expanded syntax instead of reading/transferring it “just in
> time”. This avoids the need for properties to preserved in bytecode.
> What do I mean by this? Well, instead of expanding to something like
> this:
> 
>    #'(define-syntax x
>        (make-variable-like-transformer
>          (syntax-property #'x* 'prop (syntax-property #'y 'prop)))
> 
> ...where 'prop is preserved on #'y, I instead expand to something like
> this:
> 
>    #`(define-syntax x
>        (make-variable-like-transformer
>          (syntax-property
>           #'x* 'prop
>           (quote-syntax #,(syntax-property #'y 'prop))))
> 
> This way, the syntax property’s value is actually embedded in the fully
> expanded syntax as an expression, and the invocation of
> make-variable-like-transformer receives a “hardcoded” value. This means
> 'prop no longer needs to be preserved on #'y.
> 
> I managed to fix your example program with this technique. This changes
> the definitions of define-stuff and define-thing to the following:
> 
>    (define-syntax-parser define-stuff
>      [(_ name:id)
>       #:with name* ((make-syntax-introducer) #'name)
>       #'(begin
>           (define name* 'stuff)
>           (define-syntax name
>             (make-variable-like-transformer
>              (syntax-property #'name* 'prop #'name))))])
> 
>    (define-syntax-parser define-thing
>      [(_ name:id stuff:id)
>       #:with stuff* (local-expand #'stuff 'expression '())
>       #`(define-syntax name
>           (make-variable-like-transformer
>            (syntax-property
>             #''thing
>             'prop
>             (quote-syntax #,(syntax-property #'stuff* 'prop)))))])
> 
> Now, you might argue that this technique doesn’t apply in general, since
> it explicitly uses quote-syntax, which wouldn’t work for other things
> that can be put into preserved syntax properties. That’s true! In fact,
> I use prefab structures as my types in Hackett, so I needed to provide
> a replacement for preserved properties containing prefab structures.
> Fortunately, it is trivial to produce an expression that evaluates to
> and value that is a valid preservable syntax property. The function
> Hackett uses looks like this:
> 
>    (define preservable-property->expression
>      (match-lambda
>        [(and (app prefab-struct-key (? values prefab-key))
>              (app struct->vector (vector _ fields ...)))
>         #`(make-prefab-struct
>            '#,prefab-key
>            #,@(map preservable-property->expression fields))]
>        [(? list? lst)
>         #`(list #,@(map preservable-property->expression lst))]
>        [(cons a b)
>         #`(cons #,(preservable-property->expression a)
>                 #,(preservable-property->expression b))]
>        [(? syntax? stx)
>         #`(quote-syntax #,stx)]
>        [(and (or (? boolean?) (? symbol?) (? number?) (? char?)
>                  (? string?) (? bytes?) (? regexp?))
>              datum)
>         #`(quote #,datum)]
>        [other
>         (error 'preservable-property->expression
>                "non-preservable syntax property\n  value: ~e"
>                other)]))
> 
> To use this function, just replace the hardcoded use of quote-syntax to
> an evaluated use of preservable-property->expression. Using this
> function, define-thing looks like this:
> 
>    (define-syntax-parser define-thing
>      [(_ name:id stuff:id)
>       #:with stuff* (local-expand #'stuff 'expression '())
>       #`(define-syntax name
>           (make-variable-like-transformer
>            (syntax-property
>             #''thing
>             'prop
>             #,(preservable-property->expression
>                (syntax-property #'stuff* 'prop)))))])
> 
> This wouldn’t work for any use of preservable syntax properties, since
> it relies on the particular interplay of make-variable-like-transformer
> and local-expand that Turnstile uses. However, I think it will work for
> your case.
> 
> Alexis

Oh, thanks for the advice!

I don't have time to look at it now but later this evening or tomorrow I'll try 
to apply this.

Alex Knauth

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/6D5978B2-C1D6-494E-A7D2-84F2DEFD5740%40knauth.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to