Re: [racket-users] Re: Is it possible to make submodules with private names?

2020-05-23 Thread rocketnia

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
>  
> 
> "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 " to get my packages or 
(require ) 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/mymod

Re: [racket-users] Re: Is it possible to make submodules with private names?

2020-05-23 Thread Philip McGrath
On Sat, May 23, 2020 at 5:04 PM Simon Schlee  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
. 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.

-Philip

-- 
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/CAH3z3gY4e%2BsvAQhHrtj21%3DJ2-%2B6GvVDhPpMY0PkiqbjzaNjOsQ%40mail.gmail.com.


[racket-users] Re: Is it possible to make submodules with private names?

2020-05-23 Thread Simon Schlee
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.

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

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.

These are just my intuitions, I have only limited experience with modules 
and functors with my own toy language experiments.

Maybe if you need very dynamic/custom behavior, instead of generating 
module files:
You could create a program which creates and evaluates certain in memory 
generated module-forms at runtime, attaches them to a namespace and then 
runs the other code with that namespace.
Allowing that code or your library to require and interact with the 
dynamically generated module.

So far my namespace usage was limited to attaching certain modules, but I 
think this is possible.
Think of it as a custom program launcher that acts like a 
"scripted"/automated interactive repl session.

Simon

-- 
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/be993550-da25-496b-abcb-705db0473a28%40googlegroups.com.