Thanks for answering on a Friday night. I'll limit my questions to one and do some more homework now that you've reduced the search space.
Regarding, "The *only* way for module A to affect the compilation of module B in any way is for module B to require (directly or indirectly) module A. And the only way to make a compile-time side-effect in module A "persistent", so it will affect the compile-time state of other module compilations is to put it in a 'begin-for-syntax'." True or False, anything you can do with begin-for-syntax can be done via a module, providing and subsequently requiring where needed via: (require (for-syntax ...)) (require (only-meta-in ...)) (require (for-meta 1 ...)) Thanks in advance, Ray On Fri, Nov 16, 2012 at 6:05 PM, Ryan Culpepper <r...@cs.utah.edu> wrote: > On 11/16/2012 05:16 PM, Ray Racine wrote: > >> I've run across a few things mentioning cooperating macros, something >> I'm working through. >> >> Consider the following in a source file "nest.rkt" >> https://gist.github.com/**4090877 <https://gist.github.com/4090877> >> >> So in this example each expansion of the two defined macros in the >> `nest' module sees mutually mutable state at meta level 1. >> >> And of course in a separate source module, say "bird-watcher.rkt" with >> the following. >> >> #lang racket >> >> (require "nest.rkt") >> >> (define the-nest >> (begin >> (daddy-brings-worms) >> (daddy-brings-worms))) >> >> the-nest >> >> ;; end-of-module >> >> One sees that the mutable state is not maintained across modules. i.e., >> Not cooperating. All, I'm guessing, a direct consequence of the >> "Immutable Laws Of Flatt" (ILOF), "You Want It When", and "Modules, >> Visitations and Instantiations, Oh My". >> > > Yes. To summarize: the expansion/compilation of each module starts with a > fresh state, which is then initialized with the compile-time parts of the > modules it depends on. > > > BUT, the ILOF has a backdoor[1], there exists a meta level wormhole >> which allows state to tunnel through modules and expansions. If one >> were to use `define-syntax' at compile time (during meta level 1) to >> bind a non-procedure value, one can rat-hole state which is subsequently >> accessible via `syntax-local-value' in an a different macro expansion at >> meta level 1, in a different module. i.e., the macros now can cooperate. >> Here I'm taking "cooperate" as synonymous with shared mutable state. >> >> Based on what I think I understand, I can rejigger my bird net examples >> to cooperate using the wormhole. >> > > No, that's not a back door, because you still get a fresh state and then > you execute the definition again. So if you did something like > > (define-syntax the-nest-state (box (cons 0 0))) > > and then mutated the box during the expansion of module A, then when you > start expanding module B you execute that syntax definition again, so > module B starts out with a fresh box holding (cons 0 0). > > -- > > The *only* way for module A to affect the compilation of module B in any > way is for module B to require (directly or indirectly) module A. > > And the only way to make a compile-time side-effect in module A > "persistent", so it will affect the compile-time state of other module > compilations is to put it in a 'begin-for-syntax'. (Actually, there are a > few other ways, but they take longer to explain.) > > -- > > I'll stop here in case you want to reformulate the questions in your next > few paragraphs based on my answers so far. > > Ryan > > > So assuming the above is more-or-less correct, can cooperating macros be >> accomplished solely via the application of module require / provide at >> proper meta levels. One one hand, I'm visualizing a `define-syntax' >> binding a non-procedure value at compile time (meta 1) as in essence >> pushing the value up into meta 2. And the `syntax-local-value' as >> reaching out from meta 1 into meta 2 to fetch the state down. It's >> global because meta layer 2 is a single global environment in which meta >> 1 syntax transformers are evaluated. >> >> On the other, other hand I visualize that during module visitations and >> instantiations the _only_ thing which can _cross_ meta levels is syntax. >> i.e. syntax at meta level N can be lifted into meta level N+1, >> transformed and returned back to meta level N. But as only syntax >> crosses meta boundaries, hence the define-syntax and syntax-local-value >> backdoor. >> >> Or another way of phrasing the question, "Can one >> write cooperating macros without resorting to the use of `define-syntax' >> and `syntax-local-value'". If yes, how? >> >> >> Thanks, >> >> >> Ray >> >> >> [1] Seems the only true immutable law in CS is, there's always a backdoor. >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/**users<http://lists.racket-lang.org/users> >> >> >
____________________ Racket Users list: http://lists.racket-lang.org/users