Could you put the dialect values in separate modules and have the #%module-begin conditionally pick which dialect modules to require?
On Thu, Feb 11, 2016 at 11:18 AM, Matthew Butterick <m...@mbtype.com> wrote: > > Why don't you put the val-id into the module via foo? Why is bar > supposed to do that? > > > This is part of a larger pattern where I've got a basic `#%module-begin` > for my #lang that I want to spin out into dialect-specific versions. The > dialects only vary in certain values. > > Sure, I can make a wrapper macro that generates the `#%module-begin` > macro. That's what I've done in the past. It works. But a) it's unhygienic, > and I'm trying to learn cleaner habits, and b) I was recently reminded [1] > that repeated code should be factored out of macros. > > But I'm starting to think that the specialness of `#%module-begin` resists > this kind of hacking. > > [1] > http://docs.racket-lang.org/style/Language_and_Performance.html#%28part._.Macros__.Space_and_.Performance%29 > > > > On Feb 11, 2016, at 7:08 AM, Matthias Felleisen <matth...@ccs.neu.edu> > wrote: > > > > > Why don't you put the val-id into the module via foo? Why is bar > supposed to do that? > > > > > > > > > > On Feb 10, 2016, at 7:13 PM, Matthew Butterick <m...@mbtype.com> wrote: > > > >>>> You really want to parametrize foo over x for such things. (Or use a > syntax parameter.) > >> > >> > >> Of course, though I see now that my example is perhaps too schematic. > If I were really adding, I could do this: > >> > >> ;;;;;;;;;;;;;; > >> #lang racket > >> (require racket/stxparam rackunit) > >> > >> (define-syntax-parameter x-param > >> (λ (stx) (raise-syntax-error (syntax-e stx) "must be parameterized > first"))) > >> > >> (define-syntax-rule (foo) (+ x-param x-param)) > >> > >> (define-syntax bar > >> (syntax-rules () > >> [(_ val-in) > >> (let ([val-id val-in]) > >> (syntax-parameterize ([x-param (make-rename-transformer #'val-id)]) > >> (foo)))])) > >> > >> (check-equal? (bar 42) 84) > >> ;;;;;;;;;;;;;; > >> > >> Wonderful. But in fact, both my `foo` and `bar` are #%module-begin > transformers. So I can try to follow the same pattern, but I get stuck at > the end: > >> > >> ;;;;;;;;;;;;;; > >> #lang racket > >> (require racket/stxparam) > >> > >> (define-syntax-parameter x-param > >> (λ (stx) (raise-syntax-error (syntax-e stx) "must be parameterized > first"))) > >> > >> (define-syntax-rule (foo expr ...) (#%module-begin x-param expr ...)) > >> > >> (define-syntax bar > >> (syntax-rules () > >> [(_ val-in) > >> (let ([val-id val-in]) > >> (syntax-parameterize ([x-param (make-rename-transformer #'val-id)]) > >> <what goes here?>))])) > >> ;;;;;;;;;;;;;; > >> > >> If I put `(foo)` on the last line, I'm trying to `syntax-parameterize` > over a module-begin context, which fails. > >> > >> AFAICT it's also not possible to syntax-parameterize over > `make-rename-transformer`, because it produces a transformer inside a > transformer, and I'm not clear how to unwrap this so that `bar` is a usable > #%module-begin macro: > >> > >> ;;;;;;;;;;;;;; > >> #lang racket > >> (require racket/stxparam) > >> > >> (define-syntax-parameter x-param > >> (λ (stx) (raise-syntax-error (syntax-e stx) "must be parameterized > first"))) > >> > >> (define-syntax-rule (foo expr ...) (#%module-begin x-param expr ...)) > >> > >> (define-syntax bar > >> (<what goes here?> > >> (λ(stx) > >> #'(let ([val-id 42]) > >> (syntax-parameterize ([x-param (make-rename-transformer > #'val-id)]) > >> (make-rename-transformer #'foo)))))) > >> ;;;;;;;;;;;;;; > >> > >> > >> > >> On Feb 10, 2016, at 2:52 PM, Matthias Felleisen <matth...@ccs.neu.edu> > wrote: > >> > >>> > >>> You really want to parametrize foo over x for such things. (Or use a > syntax parameter.) > >>> > >>> > >>> On Feb 10, 2016, at 3:26 PM, Matthew Butterick <m...@mbtype.com> wrote: > >>> > >>>> I suspect there's a simple way to do this, I just haven't done it > before, so it does not appear simple. I tried a syntax parameter, and then > I had two problems. > >>>> > >>>> Please consider this schematic example (no, I am not using macros to > add): > >>>> > >>>> #lang racket > >>>> (define-syntax-rule (foo) (+ x x)) > >>>> (define-syntax bar (make-rename-transformer #'foo)) > >>>> > >>>> `(foo)` will fail with an undefined-identifier error because there is > no binding for x. As will `(bar)`, because it just refers to `(foo)`. > >>>> > >>>> Q: At the definition site of `bar`, is there a way to bind x so that > it affects `foo`, and `(bar)` thereby produces a meaningful answer? > >>>> > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.