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.
