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

Reply via email to