Thanks so much for your suggestion! Switching over to `define-simple-macro` 
made the code smell a lot less, and with a reframing of how I approached 
using macros, this has led to a much neater and cleaner expander that 
doesn't require recursive `local-expand`ing. I've spent the last day 
implementing this change, and it's looking good!

On Thursday, July 23, 2020 at 1:22:03 PM UTC-4 [email protected] wrote:

> local-expand supports the stop-list argument, so I think you can put all 
> core forms there.
>
> #lang racket
>
> (require syntax/parse/define)
>
> (define-syntax (A-core stx)
>   (syntax-parse stx #:literals (b-core)
>     [(A-core (b-core x)) #'(printf "A-core got value ~a.~n" x)]))
>
> (define-syntax (b-core stx) (raise-syntax-error #f "b-core out of context"))
>
> (define-simple-macro (b-surface x) (b-core x))
>
> (define-syntax (A-surface stx)
>   (syntax-parse stx
>     [(A-surface expr)
>      #:with sub-stx (local-expand #'expr 'expression (list #'b-core))
>      #`(A-core sub-stx)]))
>
> (A-surface (b-surface "hello"))
>
> Note that I switch define-syntax-rule to define-simple-macro because 
> define-syntax-rule will use syntax-protect, resulting in errors like cannot 
> use identifier tainted by macro transformation.
>
> On Thu, Jul 23, 2020 at 10:00 AM Thomas Del Vecchio <
> [email protected]> wrote:
>
>> Hi all,
>>
>> I'm working on a family of languages in Racket, and I'm running into a 
>> conceptual issue with the information flow of the project. I have a 
>> standard core language whose syntax is s-expressions, with some macros in 
>> the expander. Then, there is a surface language (compiled into 
>> s-expressions with brag) which directly translates into the core language. 
>> There will also be other surface languages in the future, forming a 
>> tower/tree of languages that compile into simpler ones, so I want to make 
>> sure I get this pattern right.
>>
>> Conceptually, I would want the surface language to fully "compile" into 
>> the core language before the core language tries to do anything. As I 
>> develop the surface language, I don't think I should have to concern myself 
>> with the inner workings of the core language; I should be able to just 
>> produce core language code, and then have the core language handle it from 
>> there. I find myself running into an issue, however, where the core 
>> language starts to do computations before the translation is 
>> fully complete. This is an issue because the macros of the core language 
>> are taking in the syntax of the surface language which hasn't been 
>> translated yet, and so the core language doesn't recognize this syntax and 
>> breaks. 
>>
>> As a small example, consider the following:
>> core-language-expander.rkt
>> (define-syntax (A-core stx)
>>   (syntax-parse stx #:datum-literals (b-core)
>>     [(A-core (b-core x)) #'(printf "A-core got value ~a.~n" x)]))
>>
>> surface-language-expander.rkt
>> (define-syntax-rule (b-surface x) (b-core x))
>> (define-syntax (A-surface stx)
>>   (syntax-parse stx
>>     [(A-surface expr) #'(A-core expr)]))
>>
>> Here, if we call `(A-surface (b-surface "hello"))`, we would want it to 
>> take the `A-surface`, and convert it into `A-core`, and then expand 
>> `(b-surface 
>> "hello")`. Since `A-core` is implemented as a macro, though, it takes 
>> `(b-surface 
>> "hello")` unexpanded, and so tries to evaluate `(A-core (b-surface 
>> "hello"))`, which fails.
>>
>> Since `b-core` isn't defined as a function/macro in the core language 
>> (it is just a piece of syntax used in `A-core`), we can't just evaluate 
>> `(b-surface 
>> "hello")` as a value before passing it in. If we try using `local-expand` 
>> or something similar to handle the expansion as syntax, there isn't an 
>> obvious way to make it only expand macros defined in the surface language 
>> expander (and not those defined in the core language expander), which turns 
>> out to be an issue in my case.
>>
>> Do any of you recommend a resource for understanding the strategy of 
>> taking a stack of languages and compiling down one layer at a time? It 
>> seems like the notion of a tower of languages would be fairly natural, yet 
>> the only success I have had is with some hacks with recursive local-expand 
>> that feel extremely unnatural, and also require further hacks to get around 
>> things like syntax-tainting.
>>
>> Thanks so much!
>> Thomas Del Vecchio
>>
>> -- 
>> 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 [email protected].
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/racket-users/26f44e6d-f1f8-465e-9639-6cd6afeffa31n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/racket-users/26f44e6d-f1f8-465e-9639-6cd6afeffa31n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/785f76bc-5b81-4747-baa8-fc0378ee329fn%40googlegroups.com.

Reply via email to