> 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.
