Thanks everyone for the perspectives and techniques you've offered so far.

I've found a flaw in my gensym technique, even at the command line. If I 
run "raco make badlang.rkt", "raco make badlibrary.rkt", and "raco make 
client.rkt", the last command has an error. That's because the gensym is 
marshaled into both badlang_rkt.zo and badlibrary_rkt.zo. When "raco make 
client.rkt" unmarshals both those files, it gets two different gensyms.

I suppose I would've liked badlibrary_rkt.zo to marshal the gensym in a way 
that "remembered" which gensym in badlang_rkt.zo it came from. Perhaps 
that's not how gensym marshaling works. :)

So I don't think DrRacket's behavior shows any signs of a problem. In fact, 
it alerted me to the problem sooner than the command line did.


On Saturday, May 23, 2020 at 2:04:00 PM UTC-7, Simon Schlee wrote:

> I think pollen uses racket's compiled directories to store some of its own 
> cached/generated code, maybe a similar technique could be helpful for you.
>
> Do you want to create submodules for arbitrary modules or only for modules 
> using a certain library or language?
> When its the latter I think its a community coordination issue.
>

The latter. My compile-time-arguments system wouldn't need to interact with 
modules that don't receive or supply arguments. The modules that do receive 
or supply these arguments would refer to operations my library, so I can 
generate the code I need during those modules' usual compilation process. 
So I don't foresee any need to create files in the compiled/ directory or 
(as you mention later on) to generate code at run time.

I suppose I did consider using `eval` or `dynamic-require` so that I could 
use `parameterize` to supply my compile-time arguments. But I do consider 
it important that the module is actually compiled with those arguments, and 
that the compilation result can be reused rather than being generated each 
time. A module that supplies a lot of compile-time arguments to other 
modules might take a while to compile (since it has to compile customized 
variations of its dependencies as well), but at least that cost isn't paid 
at run time.


On Saturday, May 23, 2020 at 2:04:00 PM UTC-7, Simon Schlee wrote:

>
> I can understand wanting to encapsulate everything but it seems that 
> module names are expected to be public interned symbols in the current 
> implementation:
>
> https://docs.racket-lang.org/reference/Module_Names_and_Loading.html?q=module#%28def._%28%28quote._~23~25kernel%29._make-resolved-module-path%29%29
>  
> <https://www.google.com/url?q=https%3A%2F%2Fdocs.racket-lang.org%2Freference%2FModule_Names_and_Loading.html%3Fq%3Dmodule%23%2528def._%2528%2528quote._~23~25kernel%2529._make-resolved-module-path%2529%2529&sa=D&sntz=1&usg=AFQjCNEgB6-uIKbaC00oT2lmjDN7ATjxmw>
> "A resolved module path is interned. That is, if two resolved module path 
> values encapsulate paths that are equal?, then the resolved module path 
> values are eq?."
> I think gensyms are not allowed, because they are not interned.
>

The resolved module path as a whole is interned, but that doesn't mean 
every symbol within it is interned.

As the part you quoted says, the resolved paths are interned in the 
specific sense that if the paths to encapsulate are `equal?`, then the 
resolved paths are `eq?`.

If I pass in paths that contain two distinct uninterned symbols, those 
paths aren't `equal?`, so the documentation isn't implying that the 
resolved paths would be `eq?`. Currently, they're not `eq?`:

(define foo
  (make-resolved-module-path (list 'mycollection/mylib 
(string->uninterned-symbol "x"))))
(define bar
  (make-resolved-module-path (list 'mycollection/mylib 
(string->uninterned-symbol "x"))))
(eq? foo bar)
; returns #f

I suppose I'm not really sure what good it is to use an uninterned symbol 
as a submodule name. It seems that after the module is compiled, one of the 
only ways another part of the system can do anything with that submodule is 
by digging into the code using `module-compiled-submodules`. Perhaps a 
module can refer to its *own* gensym-named submodules at least.


On Saturday, May 23, 2020 at 3:40:37 PM UTC-7, gneuner2 wrote:
>
>
> Why not name your modules using UUIDs or similar generated random 
> strings?  You can't ever be certain that a generated name won't 
> conflict, but you can make the probability very, very small.
>

That could be good.

For Racket purposes, I'm not quite so worried about namespace collisions 
that I'd ask people to "raco pkg install <uuid>" to get my packages or 
(require <uuid>) to get my collections. Likewise, I probably wouldn't use a 
UUID for this submodule name. I just thought that if the Racket module 
system already offered a way to guarantee noncolliding submodule names, I 
oughta use it.

Instead, I'll probably settle for something like 
`private/generated-by/mycollection/mymodule`. This way, another library 
usually won't conflict with it unless it has its own 
`mycollection/mymodule` module that conflicts with mine at installation 
time. The rest of the name makes it pretty clear that it's not a stable 
interface for the public, and it gives the user a small clue to understand 
how this invader ended up in their module.


On Saturday, May 23, 2020 at 4:16:43 PM UTC-7, Philip McGrath wrote:
>
> On Sat, May 23, 2020 at 5:04 PM Simon Schlee <schle...@gmail.com 
> <javascript:>> wrote:
>
>> I also would find it interesting to have something functor like, in the 
>> sense of being able to create parameterized module instances.
>> My guess is that constructs like that are difficult to optimize and the 
>> separation between runtime and compile time can become extremely blurry.
>> To the point that certain dynamic constructs would cause big chunks of 
>> code to become ready for compiling at run-time only and at that time an 
>> interpreter might be faster.
>>
>
> In fact, Racket has such a construct, units 
> <https://docs.racket-lang.org/guide/units.html>. They are first-class 
> values, with run-time operations to link and invoke them, and they allowing 
> for cyclic dependencies and multiple instantiations of a given unit.
>
> One of the major design goals of units was support for separate 
> compilation (units predate `module` in Racket), which may rule them out for 
> Nia's goal of modules with "optional *compile-time* arguments" per se.
>
> I guess I'm interested in what sorts of things these optional arguments 
> might be used for: if dealing with the arguments could instead be done at 
> link- or invoke-time, you might be able to use units to implement this 
> module system. Regardless, I recommend anyone thinking about implementing a 
> unit-like system look closely at units first: even when I ultimately ended 
> up implementing my own unit-like system to meet a specific need (this was 
> part of my RacketCon talk), my experience with units was very valuable in 
> doing so.
>

I've actually thought about how units could play into this! If this system 
had seamless support for optional run-time arguments alongside the 
compile-time ones, then the result of supplying those run time arguments 
would need to be something like a unit. And maybe the run-time entity those 
arguments are supplied *to* would need to be something like a unit as well. 
Actual Racket units could be involved, or maybe there'd merely be a 
"unit-like system" like you say.

But I don't expect to build that feature anytime soon. I've only thought it 
through well enough to get a rough idea of how it would fit into the 
design. In the meantime, normal Racket run time abstractions exist, 
including functions and units, and people can use those. :)

In the short term, I don't want to put very much work into this 
compile-time arguments system; there are other projects I feel I should be 
applying that attention to. I'm aiming to build just the minimal set of 
functionality I need, while giving it enough room to grow into something 
better later on. The reason I mentioned it here was to help demonstrate a 
concrete reason I was interested in private submodules (and this technique 
that turned out to be flawed).


Thank you everyone,
Nia

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/a457e984-87d8-4d5b-b048-28990fa10897%40googlegroups.com.

Reply via email to