Re: [racket-dev] submodules and local-expand
At Wed, 6 Jun 2012 13:32:19 -0400, Sam Tobin-Hochstadt wrote: > However, we can't just > add `module*` to the stop list at the moment, because if anything is > in the stop list, then all the core forms are added, and then we > wouldn't fully expand the program. > > However, I think we can relax this restriction in the case of > `module*`. In particular, if the stop list contains *only* `module*`, > then we should avoid adding the other core forms. That sounds right to me. _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] submodules and local-expand
I think the current semantics of submodules doesn't work for Typed Racket, and in general for the technique described in "Language as Libraries", but we can fix it easily. In particular, consider a language that lets you statically assert that an identifier is bound to 5, so that this program is a static error: #lang five (define f 6) (assert5 f) Now, we can let our language, using `#%module-begin`, record information about what identifiers are bound to 5, inserting updates to a compile-time table after analyzing the fully-expanded module body. So this program: #lang five (define g 5) (provide g) expands to, roughly: (module racket (define-values (g) '5) (provide g) (begin-for-syntax (declare-5! #'g))) However, when we add submodules, in particular submodules declared with `module*`, things go wrong: #lang five (define g 5) (module* m #f (assert5 g)) Now, we're going to check that `g` is bound to 5 in the inner module during the local-expansion of the outer module, which is *before* we've inserted the declaration that `g` is bound to 5. So we're in trouble. What we'd like to do is to change our expansion to not expand the submodules, in particular `module*` submodules, until we're done with processing the main module. This would be in keeping with the way that module dependencies are usually expanded. However, we can't just add `module*` to the stop list at the moment, because if anything is in the stop list, then all the core forms are added, and then we wouldn't fully expand the program. However, I think we can relax this restriction in the case of `module*`. In particular, if the stop list contains *only* `module*`, then we should avoid adding the other core forms. This is safe because the submodule is intentionally "later" than the rest of the module, and so we don't run into the binding and renaming issues that motivated this restriction in the first place. And then our `five` language can avoid expanding `module*` submodules, and not worry about anything else. -- sam th sa...@ccs.neu.edu _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Submodules and internal #langs
With the submodule support, the following is a legal program: #lang racket #lang racket Is this intentional? _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
At Fri, 9 Mar 2012 17:21:26 -0700, Matthew Flatt wrote: > At Fri, 9 Mar 2012 15:58:11 -0700, Jay McCarthy wrote: > > I just pushed... > > > > - module** > > > > Like module* but combines multiple occurrences of the same submodule > > name into one module* > > I like this direction --- and like everyone, I wish for a better name. As you probably noticed, we're currently trying out `module+'. I tried out several alternatives, including `submodule', `slice', `facet', `segment', `section', `.section', `at-module', and even `p.s.'; `module+' is the best so far. One big advantage of `module+' is that it avoids inventing a new term, and I think `+' is suggestive of combining multiple bodies into one. Meanwhile, `(submod "..")' is now allowed as a shorthand for `(submod "." "..")'. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
On Monday, Matthias Felleisen wrote: > > I think Jay is expressing an Eli-concern: we need to distribute the > full source to determine whether something can be thrown away. It's more than just the dependencies between libraries -- it's the fact that expanding the code (before "stripping", but see below) requires the extra libraries to be present. So it's not plain stripping of the zo files that are needed -- it's some way to make all tools silently ignore `test' submodules (or something else). On Monday, Matthew Flatt wrote: > Yes: In other words, there could be a parameter that causes the > macro expander to drop `test' submodules before it even attempts to > expand them --- roughly like not using `-g' with `gcc'. > > Meanwhile, the after-the-fact pruning tool could be called `raco > strip'. In the case of tests, this is a good analogy: either you ship the full zos as-is, with the test code, or you strip it out just like the `-g' flag. But things get more complicated with something like documentation submodules: in that case you want to strip them out for one kind of (core) distribution, but for some "documentation-source" distribution you'll want to have just the documentation code. So in this case it's splitting more than stripping. (And then there's the problem of how both of these packages are assembled.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
I agree with Robby. Jay On Mon, Mar 12, 2012 at 1:18 PM, Robby Findler wrote: > I thought Matthew was pointing out how we can distribute some source > that works if you set a parameter properly and that same source will > contain no test-based dependencies. > > Boy, this conversation sure makes me wish for the ability to just > gather everyone up around a whiteboard or something :( > > Robby > > On Mon, Mar 12, 2012 at 2:15 PM, Matthias Felleisen > wrote: >> >> I think Jay is expressing an Eli-concern: we need to distribute >> the full source to determine whether something can be thrown away. >> >> >> On Mar 12, 2012, at 3:13 PM, Robby Findler wrote: >> >>> Oh, I get it now. Thanks. >>> >>> This also seems like something that you'd want to put control over at >>> the package level, I guess. That is, a package can depend on another >>> package, but without that second package's test modules or something. >>> >>> Robby >>> >>> On Mon, Mar 12, 2012 at 2:05 PM, Matthew Flatt wrote: Yes: In other words, there could be a parameter that causes the macro expander to drop `test' submodules before it even attempts to expand them --- roughly like not using `-g' with `gcc'. Meanwhile, the after-the-fact pruning tool could be called `raco strip'. At Mon, 12 Mar 2012 15:02:58 -0400, Matthias Felleisen wrote: > > Or you make the pruning step a part of the compiler. > > > On Mar 12, 2012, at 3:01 PM, Robby Findler wrote: > >> Yes, I think the point that Jay's making is that the thing you'd >> distribute wouldn't be rkt code, but some low-level thing. Well, >> either that or you distribute .rkt code that doesn't actually run. >> >> Robby >> >> On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen >> wrote: >>> >>> I know that. But we could consider the pruning step as part of >>> compilation. >>> >>> >>> On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: >>> He's saying that there is no easy way to, without expanding the code (and perhaps without going one step further beyond a fully expanded program, but nevermind that detail), split apart the submodules that come from a single module. You just cannot tell, without expanding everything, which of the imports end up being used where (at least I think that's the idea). Robby On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen wrote: > > Why does it not compile? Do you mean it doesn't compile to the same > byte > codes? > > > > > On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: > >> Sorry Matthias, I don't think I understand your question. >> >> At the bytecode level, it would be "easy", so we could change the >> distribution scripts to do that. >> >> At the source level, it's not really possible because of macros that >> generate code in a submodule. >> >> My personal taste is that it is bad to ship .rkt that doesn't >> compile, >> but I'd also like a future where we don't ship .rkt >> >> Jay >> >> On 3/12/12, Matthias Felleisen wrote: >>> >>> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: >>> The current demodularizer would do that. Presumably we could make a tool that operated on a single module's zo and removed such submodules. The main problem would be that the source is un-compilable. >>> >>> >>> Meaning? Removing docs and tests shouldn't leave the functional >>> part in > bad >>> shape >>> >>> Jay On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen wrote: > > Yes, dependencies abound if we include tests and doc in the same > module. > At the same time it is good practice to have things together. > > Can't this problem be solved with module-flattening tools? From > what I > can tell, these test and doc modules could be dropped leaving the > running > residual, which could be bundled. -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 >>> >>> >> >> >> -- >> Jay McCarthy >> Assistant Professor / Brigham Young University >> http://faculty.cs.byu.edu/~jay >> >> "The glory of God is Intelligence" - D&C 93 > > > _ >
Re: [racket-dev] Submodules & dependencies
I thought Matthew was pointing out how we can distribute some source that works if you set a parameter properly and that same source will contain no test-based dependencies. Boy, this conversation sure makes me wish for the ability to just gather everyone up around a whiteboard or something :( Robby On Mon, Mar 12, 2012 at 2:15 PM, Matthias Felleisen wrote: > > I think Jay is expressing an Eli-concern: we need to distribute > the full source to determine whether something can be thrown away. > > > On Mar 12, 2012, at 3:13 PM, Robby Findler wrote: > >> Oh, I get it now. Thanks. >> >> This also seems like something that you'd want to put control over at >> the package level, I guess. That is, a package can depend on another >> package, but without that second package's test modules or something. >> >> Robby >> >> On Mon, Mar 12, 2012 at 2:05 PM, Matthew Flatt wrote: >>> Yes: In other words, there could be a parameter that causes the macro >>> expander to drop `test' submodules before it even attempts to expand >>> them --- roughly like not using `-g' with `gcc'. >>> >>> Meanwhile, the after-the-fact pruning tool could be called `raco >>> strip'. >>> >>> At Mon, 12 Mar 2012 15:02:58 -0400, Matthias Felleisen wrote: Or you make the pruning step a part of the compiler. On Mar 12, 2012, at 3:01 PM, Robby Findler wrote: > Yes, I think the point that Jay's making is that the thing you'd > distribute wouldn't be rkt code, but some low-level thing. Well, > either that or you distribute .rkt code that doesn't actually run. > > Robby > > On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen > wrote: >> >> I know that. But we could consider the pruning step as part of >> compilation. >> >> >> On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: >> >>> He's saying that there is no easy way to, without expanding the code >>> (and perhaps without going one step further beyond a fully expanded >>> program, but nevermind that detail), split apart the submodules that >>> come from a single module. You just cannot tell, without expanding >>> everything, which of the imports end up being used where (at least I >>> think that's the idea). >>> >>> Robby >>> >>> On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen >>> wrote: Why does it not compile? Do you mean it doesn't compile to the same byte codes? On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: > Sorry Matthias, I don't think I understand your question. > > At the bytecode level, it would be "easy", so we could change the > distribution scripts to do that. > > At the source level, it's not really possible because of macros that > generate code in a submodule. > > My personal taste is that it is bad to ship .rkt that doesn't compile, > but I'd also like a future where we don't ship .rkt > > Jay > > On 3/12/12, Matthias Felleisen wrote: >> >> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: >> >>> The current demodularizer would do that. Presumably we could make a >>> tool that operated on a single module's zo and removed such >>> submodules. The main problem would be that the source is >>> un-compilable. >> >> >> Meaning? Removing docs and tests shouldn't leave the functional part >> in bad >> shape >> >> >>> >>> Jay >>> >>> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >>> wrote: Yes, dependencies abound if we include tests and doc in the same module. At the same time it is good practice to have things together. Can't this problem be solved with module-flattening tools? From what I can tell, these test and doc modules could be dropped leaving the running residual, which could be bundled. >>> >>> >>> >>> -- >>> Jay McCarthy >>> Assistant Professor / Brigham Young University >>> http://faculty.cs.byu.edu/~jay >>> >>> "The glory of God is Intelligence" - D&C 93 >> >> > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev >> _ Racket Developers list: http://lists.racket-lang.org/dev > _ Racket Developers list: h
Re: [racket-dev] Submodules & dependencies
I think Jay is expressing an Eli-concern: we need to distribute the full source to determine whether something can be thrown away. On Mar 12, 2012, at 3:13 PM, Robby Findler wrote: > Oh, I get it now. Thanks. > > This also seems like something that you'd want to put control over at > the package level, I guess. That is, a package can depend on another > package, but without that second package's test modules or something. > > Robby > > On Mon, Mar 12, 2012 at 2:05 PM, Matthew Flatt wrote: >> Yes: In other words, there could be a parameter that causes the macro >> expander to drop `test' submodules before it even attempts to expand >> them --- roughly like not using `-g' with `gcc'. >> >> Meanwhile, the after-the-fact pruning tool could be called `raco >> strip'. >> >> At Mon, 12 Mar 2012 15:02:58 -0400, Matthias Felleisen wrote: >>> >>> Or you make the pruning step a part of the compiler. >>> >>> >>> On Mar 12, 2012, at 3:01 PM, Robby Findler wrote: >>> Yes, I think the point that Jay's making is that the thing you'd distribute wouldn't be rkt code, but some low-level thing. Well, either that or you distribute .rkt code that doesn't actually run. Robby On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen wrote: > > I know that. But we could consider the pruning step as part of > compilation. > > > On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: > >> He's saying that there is no easy way to, without expanding the code >> (and perhaps without going one step further beyond a fully expanded >> program, but nevermind that detail), split apart the submodules that >> come from a single module. You just cannot tell, without expanding >> everything, which of the imports end up being used where (at least I >> think that's the idea). >> >> Robby >> >> On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen >> wrote: >>> >>> Why does it not compile? Do you mean it doesn't compile to the same byte >>> codes? >>> >>> >>> >>> >>> On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: >>> Sorry Matthias, I don't think I understand your question. At the bytecode level, it would be "easy", so we could change the distribution scripts to do that. At the source level, it's not really possible because of macros that generate code in a submodule. My personal taste is that it is bad to ship .rkt that doesn't compile, but I'd also like a future where we don't ship .rkt Jay On 3/12/12, Matthias Felleisen wrote: > > On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > >> The current demodularizer would do that. Presumably we could make a >> tool that operated on a single module's zo and removed such >> submodules. The main problem would be that the source is >> un-compilable. > > > Meaning? Removing docs and tests shouldn't leave the functional part > in >>> bad > shape > > >> >> Jay >> >> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >> wrote: >>> >>> Yes, dependencies abound if we include tests and doc in the same >>> module. >>> At the same time it is good practice to have things together. >>> >>> Can't this problem be solved with module-flattening tools? From >>> what I >>> can tell, these test and doc modules could be dropped leaving the >>> running >>> residual, which could be bundled. >> >> >> >> -- >> Jay McCarthy >> Assistant Professor / Brigham Young University >> http://faculty.cs.byu.edu/~jay >> >> "The glory of God is Intelligence" - D&C 93 > > -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 >>> >>> >>> _ >>> Racket Developers list: >>> http://lists.racket-lang.org/dev > >>> >>> >>> _ >>> Racket Developers list: >>> http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Oh, I get it now. Thanks. This also seems like something that you'd want to put control over at the package level, I guess. That is, a package can depend on another package, but without that second package's test modules or something. Robby On Mon, Mar 12, 2012 at 2:05 PM, Matthew Flatt wrote: > Yes: In other words, there could be a parameter that causes the macro > expander to drop `test' submodules before it even attempts to expand > them --- roughly like not using `-g' with `gcc'. > > Meanwhile, the after-the-fact pruning tool could be called `raco > strip'. > > At Mon, 12 Mar 2012 15:02:58 -0400, Matthias Felleisen wrote: >> >> Or you make the pruning step a part of the compiler. >> >> >> On Mar 12, 2012, at 3:01 PM, Robby Findler wrote: >> >> > Yes, I think the point that Jay's making is that the thing you'd >> > distribute wouldn't be rkt code, but some low-level thing. Well, >> > either that or you distribute .rkt code that doesn't actually run. >> > >> > Robby >> > >> > On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen >> > wrote: >> >> >> >> I know that. But we could consider the pruning step as part of >> >> compilation. >> >> >> >> >> >> On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: >> >> >> >>> He's saying that there is no easy way to, without expanding the code >> >>> (and perhaps without going one step further beyond a fully expanded >> >>> program, but nevermind that detail), split apart the submodules that >> >>> come from a single module. You just cannot tell, without expanding >> >>> everything, which of the imports end up being used where (at least I >> >>> think that's the idea). >> >>> >> >>> Robby >> >>> >> >>> On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen >> >>> wrote: >> >> Why does it not compile? Do you mean it doesn't compile to the same byte >> codes? >> >> >> >> >> On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: >> >> > Sorry Matthias, I don't think I understand your question. >> > >> > At the bytecode level, it would be "easy", so we could change the >> > distribution scripts to do that. >> > >> > At the source level, it's not really possible because of macros that >> > generate code in a submodule. >> > >> > My personal taste is that it is bad to ship .rkt that doesn't compile, >> > but I'd also like a future where we don't ship .rkt >> > >> > Jay >> > >> > On 3/12/12, Matthias Felleisen wrote: >> >> >> >> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: >> >> >> >>> The current demodularizer would do that. Presumably we could make a >> >>> tool that operated on a single module's zo and removed such >> >>> submodules. The main problem would be that the source is >> >>> un-compilable. >> >> >> >> >> >> Meaning? Removing docs and tests shouldn't leave the functional part >> >> in >> bad >> >> shape >> >> >> >> >> >>> >> >>> Jay >> >>> >> >>> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >> >>> wrote: >> >> Yes, dependencies abound if we include tests and doc in the same >> module. >> At the same time it is good practice to have things together. >> >> Can't this problem be solved with module-flattening tools? From >> what I >> can tell, these test and doc modules could be dropped leaving the >> running >> residual, which could be bundled. >> >>> >> >>> >> >>> >> >>> -- >> >>> Jay McCarthy >> >>> Assistant Professor / Brigham Young University >> >>> http://faculty.cs.byu.edu/~jay >> >>> >> >>> "The glory of God is Intelligence" - D&C 93 >> >> >> >> >> > >> > >> > -- >> > Jay McCarthy >> > Assistant Professor / Brigham Young University >> > http://faculty.cs.byu.edu/~jay >> > >> > "The glory of God is Intelligence" - D&C 93 >> >> >> _ >> Racket Developers list: >> http://lists.racket-lang.org/dev >> >> >> >> >> _ >> Racket Developers list: >> http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Ya, even if someone does their best by moving dependencies into the tightest module*, there is a compilation problem: "m.rk" #lang racket (module* test #f (require tests/eli-tester)) simply does not compile if tests/eli-tester is not there. If you did compile it but didn't instantiate the test module, then it would run just fine (even without zo stripping) Jay On 3/12/12, Robby Findler wrote: > He's saying that there is no easy way to, without expanding the code > (and perhaps without going one step further beyond a fully expanded > program, but nevermind that detail), split apart the submodules that > come from a single module. You just cannot tell, without expanding > everything, which of the imports end up being used where (at least I > think that's the idea). > > Robby > > On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen > wrote: >> >> Why does it not compile? Do you mean it doesn't compile to the same byte >> codes? >> >> >> >> >> On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: >> >>> Sorry Matthias, I don't think I understand your question. >>> >>> At the bytecode level, it would be "easy", so we could change the >>> distribution scripts to do that. >>> >>> At the source level, it's not really possible because of macros that >>> generate code in a submodule. >>> >>> My personal taste is that it is bad to ship .rkt that doesn't compile, >>> but I'd also like a future where we don't ship .rkt >>> >>> Jay >>> >>> On 3/12/12, Matthias Felleisen wrote: On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > The current demodularizer would do that. Presumably we could make a > tool that operated on a single module's zo and removed such > submodules. The main problem would be that the source is > un-compilable. Meaning? Removing docs and tests shouldn't leave the functional part in bad shape > > Jay > > On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen > wrote: >> >> Yes, dependencies abound if we include tests and doc in the same >> module. >> At the same time it is good practice to have things together. >> >> Can't this problem be solved with module-flattening tools? From what I >> can tell, these test and doc modules could be dropped leaving the >> running >> residual, which could be bundled. > > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 >>> >>> >>> -- >>> Jay McCarthy >>> Assistant Professor / Brigham Young University >>> http://faculty.cs.byu.edu/~jay >>> >>> "The glory of God is Intelligence" - D&C 93 >> >> >> _ >> Racket Developers list: >> http://lists.racket-lang.org/dev > -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Yes: In other words, there could be a parameter that causes the macro expander to drop `test' submodules before it even attempts to expand them --- roughly like not using `-g' with `gcc'. Meanwhile, the after-the-fact pruning tool could be called `raco strip'. At Mon, 12 Mar 2012 15:02:58 -0400, Matthias Felleisen wrote: > > Or you make the pruning step a part of the compiler. > > > On Mar 12, 2012, at 3:01 PM, Robby Findler wrote: > > > Yes, I think the point that Jay's making is that the thing you'd > > distribute wouldn't be rkt code, but some low-level thing. Well, > > either that or you distribute .rkt code that doesn't actually run. > > > > Robby > > > > On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen > > wrote: > >> > >> I know that. But we could consider the pruning step as part of compilation. > >> > >> > >> On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: > >> > >>> He's saying that there is no easy way to, without expanding the code > >>> (and perhaps without going one step further beyond a fully expanded > >>> program, but nevermind that detail), split apart the submodules that > >>> come from a single module. You just cannot tell, without expanding > >>> everything, which of the imports end up being used where (at least I > >>> think that's the idea). > >>> > >>> Robby > >>> > >>> On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen > >>> wrote: > > Why does it not compile? Do you mean it doesn't compile to the same byte > codes? > > > > > On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: > > > Sorry Matthias, I don't think I understand your question. > > > > At the bytecode level, it would be "easy", so we could change the > > distribution scripts to do that. > > > > At the source level, it's not really possible because of macros that > > generate code in a submodule. > > > > My personal taste is that it is bad to ship .rkt that doesn't compile, > > but I'd also like a future where we don't ship .rkt > > > > Jay > > > > On 3/12/12, Matthias Felleisen wrote: > >> > >> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > >> > >>> The current demodularizer would do that. Presumably we could make a > >>> tool that operated on a single module's zo and removed such > >>> submodules. The main problem would be that the source is > >>> un-compilable. > >> > >> > >> Meaning? Removing docs and tests shouldn't leave the functional part > >> in > bad > >> shape > >> > >> > >>> > >>> Jay > >>> > >>> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen > >>> wrote: > > Yes, dependencies abound if we include tests and doc in the same > module. > At the same time it is good practice to have things together. > > Can't this problem be solved with module-flattening tools? From what > I > can tell, these test and doc modules could be dropped leaving the > running > residual, which could be bundled. > >>> > >>> > >>> > >>> -- > >>> Jay McCarthy > >>> Assistant Professor / Brigham Young University > >>> http://faculty.cs.byu.edu/~jay > >>> > >>> "The glory of God is Intelligence" - D&C 93 > >> > >> > > > > > > -- > > Jay McCarthy > > Assistant Professor / Brigham Young University > > http://faculty.cs.byu.edu/~jay > > > > "The glory of God is Intelligence" - D&C 93 > > > _ > Racket Developers list: > http://lists.racket-lang.org/dev > >> > > > _ > Racket Developers list: > http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Or you make the pruning step a part of the compiler. On Mar 12, 2012, at 3:01 PM, Robby Findler wrote: > Yes, I think the point that Jay's making is that the thing you'd > distribute wouldn't be rkt code, but some low-level thing. Well, > either that or you distribute .rkt code that doesn't actually run. > > Robby > > On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen > wrote: >> >> I know that. But we could consider the pruning step as part of compilation. >> >> >> On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: >> >>> He's saying that there is no easy way to, without expanding the code >>> (and perhaps without going one step further beyond a fully expanded >>> program, but nevermind that detail), split apart the submodules that >>> come from a single module. You just cannot tell, without expanding >>> everything, which of the imports end up being used where (at least I >>> think that's the idea). >>> >>> Robby >>> >>> On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen >>> wrote: Why does it not compile? Do you mean it doesn't compile to the same byte codes? On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: > Sorry Matthias, I don't think I understand your question. > > At the bytecode level, it would be "easy", so we could change the > distribution scripts to do that. > > At the source level, it's not really possible because of macros that > generate code in a submodule. > > My personal taste is that it is bad to ship .rkt that doesn't compile, > but I'd also like a future where we don't ship .rkt > > Jay > > On 3/12/12, Matthias Felleisen wrote: >> >> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: >> >>> The current demodularizer would do that. Presumably we could make a >>> tool that operated on a single module's zo and removed such >>> submodules. The main problem would be that the source is >>> un-compilable. >> >> >> Meaning? Removing docs and tests shouldn't leave the functional part in >> bad >> shape >> >> >>> >>> Jay >>> >>> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >>> wrote: Yes, dependencies abound if we include tests and doc in the same module. At the same time it is good practice to have things together. Can't this problem be solved with module-flattening tools? From what I can tell, these test and doc modules could be dropped leaving the running residual, which could be bundled. >>> >>> >>> >>> -- >>> Jay McCarthy >>> Assistant Professor / Brigham Young University >>> http://faculty.cs.byu.edu/~jay >>> >>> "The glory of God is Intelligence" - D&C 93 >> >> > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev >> _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Yes, I think the point that Jay's making is that the thing you'd distribute wouldn't be rkt code, but some low-level thing. Well, either that or you distribute .rkt code that doesn't actually run. Robby On Mon, Mar 12, 2012 at 1:59 PM, Matthias Felleisen wrote: > > I know that. But we could consider the pruning step as part of compilation. > > > On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: > >> He's saying that there is no easy way to, without expanding the code >> (and perhaps without going one step further beyond a fully expanded >> program, but nevermind that detail), split apart the submodules that >> come from a single module. You just cannot tell, without expanding >> everything, which of the imports end up being used where (at least I >> think that's the idea). >> >> Robby >> >> On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen >> wrote: >>> >>> Why does it not compile? Do you mean it doesn't compile to the same byte >>> codes? >>> >>> >>> >>> >>> On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: >>> Sorry Matthias, I don't think I understand your question. At the bytecode level, it would be "easy", so we could change the distribution scripts to do that. At the source level, it's not really possible because of macros that generate code in a submodule. My personal taste is that it is bad to ship .rkt that doesn't compile, but I'd also like a future where we don't ship .rkt Jay On 3/12/12, Matthias Felleisen wrote: > > On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > >> The current demodularizer would do that. Presumably we could make a >> tool that operated on a single module's zo and removed such >> submodules. The main problem would be that the source is >> un-compilable. > > > Meaning? Removing docs and tests shouldn't leave the functional part in > bad > shape > > >> >> Jay >> >> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >> wrote: >>> >>> Yes, dependencies abound if we include tests and doc in the same module. >>> At the same time it is good practice to have things together. >>> >>> Can't this problem be solved with module-flattening tools? From what I >>> can tell, these test and doc modules could be dropped leaving the >>> running >>> residual, which could be bundled. >> >> >> >> -- >> Jay McCarthy >> Assistant Professor / Brigham Young University >> http://faculty.cs.byu.edu/~jay >> >> "The glory of God is Intelligence" - D&C 93 > > -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 >>> >>> >>> _ >>> Racket Developers list: >>> http://lists.racket-lang.org/dev > _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
I know that. But we could consider the pruning step as part of compilation. On Mar 12, 2012, at 2:57 PM, Robby Findler wrote: > He's saying that there is no easy way to, without expanding the code > (and perhaps without going one step further beyond a fully expanded > program, but nevermind that detail), split apart the submodules that > come from a single module. You just cannot tell, without expanding > everything, which of the imports end up being used where (at least I > think that's the idea). > > Robby > > On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen > wrote: >> >> Why does it not compile? Do you mean it doesn't compile to the same byte >> codes? >> >> >> >> >> On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: >> >>> Sorry Matthias, I don't think I understand your question. >>> >>> At the bytecode level, it would be "easy", so we could change the >>> distribution scripts to do that. >>> >>> At the source level, it's not really possible because of macros that >>> generate code in a submodule. >>> >>> My personal taste is that it is bad to ship .rkt that doesn't compile, >>> but I'd also like a future where we don't ship .rkt >>> >>> Jay >>> >>> On 3/12/12, Matthias Felleisen wrote: On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > The current demodularizer would do that. Presumably we could make a > tool that operated on a single module's zo and removed such > submodules. The main problem would be that the source is > un-compilable. Meaning? Removing docs and tests shouldn't leave the functional part in bad shape > > Jay > > On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen > wrote: >> >> Yes, dependencies abound if we include tests and doc in the same module. >> At the same time it is good practice to have things together. >> >> Can't this problem be solved with module-flattening tools? From what I >> can tell, these test and doc modules could be dropped leaving the running >> residual, which could be bundled. > > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 >>> >>> >>> -- >>> Jay McCarthy >>> Assistant Professor / Brigham Young University >>> http://faculty.cs.byu.edu/~jay >>> >>> "The glory of God is Intelligence" - D&C 93 >> >> >> _ >> Racket Developers list: >> http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
He's saying that there is no easy way to, without expanding the code (and perhaps without going one step further beyond a fully expanded program, but nevermind that detail), split apart the submodules that come from a single module. You just cannot tell, without expanding everything, which of the imports end up being used where (at least I think that's the idea). Robby On Mon, Mar 12, 2012 at 1:47 PM, Matthias Felleisen wrote: > > Why does it not compile? Do you mean it doesn't compile to the same byte > codes? > > > > > On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: > >> Sorry Matthias, I don't think I understand your question. >> >> At the bytecode level, it would be "easy", so we could change the >> distribution scripts to do that. >> >> At the source level, it's not really possible because of macros that >> generate code in a submodule. >> >> My personal taste is that it is bad to ship .rkt that doesn't compile, >> but I'd also like a future where we don't ship .rkt >> >> Jay >> >> On 3/12/12, Matthias Felleisen wrote: >>> >>> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: >>> The current demodularizer would do that. Presumably we could make a tool that operated on a single module's zo and removed such submodules. The main problem would be that the source is un-compilable. >>> >>> >>> Meaning? Removing docs and tests shouldn't leave the functional part in bad >>> shape >>> >>> Jay On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen wrote: > > Yes, dependencies abound if we include tests and doc in the same module. > At the same time it is good practice to have things together. > > Can't this problem be solved with module-flattening tools? From what I > can tell, these test and doc modules could be dropped leaving the running > residual, which could be bundled. -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 >>> >>> >> >> >> -- >> Jay McCarthy >> Assistant Professor / Brigham Young University >> http://faculty.cs.byu.edu/~jay >> >> "The glory of God is Intelligence" - D&C 93 > > > _ > Racket Developers list: > http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Why does it not compile? Do you mean it doesn't compile to the same byte codes? On Mar 12, 2012, at 2:40 PM, Jay McCarthy wrote: > Sorry Matthias, I don't think I understand your question. > > At the bytecode level, it would be "easy", so we could change the > distribution scripts to do that. > > At the source level, it's not really possible because of macros that > generate code in a submodule. > > My personal taste is that it is bad to ship .rkt that doesn't compile, > but I'd also like a future where we don't ship .rkt > > Jay > > On 3/12/12, Matthias Felleisen wrote: >> >> On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: >> >>> The current demodularizer would do that. Presumably we could make a >>> tool that operated on a single module's zo and removed such >>> submodules. The main problem would be that the source is >>> un-compilable. >> >> >> Meaning? Removing docs and tests shouldn't leave the functional part in bad >> shape >> >> >>> >>> Jay >>> >>> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >>> wrote: Yes, dependencies abound if we include tests and doc in the same module. At the same time it is good practice to have things together. Can't this problem be solved with module-flattening tools? From what I can tell, these test and doc modules could be dropped leaving the running residual, which could be bundled. >>> >>> >>> >>> -- >>> Jay McCarthy >>> Assistant Professor / Brigham Young University >>> http://faculty.cs.byu.edu/~jay >>> >>> "The glory of God is Intelligence" - D&C 93 >> >> > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Sorry Matthias, I don't think I understand your question. At the bytecode level, it would be "easy", so we could change the distribution scripts to do that. At the source level, it's not really possible because of macros that generate code in a submodule. My personal taste is that it is bad to ship .rkt that doesn't compile, but I'd also like a future where we don't ship .rkt Jay On 3/12/12, Matthias Felleisen wrote: > > On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > >> The current demodularizer would do that. Presumably we could make a >> tool that operated on a single module's zo and removed such >> submodules. The main problem would be that the source is >> un-compilable. > > > Meaning? Removing docs and tests shouldn't leave the functional part in bad > shape > > >> >> Jay >> >> On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen >> wrote: >>> >>> Yes, dependencies abound if we include tests and doc in the same module. >>> At the same time it is good practice to have things together. >>> >>> Can't this problem be solved with module-flattening tools? From what I >>> can tell, these test and doc modules could be dropped leaving the running >>> residual, which could be bundled. >> >> >> >> -- >> Jay McCarthy >> Assistant Professor / Brigham Young University >> http://faculty.cs.byu.edu/~jay >> >> "The glory of God is Intelligence" - D&C 93 > > -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
On Mar 12, 2012, at 11:39 AM, Jay McCarthy wrote: > The current demodularizer would do that. Presumably we could make a > tool that operated on a single module's zo and removed such > submodules. The main problem would be that the source is > un-compilable. Meaning? Removing docs and tests shouldn't leave the functional part in bad shape > > Jay > > On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen > wrote: >> >> Yes, dependencies abound if we include tests and doc in the same module. At >> the same time it is good practice to have things together. >> >> Can't this problem be solved with module-flattening tools? From what I can >> tell, these test and doc modules could be dropped leaving the running >> residual, which could be bundled. > > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
The current demodularizer would do that. Presumably we could make a tool that operated on a single module's zo and removed such submodules. The main problem would be that the source is un-compilable. Jay On Mon, Mar 12, 2012 at 8:58 AM, Matthias Felleisen wrote: > > Yes, dependencies abound if we include tests and doc in the same module. At > the same time it is good practice to have things together. > > Can't this problem be solved with module-flattening tools? From what I can > tell, these test and doc modules could be dropped leaving the running > residual, which could be bundled. -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Yes, dependencies abound if we include tests and doc in the same module. At the same time it is good practice to have things together. Can't this problem be solved with module-flattening tools? From what I can tell, these test and doc modules could be dropped leaving the running residual, which could be bundled. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
Just now, Jay McCarthy wrote: > I agree with your point #1 heartily. > > I don't follow point #2. Do you mean that currently by having two > files the tests can depend on things that the code does not (for > purposes of distribution, etc) and having those tests embedded in > the files increases the cross-collection dependencies as well as > increasing compilation time? I suppose that is true, but I don't > know how severe it is and I value having the tests. Say that the `foo' collection author sees that and thinks "ooh, a useful feature", then folds the tests into the main code -- so "foo/bar.rkt" has some library code as well as a `test' submodule that uses `tests/eli-tester'. The collection becomes undistributable because `tests/*' is not distributed. Variations: using `rackunit' makes all of `foo' depend on rackunit, a dependency that is needed only for tests, putting the scribble docs in the same file leads to a dependency on scribble, etc. [I guess that it could be argued that all of these dependencies are justified, by my own argument is a proxy argument: linux distributions usually have different sub-packages for docs and for developement files (= tests), and I think that enough thought has been spent there on deciding that this is a useful way to divide things. On one hand, I choose to shoot for a distro-friendly packaging, which is why I take this argument as valid without questioning it. On the other hand, as someone who appreciates such division when I install other packages, I *definitely* see the value in having it -- I imagine some random application that is written in ruby/python/whatever, and I'd hesitate to install it if it pulls in some IDE package, a documentation system, and test files.] -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Submodules & dependencies
I agree with your point #1 heartily. I don't follow point #2. Do you mean that currently by having two files the tests can depend on things that the code does not (for purposes of distribution, etc) and having those tests embedded in the files increases the cross-collection dependencies as well as increasing compilation time? I suppose that is true, but I don't know how severe it is and I value having the tests. Jay On 3/11/12, Eli Barzilay wrote: > Two days ago, Jay McCarthy wrote: >> [...] >> I've expanded 'raco test' to support running a different submodule >> or running the default module (what's a good name for it?) if the >> submodule isn't there. >> >> I intend to change DrDr so that it always uses "raco test -r" rather >> than "racket -t". > > Two comments on this: > > 1. I still would like to see a way to properly run some submodule >other than `main' that is not tied to a "raco test". But probably >a better place for this is a new command-line flag for the main >`racket' executable, where the default for the flag would be >`main'. (This should probably use the same terminology as `slice', >or anything else if it changes.) Then, `raco test' could be >explained as doing two things: changing the default to `test'[*], >and running it recursively over a bunch of files (which is >definitely suitable for testing but not for other modes). > >([*]I still prefer `tests' but...) > > 2. It sounds dangerous to encourage using this by making drdr do it. >The thing is that while the tests don't have a loading overhead, >they will still add dependencies to the files. > > -- > ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: > http://barzilay.org/ Maze is Life! > _ > Racket Developers list: > http://lists.racket-lang.org/dev > -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Submodules & dependencies
Two days ago, Jay McCarthy wrote: > [...] > I've expanded 'raco test' to support running a different submodule > or running the default module (what's a good name for it?) if the > submodule isn't there. > > I intend to change DrDr so that it always uses "raco test -r" rather > than "racket -t". Two comments on this: 1. I still would like to see a way to properly run some submodule other than `main' that is not tied to a "raco test". But probably a better place for this is a new command-line flag for the main `racket' executable, where the default for the flag would be `main'. (This should probably use the same terminology as `slice', or anything else if it changes.) Then, `raco test' could be explained as doing two things: changing the default to `test'[*], and running it recursively over a bunch of files (which is definitely suitable for testing but not for other modes). ([*]I still prefer `tests' but...) 2. It sounds dangerous to encourage using this by making drdr do it. The thing is that while the tests don't have a loading overhead, they will still add dependencies to the files. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
An hour and a half ago, Matthew Flatt wrote: > If I understand what you mean, then all of the interesting uses I > see involve extracting a submodule from the outside: > > * Extracting the `reader' submodule of a given module. > > * Running a `main' submodule of a given module. > > * Running a `test' submodule of a given module. > > * Getting documentation information for a given module. > > * Getting "extra exports" of a given module. Ah, obviously... I can trace the reason I didn't see these as obvious cases to the same little dependency graph I wrote about earlier: sub-`module*' ⇢ module ⇢ sub-`module' Looks like the above items would all be on the left `module*' side, and on that side it makes sense for the submodules on that side to be public since otherwise there's no use for them. So maybe there's a case for `module*' to be visible and for `module' to be hidden? I can't think of practical cases where a submodule on the right side should be visible to the outside. Hopefully this will be clear: for a sub-`module' to be visible on the right, it needs to have some excuse for being a sub-`module', but since there's no way to require the main module from these sub-modules, I no reason for them to be sub-`module's rather than sub-`module*'s. IOW, I think that even a "code-repository" kind of thing could be done with sub-`module*'s. > > I first thought that the whole point of allowing a sub-`module' > > would be to have some otherwise-inaccessible private code in it > > (as the fictitious author of that `my-code' module thinks). > > That is indeed not the goal. But it works the other direction with > `(submodule* ... #f )': the enclosing module can have > otherwise-inaccessible code that is accessed by the submodule (e.g., > to test unexported functions). (This sounds like a point that supports what I said above.) > > If that's wasn't possible, or possible only as a some > > semi-obscure-reflection-api then the `submod' syntax could be > > simpler. > > I'm not sure what you mean here. (I was talking about not allowing submodules to be visible. Clarifying the above first would help here, probably.) > > > > I also love the analogy to paths -- but using strings for them > > > > doesn't look so nice, since strings are begging to be > > > > combined... (I can already see myself wishing for > > > > "./../foo".) Other than the obvious reader issue, would there > > > > be a problem in using `|.|' and `..' for these (and making > > > > them into special module names)? > > > > > > Submodule identifiers are not currently constrained, and I think > > > we should avoid constraining them. If we refrain from > > > constraining submodule names, then `..' could be the name of a > > > submodule. > > > > It just seems similar to the old ("lib.ss" "some" "path") thing in > > that it's asking to be changed to something that is easier to > > remember. Maybe make ".." have an implicit "." before it so > > there's no need for a mysterious `"." ".."'? > > Yes, I think `(submod ".." ...)' can be a shorthand for > `(submod "." ".." ...)'. I see no way to handle it other than > as a special case, but that seems ok. The main benefit I see in this is to supress the "obvious" desire to combine them with "./..". -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
At Sat, 10 Mar 2012 18:26:52 -0500, Eli Barzilay wrote: > > > Perhaps a more obvious question is why aren't all `submod' uses get > > > "." as an implicit first expression? > > > > I don't see how lets you reach a submodule from the top level or from > > within a different top-level module. > > So, this is the bit that wasn't clear to me in your original email. I > now see that this code works: > > | #lang racket/load > | > | (module my-code racket/base > | (module private racket/base > | (provide secret) > | (define secret 1)) > | (require 'private) > | (provide public) > | (define public (list secret))) > | > | (module hacker racket/base > | (require (submod 'my-code private)) > | (printf "The secret is ~a\n" secret)) > | > | (require 'hacker) > > Isn't this kind of code something that doesn't have a real use, > perhaps other than some reflection stuff (like repl uses)? If I understand what you mean, then all of the interesting uses I see involve extracting a submodule from the outside: * Extracting the `reader' submodule of a given module. * Running a `main' submodule of a given module. * Running a `test' submodule of a given module. * Getting documentation information for a given module. * Getting "extra exports" of a given module. I expect submodule references across top-level modules, as in your example above, to be relatively rare, but that's what would happen for getting "extra exports". Also, a reader for language X might want to just re-export the reader for language Y. > I first > thought that the whole point of allowing a sub-`module' would be to > have some otherwise-inaccessible private code in it (as the fictitious > author of that `my-code' module thinks). That is indeed not the goal. But it works the other direction with `(submodule* ... #f )': the enclosing module can have otherwise-inaccessible code that is accessed by the submodule (e.g., to test unexported functions). > If that's wasn't possible, > or possible only as a some semi-obscure-reflection-api then the > `submod' syntax could be simpler. I'm not sure what you mean here . > > > I also love the analogy to paths -- but using strings for them > > > doesn't look so nice, since strings are begging to be combined... > > > (I can already see myself wishing for "./../foo".) Other than the > > > obvious reader issue, would there be a problem in using `|.|' and > > > `..' for these (and making them into special module names)? > > > > Submodule identifiers are not currently constrained, and I think we > > should avoid constraining them. If we refrain from constraining > > submodule names, then `..' could be the name of a submodule. > > It just seems similar to the old ("lib.ss" "some" "path") thing in > that it's asking to be changed to something that is easier to > remember. Maybe make ".." have an implicit "." before it so there's > no need for a mysterious `"." ".."'? Yes, I think `(submod ".." ...)' can be a shorthand for `(submod "." ".." ...)'. I see no way to handle it other than as a special case, but that seems ok. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
On Mar 10, 2012, at 6:26 PM, Eli Barzilay wrote: > I first > thought that the whole point of allowing a sub-`module' would be to > have some otherwise-inaccessible private code in it (as the fictitious > author of that `my-code' module thinks). I second this impression, as I have done in previous private message. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Yesterday, Matthew Flatt wrote: > At Fri, 9 Mar 2012 16:35:25 -0500, Eli Barzilay wrote: > > > > > (require (submod 'zoo monkey-house)) > > > > > > [...] a shorthand for `(submod "." zoo)' [...] > > > > ...especially here -- why is there a quote only on the first and not > > on the second? > > That jumped out at me, too. But the first is a module path and the > second is a submodule name. For example, > > (submod zoo monkey-house) > > would mean the `monkey-house' submodule of "main.rkt" from the "zoo" > collection, not a `monkey-house' subsubmodule in a `zoo' submodule. Ah, it wasn't clear that `submod' can access submodules in other modules. (This raises another issue which I'll continue below.) In any case, that quote still bugs me... It makes more sense to me to require quotes on all of the submodule parts, but that looks worse. Maybe the problem is that it looks like the syntax is (submod X ...) for equal Xs, but it's really (submod X Y ...). This suggests a solution that makes the above (submod zoo monkey-house) less convenient (and I expect it to be fairly uncommon--?) -- something like (submod (real-module zoo) monkey-house) Can something like that work out better? (With some proper name instead of `real-module', of course.) > > Is there any meaning for (submod foo) without the > > quote (or a sting)? > > We could allow > >(submod foo) > > as equivalent to > > foo > > that is, as a reference to `foo' with an empty submodule path. This seems like a sensible thing to do, given my current understanding. > > Perhaps a more obvious question is why aren't all `submod' uses get > > "." as an implicit first expression? > > I don't see how lets you reach a submodule from the top level or from > within a different top-level module. So, this is the bit that wasn't clear to me in your original email. I now see that this code works: | #lang racket/load | | (module my-code racket/base | (module private racket/base | (provide secret) | (define secret 1)) | (require 'private) | (provide public) | (define public (list secret))) | | (module hacker racket/base | (require (submod 'my-code private)) | (printf "The secret is ~a\n" secret)) | | (require 'hacker) Isn't this kind of code something that doesn't have a real use, perhaps other than some reflection stuff (like repl uses)? I first thought that the whole point of allowing a sub-`module' would be to have some otherwise-inaccessible private code in it (as the fictitious author of that `my-code' module thinks). If that's wasn't possible, or possible only as a some semi-obscure-reflection-api then the `submod' syntax could be simpler. > > I also love the analogy to paths -- but using strings for them > > doesn't look so nice, since strings are begging to be combined... > > (I can already see myself wishing for "./../foo".) Other than the > > obvious reader issue, would there be a problem in using `|.|' and > > `..' for these (and making them into special module names)? > > Submodule identifiers are not currently constrained, and I think we > should avoid constraining them. If we refrain from constraining > submodule names, then `..' could be the name of a submodule. It just seems similar to the old ("lib.ss" "some" "path") thing in that it's asking to be changed to something that is easier to remember. Maybe make ".." have an implicit "." before it so there's no need for a mysterious `"." ".."'? -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Two days ago, Matthew Flatt wrote: > > I don't think that explicit `module' or `module*' forms will be that > common. Instead, I expect that they'll mostly be generated by > macros, such as a `main' macro or Jay's `define-test' macro. But if > they become common, or if we often want to re-export an external > module via a submodule, then we should revisit this point. Sounds to me like `module' can be common enough for segregating some code, possibly even in a different language. Something like a bit of lazy/eager code inside an otherwise eager/lazy module, or some well-isolated part of the code that uses unsafe operators, etc. Just like with the case for separate files. As for which one is more "natural", I think that the main point is to consider the dependencies: whether it more natural to expect that a submodule depends on its surrounding module or the other way. Currently, it's sub-`module*' ⇢ module ⇢ sub-`module' I think that the #f-as-the-initial-require thing being allowed in `module*' is made clear by this picture, and also the similarity between module toplevel & sub-`module' on one hand, and repl & module on the other. (In case it's not clear: I'm not complaining on anything -- I'm just providing further explanation that I think justifies the current names for the two forms.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
On Sat, Mar 10, 2012 at 11:00 AM, Matthias Felleisen wrote: > > Two minor notes: > > 1. .. is a valid binding *SL > > 2. I would much prefer 'section' over 'slice'. Think of projects as books, > modules as chapters, which consist of sections, and we may even have a need > for paragraphs one day. > +1 on part 2 there. `slice' sounds/looks like a verb to me, and we're not slicing apart modules. `section' looks more like a noun, and suggests pieces that will be put together rather than a whole being taken apart. I had also thought of `fragment', in the sense of `sentence fragment' -- it's not whole until you finish it. --Carl _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Two minor notes: 1. .. is a valid binding *SL 2. I would much prefer 'section' over 'slice'. Think of projects as books, modules as chapters, which consist of sections, and we may even have a need for paragraphs one day. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Yes, just changing the default. "raco test -r" will behave like "racket -t" unless there is a test submodule, in which case, it will actually run the tests. Jay On Fri, Mar 9, 2012 at 10:04 PM, Sam Tobin-Hochstadt wrote: > On Fri, Mar 9, 2012 at 9:54 PM, Jay McCarthy wrote: >> >> I intend to change DrDr so that it always uses "raco test -r" rather >> than "racket -t". > > I assume you mean just changing the defaults. Will this resulting in > running any less code? > > -- > sam th > sa...@ccs.neu.edu -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
On Fri, Mar 9, 2012 at 9:54 PM, Jay McCarthy wrote: > > I intend to change DrDr so that it always uses "raco test -r" rather > than "racket -t". I assume you mean just changing the defaults. Will this resulting in running any less code? -- sam th sa...@ccs.neu.edu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
I've renamed module* to slice and removed its ability to specify a language other than #f (maybe it could be a #:keyword later) I've removed when-testing because (slice test ...) is shorter than (begin-for-testing test ...) [which, btw Carl, is the best name.] I've expanded 'raco test' to support running a different submodule or running the default module (what's a good name for it?) if the submodule isn't there. I intend to change DrDr so that it always uses "raco test -r" rather than "racket -t". Jay On Fri, Mar 9, 2012 at 5:58 PM, Eli Barzilay wrote: > 30 minutes ago, Matthew Flatt wrote: >> >> How about `facet', with the terminology that "facets" are >> implemented as "submodules"? > > I like using a different term with just that explanation (ie, "a facet > is a particular kind of a submodule"). > > But I still don't like `facet' -- not only because of my non-native > point, but also because it sounds to me like facets are distinct. (So > it's weird that one facet can require another.) > > How about just `slice'? It sounds good on two levels: you split a > module into several slices, and also you split each of this by small > slices of code. You'd read code as > > (slice #|of|# main > ...) > > -- > ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: > http://barzilay.org/ Maze is Life! -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
30 minutes ago, Matthew Flatt wrote: > > How about `facet', with the terminology that "facets" are > implemented as "submodules"? I like using a different term with just that explanation (ie, "a facet is a particular kind of a submodule"). But I still don't like `facet' -- not only because of my non-native point, but also because it sounds to me like facets are distinct. (So it's weird that one facet can require another.) How about just `slice'? It sounds good on two levels: you split a module into several slices, and also you split each of this by small slices of code. You'd read code as (slice #|of|# main ...) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
I'll reply to the rest later, but two quick ones: Just now, Matthew Flatt wrote: > > How about just (submodule foo ...) be a more memorable syntax for > > (module* foo #f ...)? > > That was Jon's suggestion, and my objection is that "submodule" > means something more general than those nested modules that are > declared with `submodule'. I just realized that the main use of this (the specific combination of `module*' with #f) is for sectioning the file -- so how about going in the direction of `subsection', or to avoid the obvious problem with scribble: `subpart'? > > (BTW, there's an obvious question here of why not do that for all > > paths, so that `foo/bar/baz' can access a `bar/baz' submodule in > > `foo' or a `baz' in `foo/bar'... > > Search paths cause lots of trouble and should be avoided when > possible. This particular two-step search seem to be just barely > tolerable for `#lang', and I still worry about it; I wouldn't > suggest it if I saw a better way to accommodate existing code. I completely agree -- specifically, the "mess" that I referred to at the end of that comment was due to how things ended: I inevitably would resort to grepping text to find where some change needs to be made, I created code mostly via copy-paste, and macros would get very confusing to deal with. It was a kind of an experiment that demonstrated why this particular generalization looks really cute on paper, but in practice it is a total failure. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
At Fri, 9 Mar 2012 15:58:11 -0700, Jay McCarthy wrote: > I just pushed... > > - module** > > Like module* but combines multiple occurrences of the same submodule > name into one module* I like this direction --- and like everyone, I wish for a better name. I don't like `submodule' or `sub' for this, because it's a particular way of creating submodules, not a general form for submodules. How about `facet', with the terminology that "facets" are implemented as "submodules"? For example, a module with a `main' facet could be #lang racket/base (facet main (require racket/cmdline) (command-line .)) but you could also use `(facet main )' multiple times to add parts to the `main' submodule. > - when-testing > > An abbreviation of module** with the name test and the #f language I agree with Eli that if we have a good replacement for `submodule**', then we may not need this one. For example, I like (facet test ) better than (when-testing ) > - raco test > > Finds all the files in a directory and requires their test module Good! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
At Fri, 9 Mar 2012 16:35:25 -0500, Eli Barzilay wrote: > Two days ago, Matthew Flatt wrote: > > > > Given the term "submodule", the first thing that you're likely to try > > will work as expected: > > > > #lang racket/base > > > > (module zoo racket/base > > (provide tiger) > > (define tiger "Tony")) > > > > (require 'zoo) > > > > tiger > > > > Within `module', a module path of the form `(quote id)' refers to > > the submodule `id', if any. If there's no such submodule, then > > `(quote id)' refers to an interactively declared module, as before. > > This is *really* nice in how it's building a scope for module names, > but OTOH, it makes the quote seem more like a syntactic hack... Agreed. > > [...later...] > > > > (require (submod 'zoo monkey-house)) > > > > [...] a shorthand for `(submod "." zoo)' [...] > > ...especially here -- why is there a quote only on the first and not > on the second? That jumped out at me, too. But the first is a module path and the second is a submodule name. For example, (submod zoo monkey-house) would mean the `monkey-house' submodule of "main.rkt" from the "zoo" collection, not a `monkey-house' subsubmodule in a `zoo' submodule. > Is there any meaning for (submod foo) without the > quote (or a sting)? We could allow (submod foo) as equivalent to foo that is, as a reference to `foo' with an empty submodule path. > Perhaps a more obvious question is why aren't all `submod' uses get > "." as an implicit first expression? I don't see how lets you reach a submodule from the top level or from within a different top-level module. > > The 'zoo module path above is really a shorthand for `(submod "." > > zoo)', where "." means the enclosing module and `zoo' is its > > submodule. You could write `(submod "." zoo monkey-house)' in place > > of `(submod 'zoo monkey-house)'. > > I also love the analogy to paths -- but using strings for them doesn't > look so nice, since strings are begging to be combined... (I can > already see myself wishing for "./../foo".) Other than the obvious > reader issue, would there be a problem in using `|.|' and `..' for > these (and making them into special module names)? Submodule identifiers are not currently constrained, and I think we should avoid constraining them. If we refrain from constraining submodule names, then `..' could be the name of a submodule. > How about just (submodule foo ...) be a more > memorable syntax for (module* foo #f ...)? That was Jon's suggestion, and my objection is that "submodule" means something more general than those nested modules that are declared with `submodule'. > taking what Jay did (I think, didn't look at the code or the > followups, yet), and making this: > > (submodule E ...) > > be something that can appear anywhere in the code, expands to what > (module* main #f E ...) is doing now, *and* is allowed to be used more > than once, with all uses being collected into a single submodule. Yes, I think this is a promising direction, and we just need to find a better name than `module**'. I'll leave that discussion to the other subthread. > > The `#lang' reader form was previously defined as a shorthand for > > `#reader' where the name after the `#lang' is mangled by adding > > "/lang/reader". With submodules, `#lang' first tries using the name > > as-is and checking for a `reader' submodule; if it is found, then > > the submodule is used instead of mangling the name with > > "/lang/reader", otherwise it falls back to the old behavior. > > (BTW, there's an obvious question here of why not do that for all > paths, so that `foo/bar/baz' can access a `bar/baz' submodule in `foo' > or a `baz' in `foo/bar'... Search paths cause lots of trouble and should be avoided when possible. This particular two-step search seem to be just barely tolerable for `#lang', and I still worry about it; I wouldn't suggest it if I saw a better way to accommodate existing code. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Some more comments: * There's probably a better way to collect the expression lists than set!-ing it. * `sub' is probably a bad name, though `submodule' looks too long for this. [ * I should have said earlier that if there's a `when-testing' then the bad result is adding a `when-in-main' -- even when it begs an example of: #lang racket (when-in-main (displayln "Go see Matthias.")) ] -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
A few minutes ago, Eli Barzilay wrote: > [...] Here's what I have in mind: (Other things were broken there...) Here's the code that works now: (sub tests (require tests/eli-tester)) ; make it known before main (sub main (printf "Welcome to MY library!\n")) (define (plus x y) (+ x y)) (sub tests (test (plus 1 2) => 3)) (sub main (require (submod "." ".." tests)) (printf "Goodbye.\n")) There is the obvious output order here where there main printouts come after the test message because `tests' is instantiated before the printout forms in `main'. If the test is changed to a failure, it throws an error and you won't see that printout. Complete code below, with the same example done with rackunit. --- #lang racket/base (require (for-syntax racket/base)) (define-for-syntax subs '()) (define-syntax (sub stx) (syntax-case stx () [(_ name E ...) (identifier? #'name) (let ([sub (assq (syntax-e #'name) subs)]) (if sub (begin ((cdr sub) #'(begin E ...)) #'(begin)) (with-syntax ([(submod) (generate-temporaries #'(name))]) (let ([bodies (list (syntax-local-introduce #'(begin E ...)))]) (set! subs (cons (cons (syntax-e #'name) (case-lambda [(E) (set! bodies (cons E bodies))] [() (reverse bodies)])) subs))) (syntax-local-lift-module-end-declaration #'(submod)) #'(define-syntax (submod stx) (with-syntax ([(E* (... ...)) ((cdr (assq 'name subs)))]) (syntax-local-introduce #'(module* name #f E* (... ...])) (sub tests (require rackunit)) ; make it known before main (sub main (printf "Welcome to MY library!\n")) (define (plus x y) (+ x y)) (sub tests (check-equal? (plus 1 2) 3) (check-equal? (plus 1 2) 33)) (sub main (require (submod "." ".." tests)) (printf "Goodbye.\n")) --- -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Just now, Jay McCarthy wrote: > I just pushed... > > - module** > > Like module* but combines multiple occurrences of the same submodule > name into one module* But... it adds more stars... I don't think that there's any need for a convenience macro that does just the combining, since that feature is for macro writers anyway. Here's what I have in mind: (sub main (printf "Welcome to MY library!\n")) (sub tests (require tests/eli-tester) (printf "Testing...")) (define (plus x y) (+ x y)) (sub tests (printf ">>> ~s\n" shuffle)) (sub main (printf "Running tests...\n") (require 'tests) (printf "Goodbye.\n")) I have it almost working -- I just have one problem left (that last nested require doesn't work). > - when-testing > > An abbreviation of module** with the name test and the #f language (... As I wrote the above, I realized that `tests' is a better name for this.) In any case, I think that the above is lightweight enough that there is no need for any `when-something'. (I dislike specific names because there's more than just testing.) > - raco test > > Finds all the files in a directory and requires their test module (And it works for the specified path(s) if given?) How about generalizing this too? Something like raco run tests This way, you get the others for free since `tests' is not hard wired: raco run extensive-tests raco run docs ... -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
On Fri, Mar 9, 2012 at 5:58 PM, Jay McCarthy wrote: > I just pushed... > > - module** > > Like module* but combines multiple occurrences of the same submodule > name into one module* > > - when-testing > > An abbreviation of module** with the name test and the #f language > > - raco test > > Finds all the files in a directory and requires their test module > > I like the name 'raco test'; I'm meh on 'when-testing', I didn't want > to clash with eli-tester/test or something, but I think whatever we go > with (and I think there should be such a convenience macro) should be > similar to what happens with main; I don't know a better name for > module**. I thought of something using an @ to suggest the splicing, > but didn't like anything when I tried it. > How about "begin-for-testing"? And "extend-submodule"? --Carl _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
I just pushed... - module** Like module* but combines multiple occurrences of the same submodule name into one module* - when-testing An abbreviation of module** with the name test and the #f language - raco test Finds all the files in a directory and requires their test module I like the name 'raco test'; I'm meh on 'when-testing', I didn't want to clash with eli-tester/test or something, but I think whatever we go with (and I think there should be such a convenience macro) should be similar to what happens with main; I don't know a better name for module**. I thought of something using an @ to suggest the splicing, but didn't like anything when I tried it. Jay On Fri, Mar 9, 2012 at 11:56 AM, Jay McCarthy wrote: > I'll pushed an improved version of the test macro shortly. > > Jay > > On Fri, Mar 9, 2012 at 11:04 AM, Matthew Flatt wrote: >> At Wed, 7 Mar 2012 10:14:35 -0700, Matthew Flatt wrote: >>> I've added "submodules" to a version of Racket labeled v5.2.900.1 >> >> Submodules are now pushed to the Racket git repo. >> >> >> I haven't yet added a syntactic form to simplify >> >> (module* main #f >> ) >> >> My first idea was `main', as in >> >> (main >> ) >> >> but that seems too quiet and likely to create collisions. (It does >> create a collision in part of the contract library, which imports >> `racket/base' for syntax and defines a for-syntax `main' function.) >> >> Jon suggests `submodule': >> >> (submodule main >> ...) >> >> This suggestion has the advantage of replacing all `(module* #f >> )' combinations, and mostly I like this direction. However, >> `submodule' would be only one way to define a "submodule", while >> `submod' in a module path corresponds to "submodule" in the more >> general sense. It could be that `submodule' is on the right path and >> other terminology should change, or maybe there's a more specific word >> to use for a `(module* #f )' replacement instead of `submodule'. >> >> _ >> Racket Developers list: >> http://lists.racket-lang.org/dev > > > > -- > Jay McCarthy > Assistant Professor / Brigham Young University > http://faculty.cs.byu.edu/~jay > > "The glory of God is Intelligence" - D&C 93 -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
[Some of these points may have come up earlier, I just didn't want to lose comments so reply as I read it.] [To be clear in advance, the following should be qualified by an "I love it".] Two days ago, Matthew Flatt wrote: > > Given the term "submodule", the first thing that you're likely to try > will work as expected: > > #lang racket/base > > (module zoo racket/base > (provide tiger) > (define tiger "Tony")) > > (require 'zoo) > > tiger > > Within `module', a module path of the form `(quote id)' refers to > the submodule `id', if any. If there's no such submodule, then > `(quote id)' refers to an interactively declared module, as before. This is *really* nice in how it's building a scope for module names, but OTOH, it makes the quote seem more like a syntactic hack... > [...later...] > > (require (submod 'zoo monkey-house)) > > [...] a shorthand for `(submod "." zoo)' [...] ...especially here -- why is there a quote only on the first and not on the second? Is there any meaning for (submod foo) without the quote (or a sting)? If not, then having (submod zoo monkey-house) seems beter in building up an intuition of `submod' implicitly "quoting" the following name. Perhaps a more obvious question is why aren't all `submod' uses get "." as an implicit first expression? IIUC, this means that it works nicely without quotes, and there's only a single magical ".." thing. > The 'zoo module path above is really a shorthand for `(submod "." > zoo)', where "." means the enclosing module and `zoo' is its > submodule. You could write `(submod "." zoo monkey-house)' in place > of `(submod 'zoo monkey-house)'. I also love the analogy to paths -- but using strings for them doesn't look so nice, since strings are begging to be combined... (I can already see myself wishing for "./../foo".) Other than the obvious reader issue, would there be a problem in using `|.|' and `..' for these (and making them into special module names)? Or if there was always an implicit first ".", then there's only need for a single `..' magic token thing... (It even makes syntactic sense that (submod) is something that you can't require.) Reading the later "Design Issues" section, I see that these are indeed arbitrary. So to clarify, I propose a `submod' form that always begins with a "." (under its current semantics), with no need to use a quote, and with `..' being a special name that goes up the hierarchy. To make things connect nicely to toplevel requires, (submod foo) could also resort to the repl-entered module thing, which means that we now have: (require (submod foo)) is very common, so it can be written a bit more conveniently as (require 'foo) (But this might be pushing the description into showing them as closer than they are.) > Instead of `require'ing its enclosing module, a `module*' form can > use `#f' as its language, in which case its lexical context starts > with all of the bindings of the enclosing module (implicitly > imported) instead of with an empty lexical context. As a result, the > submodule can access bindings of the enclosing module that are not > exported: > > #lang racket/base > > (module aquarium racket/base > (define fish '(1 2)) > > (module* book #f > (append fish '(red blue > > (require (submod 'aquarium book)) The explanation for this looks reasonable, but the result looks unfortunate since the common case requires you to remember to add two special things (the `*' and `#f'). But I also really don't like to abuse `module' for both uses. How about just (submodule foo ...) be a more memorable syntax for (module* foo #f ...)? Later, I see: > As things stand, the ugly pattern `(module* main #f ...)' would be > common. Probably we should have a macro that expands to `(module* main > #f ...)'. Should the macro be called `main'? So above is my suggestion. But maybe even make it more generally convenient so it can cover the `test' use without needing a library -- taking what Jay did (I think, didn't look at the code or the followups, yet), and making this: (submodule E ...) be something that can appear anywhere in the code, expands to what (module* main #f E ...) is doing now, *and* is allowed to be used more than once, with all uses being collected into a single submodule. This way I can easily interleave regular code, main code, test code, sanity assertion code, documentation code etc. IOW, I see this as something that can be used straightforwardly with any testing tool, or made into a macro by one, or being used in the obvious way by in-line documentation tools like Neil V's mcfly thing (which is more straightforward for this than srcdoc). > A common use of `module*' is likely to be with `main', since > `racket' will load a `main' submodule (after `require'ing its > enclosing module) for a module named on its command line. For > example, if you run this program via `racket': > > #lang racket/base > >
Re: [racket-dev] submodules
30 minutes ago, Jay McCarthy wrote: > I'll pushed an improved version of the test macro shortly. Please don't put it in `racket/test', since it's not a testing thing. (I haven't got to reply to that yet, but it looks like a more general convenience macro for pulling some expressions into a submodule. In any case, `racket/test' being a wrapper test code but not being the test code is going to be very confusing.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
What about specially treating the #:main keyword when it appears in a module top-level. Everything that follows it gets wrapped in a (module* main #f), perhaps with #:niam as an end delimiter. Or maybe #:submodule , if it appears at the top-level of a module could mean that. Or maybe all new syntax: #submodule { submodule body for goes here ... } Robby On Fri, Mar 9, 2012 at 12:04 PM, Matthew Flatt wrote: > At Wed, 7 Mar 2012 10:14:35 -0700, Matthew Flatt wrote: >> I've added "submodules" to a version of Racket labeled v5.2.900.1 > > Submodules are now pushed to the Racket git repo. > > > I haven't yet added a syntactic form to simplify > > (module* main #f > ) > > My first idea was `main', as in > > (main > ) > > but that seems too quiet and likely to create collisions. (It does > create a collision in part of the contract library, which imports > `racket/base' for syntax and defines a for-syntax `main' function.) > > Jon suggests `submodule': > > (submodule main > ...) > > This suggestion has the advantage of replacing all `(module* #f > )' combinations, and mostly I like this direction. However, > `submodule' would be only one way to define a "submodule", while > `submod' in a module path corresponds to "submodule" in the more > general sense. It could be that `submodule' is on the right path and > other terminology should change, or maybe there's a more specific word > to use for a `(module* #f )' replacement instead of `submodule'. > > _ > Racket Developers list: > http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
I'll pushed an improved version of the test macro shortly. Jay On Fri, Mar 9, 2012 at 11:04 AM, Matthew Flatt wrote: > At Wed, 7 Mar 2012 10:14:35 -0700, Matthew Flatt wrote: >> I've added "submodules" to a version of Racket labeled v5.2.900.1 > > Submodules are now pushed to the Racket git repo. > > > I haven't yet added a syntactic form to simplify > > (module* main #f > ) > > My first idea was `main', as in > > (main > ) > > but that seems too quiet and likely to create collisions. (It does > create a collision in part of the contract library, which imports > `racket/base' for syntax and defines a for-syntax `main' function.) > > Jon suggests `submodule': > > (submodule main > ...) > > This suggestion has the advantage of replacing all `(module* #f > )' combinations, and mostly I like this direction. However, > `submodule' would be only one way to define a "submodule", while > `submod' in a module path corresponds to "submodule" in the more > general sense. It could be that `submodule' is on the right path and > other terminology should change, or maybe there's a more specific word > to use for a `(module* #f )' replacement instead of `submodule'. > > _ > Racket Developers list: > http://lists.racket-lang.org/dev -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
At Wed, 7 Mar 2012 10:14:35 -0700, Matthew Flatt wrote: > I've added "submodules" to a version of Racket labeled v5.2.900.1 Submodules are now pushed to the Racket git repo. I haven't yet added a syntactic form to simplify (module* main #f ) My first idea was `main', as in (main ) but that seems too quiet and likely to create collisions. (It does create a collision in part of the contract library, which imports `racket/base' for syntax and defines a for-syntax `main' function.) Jon suggests `submodule': (submodule main ...) This suggestion has the advantage of replacing all `(module* #f )' combinations, and mostly I like this direction. However, `submodule' would be only one way to define a "submodule", while `submod' in a module path corresponds to "submodule" in the more general sense. It could be that `submodule' is on the right path and other terminology should change, or maybe there's a more specific word to use for a `(module* #f )' replacement instead of `submodule'. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
Nice -- just what I wished for last spring. -- Matthias On Mar 8, 2012, at 3:39 PM, Jay McCarthy wrote: > One more thing, I anticipate that the 'main' module in my "test.rkt" > will be "raco test" and I would extend it to allow you to give a > directory that it will require (if present) all the "test" modules. > You could also have "Test" button in DrRacket. > > Jay > > On Thu, Mar 8, 2012 at 1:29 PM, Jay McCarthy wrote: >> I've made a test collecting macro. >> >> https://gist.github.com/2003201 >> >> "test.rkt" gives you 'define-test' >> >> (define-test id e ...) >> >> will create a module named 'test' that can see you local bindings >> (like module* #f) at the end of the module that contains all the code >> in "e ...". In addition, you get the (id e ...) form that adds the >> given expressions to the test module. >> >> I expect most uses will look like: >> >> (require racket/test) >> (define-test test (require rackunit)) >> >> >> >> (define f ...) >> (test ... f tests ...) >> >> >> >> (define g ...) >> (test ... g tests ...) >> >> Jay >> >> On Wed, Mar 7, 2012 at 12:07 PM, Jay McCarthy wrote: >>> I love it---especially for the test collecting macro. >>> >>> I will try to write it and report back. >>> >>> Jay >>> >>> On Wed, Mar 7, 2012 at 10:14 AM, Matthew Flatt wrote: I've added "submodules" to a version of Racket labeled v5.2.900.1 that's here: https://github.com/mflatt/submodules After we've sorted out any controversial parts of the design and after the documentation is complete, then I'll be ready to merge to the main Racket repo. Why Submodules? --- Using submodules, you can abstract (via macros) over a set of modules that have distinct dynamic extents and/or bytecode load times. You can also get a private communication channel (via binding) from a module to its submodules. Some uses: * When you run a module via `racket', if it has a `main' submodule, then the `main' module is instantiated --- but not the `main' submodules of any other modules used by the starting module. This protocol is implemented for `racket', but not yet for DrRacket. * Languages with separate read-time, configure-time, and run-time code can be defined in a single module, with the configure-time and read-time code in submodules. * A testing macro could collect test cases and put them into a separate `test' submodule', so that testing code is not run or even loaded when the module is used normally. * An improved `scribble/srcdoc' can expose documentation through a submodule instead of through re-expansion hacks. * If you want to export certain of a module's bindings only to when explicitly requested (i.e., not when the module is `require'd normally), you can export the bindings from a submodule, instead. When I first started talking about these problems last summer, I called the solution sketch "facets" or "modulets", but the design has evolved into "submodules". Nesting `module' Given the term "submodule", the first thing that you're likely to try will work as expected: #lang racket/base (module zoo racket/base (provide tiger) (define tiger "Tony")) (require 'zoo) tiger Within `module', a module path of the form `(quote id)' refers to the submodule `id', if any. If there's no such submodule, then `(quote id)' refers to an interactively declared module, as before. Submodules can be nested. To access a submodule from outside the enclosing module, use the `submod' module path form: #lang racket/base (module zoo racket/base (module monkey-house racket/base (provide monkey) (define monkey "Curious George")) (displayln "Ticket, please")) (require (submod 'zoo monkey-house)) monkey The 'zoo module path above is really a shorthand for `(submod "." zoo)', where "." means the enclosing module and `zoo' is its submodule. You could write `(submod "." zoo monkey-house)' in place of `(submod 'zoo monkey-house)'. Note that `zoo' and `monkey-house' are not bound as identifiers in the module above --- just like `module' doesn't add any top-level bindings. The namespace of modules remains separate from the namespace of variables and syntax. Along those lines, submodules are not explicitly exported, because they are implicitly public. When you run the above program, "Ticket, please" is *not* displayed. Unless a module `require's a submodule, instantiating the module does not instantiate the submodule. Similarly, instantiating a submodule >
Re: [racket-dev] submodules
At Thu, 8 Mar 2012 15:41:38 -0500, Asumu Takikawa wrote: > This sounds great! I haven't tried it out yet, but here are some > preliminary comments. > > On 2012-03-07 10:14:35 -0700, Matthew Flatt wrote: > > Submodules declared with `module' are declared locally while expanding > > a module body, which means that the submodules can be `require'd > > afterward by the enclosing module. This ordering means, however, that > > the submodule cannot `require' the enclosing module. > > > > [...] > > > > The `module*' form is like `module', but it can be used only for > > submodules, and it defers the submodule's expansion until after the > > enclosing module is otherwise expanded. As a result, a submodule using > > `module*' can `require' its enclosing module, while the enclosing > > module cannot require the submodule. > > It seems to me that `module*` maybe actually be the common case for > submodules because most of the time I would expect that you want to use > the bindings of the enclosing module. This seems true for unit tests, > driver modules, documentation (requiring for-template), and so on. > > Would it make sense to swap the `module` and `module*` forms? That's how it was at first, but I didn't like how (module m racket/base) (require 'm) was completely different at the top level and within a module. Although the correspondence between `module' at the top level and within a `module' is only approximate, it makes things much easier to explain. It's also easier to explain that `#f' is allowed as the language of a `module*', which is always a submodule, and `#f' is never allowed as the language of `module'. (In fact, there was no nested `module' until the last few hours before my post. I had `module*' as `module', and it was starting to look difficult to explain... Realizing that nearly everything was in place to support nested `module' in addition to `module*' was my biggest "aha!" moment.) > Another aspect of the syntax that I foresee being annoying is that each > module nesting adds an additional indentation level. On the other hand, I > don't see any good alternative for this. I only bring this up because > this was problematic enough in the past to invent the #lang shorthand. I don't think that explicit `module' or `module*' forms will be that common. Instead, I expect that they'll mostly be generated by macros, such as a `main' macro or Jay's `define-test' macro. But if they become common, or if we often want to re-export an external module via a submodule, then we should revisit this point. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
On Thu, Mar 8, 2012 at 1:41 PM, Asumu Takikawa wrote: > Maybe a pattern that could avoid this is to have something like > > #lang racket/main > #:main "driver.rkt" > #:tests "tests.rkt" > > which would bring in the given modules (in the filesystem) as > submodules. That way you could define submodules separately but still > package them together in order to follow any protocols for documentation > or unit testing that come about with submodules. Is that implementable > with submodules? Yes. I just tested this idea. You could expand to: include.rkt: #lang racket/base (define (f x) 1) (module* test #f (require racket/include) (include "include-tests.rkt")) include-tests.rkt: (require rackunit) (check-equal? (f 1) 1) (check-equal? (f 3) 2) Although I personally don't like it as much :) Jay -- Jay McCarthy Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
This sounds great! I haven't tried it out yet, but here are some preliminary comments. On 2012-03-07 10:14:35 -0700, Matthew Flatt wrote: > Submodules declared with `module' are declared locally while expanding > a module body, which means that the submodules can be `require'd > afterward by the enclosing module. This ordering means, however, that > the submodule cannot `require' the enclosing module. > > [...] > > The `module*' form is like `module', but it can be used only for > submodules, and it defers the submodule's expansion until after the > enclosing module is otherwise expanded. As a result, a submodule using > `module*' can `require' its enclosing module, while the enclosing > module cannot require the submodule. It seems to me that `module*` maybe actually be the common case for submodules because most of the time I would expect that you want to use the bindings of the enclosing module. This seems true for unit tests, driver modules, documentation (requiring for-template), and so on. Would it make sense to swap the `module` and `module*` forms? *** Another aspect of the syntax that I foresee being annoying is that each module nesting adds an additional indentation level. On the other hand, I don't see any good alternative for this. I only bring this up because this was problematic enough in the past to invent the #lang shorthand. Maybe a pattern that could avoid this is to have something like #lang racket/main #:main "driver.rkt" #:tests "tests.rkt" which would bring in the given modules (in the filesystem) as submodules. That way you could define submodules separately but still package them together in order to follow any protocols for documentation or unit testing that come about with submodules. Is that implementable with submodules? Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] submodules
One more thing, I anticipate that the 'main' module in my "test.rkt" will be "raco test" and I would extend it to allow you to give a directory that it will require (if present) all the "test" modules. You could also have "Test" button in DrRacket. Jay On Thu, Mar 8, 2012 at 1:29 PM, Jay McCarthy wrote: > I've made a test collecting macro. > > https://gist.github.com/2003201 > > "test.rkt" gives you 'define-test' > > (define-test id e ...) > > will create a module named 'test' that can see you local bindings > (like module* #f) at the end of the module that contains all the code > in "e ...". In addition, you get the (id e ...) form that adds the > given expressions to the test module. > > I expect most uses will look like: > > (require racket/test) > (define-test test (require rackunit)) > > > > (define f ...) > (test ... f tests ...) > > > > (define g ...) > (test ... g tests ...) > > Jay > > On Wed, Mar 7, 2012 at 12:07 PM, Jay McCarthy wrote: >> I love it---especially for the test collecting macro. >> >> I will try to write it and report back. >> >> Jay >> >> On Wed, Mar 7, 2012 at 10:14 AM, Matthew Flatt wrote: >>> I've added "submodules" to a version of Racket labeled v5.2.900.1 >>> that's here: >>> >>> https://github.com/mflatt/submodules >>> >>> After we've sorted out any controversial parts of the design and after >>> the documentation is complete, then I'll be ready to merge to the main >>> Racket repo. >>> >>> >>> Why Submodules? >>> --- >>> >>> Using submodules, you can abstract (via macros) over a set of modules >>> that have distinct dynamic extents and/or bytecode load times. You can >>> also get a private communication channel (via binding) from a module >>> to its submodules. >>> >>> Some uses: >>> >>> * When you run a module via `racket', if it has a `main' submodule, >>> then the `main' module is instantiated --- but not the `main' >>> submodules of any other modules used by the starting module. This >>> protocol is implemented for `racket', but not yet for DrRacket. >>> >>> * Languages with separate read-time, configure-time, and run-time >>> code can be defined in a single module, with the configure-time and >>> read-time code in submodules. >>> >>> * A testing macro could collect test cases and put them into a >>> separate `test' submodule', so that testing code is not run or even >>> loaded when the module is used normally. >>> >>> * An improved `scribble/srcdoc' can expose documentation through a >>> submodule instead of through re-expansion hacks. >>> >>> * If you want to export certain of a module's bindings only to when >>> explicitly requested (i.e., not when the module is `require'd >>> normally), you can export the bindings from a submodule, instead. >>> >>> When I first started talking about these problems last summer, I >>> called the solution sketch "facets" or "modulets", but the design >>> has evolved into "submodules". >>> >>> >>> Nesting `module' >>> >>> >>> Given the term "submodule", the first thing that you're likely to try >>> will work as expected: >>> >>> #lang racket/base >>> >>> (module zoo racket/base >>> (provide tiger) >>> (define tiger "Tony")) >>> >>> (require 'zoo) >>> >>> tiger >>> >>> Within `module', a module path of the form `(quote id)' refers to the >>> submodule `id', if any. If there's no such submodule, then `(quote >>> id)' refers to an interactively declared module, as before. >>> >>> Submodules can be nested. To access a submodule from outside the >>> enclosing module, use the `submod' module path form: >>> >>> #lang racket/base >>> >>> (module zoo racket/base >>> (module monkey-house racket/base >>> (provide monkey) >>> (define monkey "Curious George")) >>> (displayln "Ticket, please")) >>> >>> (require (submod 'zoo monkey-house)) >>> >>> monkey >>> >>> The 'zoo module path above is really a shorthand for `(submod "." >>> zoo)', where "." means the enclosing module and `zoo' is its >>> submodule. You could write `(submod "." zoo monkey-house)' in >>> place of `(submod 'zoo monkey-house)'. >>> >>> Note that `zoo' and `monkey-house' are not bound as identifiers in the >>> module above --- just like `module' doesn't add any top-level >>> bindings. The namespace of modules remains separate from the namespace >>> of variables and syntax. Along those lines, submodules are not >>> explicitly exported, because they are implicitly public. >>> >>> When you run the above program, "Ticket, please" is *not* displayed. >>> Unless a module `require's a submodule, instantiating the module does >>> not instantiate the submodule. Similarly, instantiating a submodule >>> does not imply instantiating its enclosing module. >>> >>> Furthermore, if you compile the above example to bytecode and run it, >>> the bytecode for `zoo' is not loaded. Only the bytecode for the >>> top-level module and `monkey-house' is loaded. >>> >>> >>> Nesting `module*' >>> ---
Re: [racket-dev] submodules
I've made a test collecting macro. https://gist.github.com/2003201 "test.rkt" gives you 'define-test' (define-test id e ...) will create a module named 'test' that can see you local bindings (like module* #f) at the end of the module that contains all the code in "e ...". In addition, you get the (id e ...) form that adds the given expressions to the test module. I expect most uses will look like: (require racket/test) (define-test test (require rackunit)) (define f ...) (test ... f tests ...) (define g ...) (test ... g tests ...) Jay On Wed, Mar 7, 2012 at 12:07 PM, Jay McCarthy wrote: > I love it---especially for the test collecting macro. > > I will try to write it and report back. > > Jay > > On Wed, Mar 7, 2012 at 10:14 AM, Matthew Flatt wrote: >> I've added "submodules" to a version of Racket labeled v5.2.900.1 >> that's here: >> >> https://github.com/mflatt/submodules >> >> After we've sorted out any controversial parts of the design and after >> the documentation is complete, then I'll be ready to merge to the main >> Racket repo. >> >> >> Why Submodules? >> --- >> >> Using submodules, you can abstract (via macros) over a set of modules >> that have distinct dynamic extents and/or bytecode load times. You can >> also get a private communication channel (via binding) from a module >> to its submodules. >> >> Some uses: >> >> * When you run a module via `racket', if it has a `main' submodule, >> then the `main' module is instantiated --- but not the `main' >> submodules of any other modules used by the starting module. This >> protocol is implemented for `racket', but not yet for DrRacket. >> >> * Languages with separate read-time, configure-time, and run-time >> code can be defined in a single module, with the configure-time and >> read-time code in submodules. >> >> * A testing macro could collect test cases and put them into a >> separate `test' submodule', so that testing code is not run or even >> loaded when the module is used normally. >> >> * An improved `scribble/srcdoc' can expose documentation through a >> submodule instead of through re-expansion hacks. >> >> * If you want to export certain of a module's bindings only to when >> explicitly requested (i.e., not when the module is `require'd >> normally), you can export the bindings from a submodule, instead. >> >> When I first started talking about these problems last summer, I >> called the solution sketch "facets" or "modulets", but the design >> has evolved into "submodules". >> >> >> Nesting `module' >> >> >> Given the term "submodule", the first thing that you're likely to try >> will work as expected: >> >> #lang racket/base >> >> (module zoo racket/base >> (provide tiger) >> (define tiger "Tony")) >> >> (require 'zoo) >> >> tiger >> >> Within `module', a module path of the form `(quote id)' refers to the >> submodule `id', if any. If there's no such submodule, then `(quote >> id)' refers to an interactively declared module, as before. >> >> Submodules can be nested. To access a submodule from outside the >> enclosing module, use the `submod' module path form: >> >> #lang racket/base >> >> (module zoo racket/base >> (module monkey-house racket/base >> (provide monkey) >> (define monkey "Curious George")) >> (displayln "Ticket, please")) >> >> (require (submod 'zoo monkey-house)) >> >> monkey >> >> The 'zoo module path above is really a shorthand for `(submod "." >> zoo)', where "." means the enclosing module and `zoo' is its >> submodule. You could write `(submod "." zoo monkey-house)' in >> place of `(submod 'zoo monkey-house)'. >> >> Note that `zoo' and `monkey-house' are not bound as identifiers in the >> module above --- just like `module' doesn't add any top-level >> bindings. The namespace of modules remains separate from the namespace >> of variables and syntax. Along those lines, submodules are not >> explicitly exported, because they are implicitly public. >> >> When you run the above program, "Ticket, please" is *not* displayed. >> Unless a module `require's a submodule, instantiating the module does >> not instantiate the submodule. Similarly, instantiating a submodule >> does not imply instantiating its enclosing module. >> >> Furthermore, if you compile the above example to bytecode and run it, >> the bytecode for `zoo' is not loaded. Only the bytecode for the >> top-level module and `monkey-house' is loaded. >> >> >> Nesting `module*' >> - >> >> Submodules declared with `module' are declared locally while expanding >> a module body, which means that the submodules can be `require'd >> afterward by the enclosing module. This ordering means, however, that >> the submodule cannot `require' the enclosing module. The submodule >> also sees no bindings of the enclosing module; it starts with an empty >> lexical context. >> >> The `module*' form is like `module', but it can be used only for >> submodule
Re: [racket-dev] submodules
I love it---especially for the test collecting macro. I will try to write it and report back. Jay On Wed, Mar 7, 2012 at 10:14 AM, Matthew Flatt wrote: > I've added "submodules" to a version of Racket labeled v5.2.900.1 > that's here: > > https://github.com/mflatt/submodules > > After we've sorted out any controversial parts of the design and after > the documentation is complete, then I'll be ready to merge to the main > Racket repo. > > > Why Submodules? > --- > > Using submodules, you can abstract (via macros) over a set of modules > that have distinct dynamic extents and/or bytecode load times. You can > also get a private communication channel (via binding) from a module > to its submodules. > > Some uses: > > * When you run a module via `racket', if it has a `main' submodule, > then the `main' module is instantiated --- but not the `main' > submodules of any other modules used by the starting module. This > protocol is implemented for `racket', but not yet for DrRacket. > > * Languages with separate read-time, configure-time, and run-time > code can be defined in a single module, with the configure-time and > read-time code in submodules. > > * A testing macro could collect test cases and put them into a > separate `test' submodule', so that testing code is not run or even > loaded when the module is used normally. > > * An improved `scribble/srcdoc' can expose documentation through a > submodule instead of through re-expansion hacks. > > * If you want to export certain of a module's bindings only to when > explicitly requested (i.e., not when the module is `require'd > normally), you can export the bindings from a submodule, instead. > > When I first started talking about these problems last summer, I > called the solution sketch "facets" or "modulets", but the design > has evolved into "submodules". > > > Nesting `module' > > > Given the term "submodule", the first thing that you're likely to try > will work as expected: > > #lang racket/base > > (module zoo racket/base > (provide tiger) > (define tiger "Tony")) > > (require 'zoo) > > tiger > > Within `module', a module path of the form `(quote id)' refers to the > submodule `id', if any. If there's no such submodule, then `(quote > id)' refers to an interactively declared module, as before. > > Submodules can be nested. To access a submodule from outside the > enclosing module, use the `submod' module path form: > > #lang racket/base > > (module zoo racket/base > (module monkey-house racket/base > (provide monkey) > (define monkey "Curious George")) > (displayln "Ticket, please")) > > (require (submod 'zoo monkey-house)) > > monkey > > The 'zoo module path above is really a shorthand for `(submod "." > zoo)', where "." means the enclosing module and `zoo' is its > submodule. You could write `(submod "." zoo monkey-house)' in > place of `(submod 'zoo monkey-house)'. > > Note that `zoo' and `monkey-house' are not bound as identifiers in the > module above --- just like `module' doesn't add any top-level > bindings. The namespace of modules remains separate from the namespace > of variables and syntax. Along those lines, submodules are not > explicitly exported, because they are implicitly public. > > When you run the above program, "Ticket, please" is *not* displayed. > Unless a module `require's a submodule, instantiating the module does > not instantiate the submodule. Similarly, instantiating a submodule > does not imply instantiating its enclosing module. > > Furthermore, if you compile the above example to bytecode and run it, > the bytecode for `zoo' is not loaded. Only the bytecode for the > top-level module and `monkey-house' is loaded. > > > Nesting `module*' > - > > Submodules declared with `module' are declared locally while expanding > a module body, which means that the submodules can be `require'd > afterward by the enclosing module. This ordering means, however, that > the submodule cannot `require' the enclosing module. The submodule > also sees no bindings of the enclosing module; it starts with an empty > lexical context. > > The `module*' form is like `module', but it can be used only for > submodules, and it defers the submodule's expansion until after the > enclosing module is otherwise expanded. As a result, a submodule using > `module*' can `require' its enclosing module, while the enclosing > module cannot require the submodule. > > A ".." in a `submod' form goes up the submodule hierarchy, so that > `(submod "." "..")' is a reference to the enclosing module: > > #lang racket/base > > (module aquarium racket/base > (provide fish) > (define fish '(1 2)) > > (module* book racket/base > (require (submod "." "..")) > (append fish '(red blue > > (require (submod 'aquarium book)) > > Instead of `require'ing its enclosing module, a `module*' form can use > `#f' as its language, in which case its lexical
[racket-dev] submodules
I've added "submodules" to a version of Racket labeled v5.2.900.1 that's here: https://github.com/mflatt/submodules After we've sorted out any controversial parts of the design and after the documentation is complete, then I'll be ready to merge to the main Racket repo. Why Submodules? --- Using submodules, you can abstract (via macros) over a set of modules that have distinct dynamic extents and/or bytecode load times. You can also get a private communication channel (via binding) from a module to its submodules. Some uses: * When you run a module via `racket', if it has a `main' submodule, then the `main' module is instantiated --- but not the `main' submodules of any other modules used by the starting module. This protocol is implemented for `racket', but not yet for DrRacket. * Languages with separate read-time, configure-time, and run-time code can be defined in a single module, with the configure-time and read-time code in submodules. * A testing macro could collect test cases and put them into a separate `test' submodule', so that testing code is not run or even loaded when the module is used normally. * An improved `scribble/srcdoc' can expose documentation through a submodule instead of through re-expansion hacks. * If you want to export certain of a module's bindings only to when explicitly requested (i.e., not when the module is `require'd normally), you can export the bindings from a submodule, instead. When I first started talking about these problems last summer, I called the solution sketch "facets" or "modulets", but the design has evolved into "submodules". Nesting `module' Given the term "submodule", the first thing that you're likely to try will work as expected: #lang racket/base (module zoo racket/base (provide tiger) (define tiger "Tony")) (require 'zoo) tiger Within `module', a module path of the form `(quote id)' refers to the submodule `id', if any. If there's no such submodule, then `(quote id)' refers to an interactively declared module, as before. Submodules can be nested. To access a submodule from outside the enclosing module, use the `submod' module path form: #lang racket/base (module zoo racket/base (module monkey-house racket/base (provide monkey) (define monkey "Curious George")) (displayln "Ticket, please")) (require (submod 'zoo monkey-house)) monkey The 'zoo module path above is really a shorthand for `(submod "." zoo)', where "." means the enclosing module and `zoo' is its submodule. You could write `(submod "." zoo monkey-house)' in place of `(submod 'zoo monkey-house)'. Note that `zoo' and `monkey-house' are not bound as identifiers in the module above --- just like `module' doesn't add any top-level bindings. The namespace of modules remains separate from the namespace of variables and syntax. Along those lines, submodules are not explicitly exported, because they are implicitly public. When you run the above program, "Ticket, please" is *not* displayed. Unless a module `require's a submodule, instantiating the module does not instantiate the submodule. Similarly, instantiating a submodule does not imply instantiating its enclosing module. Furthermore, if you compile the above example to bytecode and run it, the bytecode for `zoo' is not loaded. Only the bytecode for the top-level module and `monkey-house' is loaded. Nesting `module*' - Submodules declared with `module' are declared locally while expanding a module body, which means that the submodules can be `require'd afterward by the enclosing module. This ordering means, however, that the submodule cannot `require' the enclosing module. The submodule also sees no bindings of the enclosing module; it starts with an empty lexical context. The `module*' form is like `module', but it can be used only for submodules, and it defers the submodule's expansion until after the enclosing module is otherwise expanded. As a result, a submodule using `module*' can `require' its enclosing module, while the enclosing module cannot require the submodule. A ".." in a `submod' form goes up the submodule hierarchy, so that `(submod "." "..")' is a reference to the enclosing module: #lang racket/base (module aquarium racket/base (provide fish) (define fish '(1 2)) (module* book racket/base (require (submod "." "..")) (append fish '(red blue (require (submod 'aquarium book)) Instead of `require'ing its enclosing module, a `module*' form can use `#f' as its language, in which case its lexical context starts with all of the bindings of the enclosing module (implicitly imported) instead of with an empty lexical context. As a result, the submodule can access bindings of the enclosing module that are not exported: #lang racket/base (module aquarium racket/base (define fish '(1 2)) (module* book #f (append fish '(red blue)