See make-variable-like-transformer in the syntax/transformer library. It's
a more general version of your delegate-fvar.

Ryan


On Fri, Mar 11, 2022 at 9:35 AM Sorawee Porncharoenwase <
[email protected]> wrote:

> Off-topic, but FWIW, you need set! in the list of literals for syntax-case.
> Otherwise, you could have a spurious match.
>
> (define-syntax test
>   (make-set!-transformer
>    (λ (stx)
>      (syntax-case stx ()
>        [(set! id v)
>         #'(println '(set! id v))]))))
>
> (test 1 2) ;=> '(test 1 2)
> (set! test 3) ;=> '(set! test 3)
>
> (define-syntax test2
>   (make-set!-transformer
>    (λ (stx)
>      (syntax-case stx (set!)
>        [(set! id v)
>         #'(println '(set! id v))]))))
>
> #;(test2 1 2) ;=> bad syntax
> (set! test2 3) ;=> '(set! test2 3)
>
>
>
> On Thu, Mar 10, 2022 at 11:57 PM 'William J. Bowman' via Racket Developers
> <[email protected]> wrote:
>
>> shhyou helped me figure this out; it was really my fault, as I was
>> generating a new set!-transformer each time through the loop, instead of a
>> call to a single transformer.
>>
>>
>> https://gist.github.com/shhyou/ff5366e8469d4da8f54d262a52744f30#file-bind-it-rkt
>>
>> Fell in a standard macro trap.
>>
>> --
>> William J. Bowman
>>
>> On Thu, Mar 10, 2022 at 08:49:46PM -0800, 'William J. Bowman' via Racket
>> Developers wrote:
>> > I've extracted a piece of a language implementation here (also attached)
>> >   https://gist.github.com/wilbowma/87d7e18718e08968cc4b2d003efbff2b
>> >
>> > It provides two implementations of a little language that provides an
>> unbounded
>> > number of implicit global mutable variables.
>> > I decided to bind the first 1000 of them because I figure no user would
>> generate
>> > that many, instead of doing anything clever.
>> >
>> > One method uses `let-syntax` and implements these variables with set!
>> > transformers, and the other just binds the variables with `let`.
>> >
>> > It seems the version that uses `let-syntax` runs in time directly
>> proportional
>> > to the number of these variables I decide to bind, i.e., the number of
>> macros I
>> > introduce via `let-syntax`; about 1ms per variable bound, regardless of
>> whether
>> > the macros are ever used.
>> >
>> > This behaviour surprised me a lot. Is this expected?
>> >
>> > --
>> > William J. Bowman
>> >
>> > --
>> > 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 view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-dev/YirU6gt5MxSnLcvf%40williamjbowman.com
>> .
>>
>> > #lang racket
>> > (require (for-syntax racket/syntax))
>> >
>> > #|
>> > 1,000 fvars; let-syntax implementation
>> > cpu time: 1162 real time: 1165 gc time: 156
>> >
>> > 10,000 fvars; let-syntax implementation
>> > cpu time: 10928 real time: 10964 gc time: 1374
>> >
>> > 1,000 fvars; let implementation
>> > cpu time: 20 real time: 20 gc time: 3
>> >
>> > 10,000 fvars; let implementation
>> > cpu time: 225 real time: 225 gc time: 54
>> > |#
>> >
>> > (begin-for-syntax
>> >   (define current-fvars (make-parameter 10000))
>> >
>> >   (define (bind-fvars s n tail)
>> >     #`(let-syntax
>> >           #,(for/list ([i (in-range 0 n)])
>> >               (with-syntax ([fvar (syntax-local-introduce (format-id #f
>> "fv~a" i))]
>> >                             [offset i]
>> >                             [stack s])
>> >                 #`[fvar (make-set!-transformer
>> >                          (lambda (stx)
>> >                            (syntax-case stx ()
>> >                              [(set! id v)
>> >                               #`(vector-set! stack offset v)]
>> >                              [id (identifier? #'id)
>> >                                  #`(vector-ref stack offset)])))]))
>> >         #,tail)))
>> >
>> > (define-syntax (my-module stx)
>> >   (syntax-case stx ()
>> >     [(_ e ...)
>> >      (with-syntax ([s #'stack])
>> >        #`(let ([s (make-vector #,(current-fvars) (void))])
>> >            #,(bind-fvars #'s (current-fvars) #`(begin e ...))))]))
>> >
>> > (define-namespace-anchor a)
>> >
>> > (displayln "1,000 fvars; let-syntax implementation")
>> >
>> > (time
>> >  (eval
>> >   '(begin
>> >      (begin-for-syntax
>> >        (current-fvars 1000))
>> >      (my-module
>> >       (set! fv0 8)
>> >       (set! fv1 8)
>> >       (+ fv0 fv1)))
>> >   (namespace-anchor->namespace a)))
>> >
>> > (displayln "10,000 fvars; let-syntax implementation")
>> >
>> > (time
>> >  (eval
>> >   '(begin
>> >      (begin-for-syntax
>> >        (current-fvars 10000))
>> >      (my-module
>> >       (set! fv0 8)
>> >       (set! fv1 8)
>> >       (+ fv0 fv1)))
>> >   (namespace-anchor->namespace a)))
>> >
>> > (define-for-syntax (bind-fvars2 n tail)
>> >   #`(let #,(for/list ([i (in-range 0 n)])
>> >              (with-syntax ([fvar (syntax-local-introduce (format-id #f
>> "fv~a" i))])
>> >                #`[fvar (void)]))
>> >       #,tail))
>> >
>> > (define-syntax (my-module2 stx)
>> >   (syntax-case stx ()
>> >     [(_ e ...)
>> >      (bind-fvars2 (current-fvars) #`(begin e ...))]))
>> >
>> > ;; expansion time increases with the number of let bindings, but not
>> nearly as bad
>> > ;; expansion time seems to be 1ms per fvar, i.e., per let-syntax?
>> >
>> > (displayln "1,000 fvars; let implementation")
>> >
>> > (time
>> >  (eval
>> >   '(begin
>> >      (begin-for-syntax
>> >        (current-fvars 1000))
>> >      (my-module2
>> >       (set! fv0 8)
>> >       (set! fv1 8)
>> >       (+ fv0 fv1)))
>> >   (namespace-anchor->namespace a)))
>> >
>> > (displayln "10,000 fvars; let implementation")
>> > (time
>> >  (eval
>> >   '(begin
>> >      (begin-for-syntax
>> >        (current-fvars 10000))
>> >      (my-module2
>> >       (set! fv0 8)
>> >       (set! fv1 8)
>> >       (+ fv0 fv1)))
>> >   (namespace-anchor->namespace a)))
>>
>> --
>> 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 view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-dev/YisAyqG3vbsosdna%40williamjbowman.com
>> .
>>
> --
> 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 view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-dev/CADcuegvO2RT18YkMiYNmJMnsdfz%3DxbGaD-HVv%2B4%3D5TsD--dQCw%40mail.gmail.com
> <https://groups.google.com/d/msgid/racket-dev/CADcuegvO2RT18YkMiYNmJMnsdfz%3DxbGaD-HVv%2B4%3D5TsD--dQCw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/CANy33q%3DAjPsT%3D1NGVw%2BJD6%3Dw2rsc1JqHRAb2Y1iC2MoA-crFPQ%40mail.gmail.com.

Reply via email to