On 24-Mar-09, at 2:25 PM, Per Eckerdal wrote:
Concurrently Guillaume Cartier was working on improving the startup time of Jedi. Guillaume expressed the need to statically link some of the modules of the Jazz system into the executable (to avoid the startup delay caused by accessing the filesystem for many small modules). He would like the modules to be linked into the executable, but *not initialized*. Instead the modules should only be initialized if and when they are actually used by the application.
I think that's a great idea. It would be a generally useful tool, for module systems and some other applications as well.
I think an important part of making a module system work well is not to have a (load) function that "loads" a module, but insted have an import/use construct that declaratively states that this module needs this other module to work. It is then up to the module system when and how to load the modules. This makes it easier to analyze dependencies and, imho, yields clearer code.
Yes I completely agree. However, at the lowest level the system must perform some operation which makes the module usable to the program. In other words, an "import" or "use" construct must rely on lower level operations to do its work. I want to brainstorm on what should be provided at the lowest level. Then this lower level could be used to implement a higher level module system on top.
- How are modules identified? In other words what is the key that
is used to access the previously loaded module table? One simple approach would be to use the filename as the key, but this does not work in a static linking model where the modules have been linked with the executable (and the executable is meant to be installed on a different machine). So what is a good way to identify modules unambiguously? A hash? A user supplied "module id"? Should modules have version numbers?
There are of course many possible solutions, but I would try to do it completely transparent for the user. If the static linking model is to work well, the user shouldn't have to think about it, and the same code should work regardless of how the code is linked.
It should be possible to build an abstraction that seems to work by filename, with some automatic trickery behind the scenes for other linking strategies.
I find filenames to be too brittle of an identifier for modules. It shouldn't matter where a module is located.
- For interactive development there is a need to force the loading
of modules, even if they have been loaded already. How should this be expressed by the user?
In the system I have written this is done simply by re-importing the module from the REPL. The module system can see (with a hash and/or with timestamps) that the module is updated and reloads it. It has simply never been a problem.
You mean because the "last modification" time of the source is newer than what was recorded when the module was loaded? What happens if module A requires B, and B has changed but A hasn't. Will your module system reload B if you ask to load A again? Moreover, often the initialisation of a module depends on the initialisation of the module it depends on. In my example, module B might create a unique key for a record type (i.e. generative records) which is then used by A's initialisation to instantiate some records of that type. So in this case it is necessary to reload A even if it hasn't changed. I believe the safest approach is to reload the whole dependence graph of the module to be reloaded.
Marc