Currently, trying to (load x) twice results in an error. This is a problem when A and B each load C and a fourth file tries to load A and B. It's also a problem when using (include x) to debug a file which loads another.
So I would suggest the load should be a no-op in the case that the file has already been loaded.
I would submit a patch, but doing the obvious to setup.c:___os_load_object_file doesn't seem to work.
AGL
Afficher les réponses par date
At 18:42 Uhr +0100 08.08.2005, Adam Langley wrote:
Currently, trying to (load x) twice results in an error. This is a problem when A and B each load C and a fourth file tries to load A and B. It's also a problem when using (include x) to debug a file which loads another.
So I would suggest the load should be a no-op in the case that the file has already been loaded.
It's a problem chjmodule is meant to solve (by only load'ing or rebuilding a module again if it has changed). http://scheme.mine.nu/gambit/chjmodule/
Be aware though that it's still buggy, especially it doesn't always reimport bindings if you reload a module. So in practice it may not yet solve your problem, but I will make it work well as soon as I find time (in a few weeks). Currently I use (namespace "") while I'm developping a module (so the reimport bug is not an issue).
Christian.
On 8/8/05, Adam Langley alangley@gmail.com wrote:
So I would suggest the load should be a no-op in the case that the file has already been loaded.
Here's a patch to do this. It's a tiny patch (apply in /lib) but, as ever, it's the finding of the lines to change which is an issue.
AGL
Hello Adam
I'm wondering why you need that patch. I think it's a bad idea to suppress module load errors, since it then would silently do nothing where as the user expects load to do something, which is bad. Whereas you could simply catch the exception if you really want to try to load without the program terminating:
(define MODULE_ALREADY_LOADED ((c-lambda () int "___result=___FIX(___MODULE_ALREADY_LOADED)")))
(define (load* x) (with-exception-catcher (lambda(e) (or (and (os-exception? e) (= (os-exception-code e) MODULE_ALREADY_LOADED))) (raise e))) (lambda() (load x))))
(untested)
Checking the exception code against a constant which is only defined in C might look a bit awkward, an exception subtype like one with predicate os-module-already-loaded-exception? might be cleaner, so I would suggest to change that instead.
Some words about the logic behind the error (from how I see it): load on source code can simply reload the source, there's no implementation problem with that. It does two things, reparse the source (which may have changed), and re-run it's body (which means, perform bindings, thus overwriting bindings which may have changed since after the first load).
Loading a binary however only loads the precompiled object, thus ignoring any possible changes in the source. It still performs initializations/bindings. A user loading that object again might expect it at least to do initializations/bindings again. But now there's the problem that loading (=linking) the same binary object file multiple times is not possible at all on some systems, and on those where it is (e.g. linux) it requires unloading it first (which may be problematic in the presence of threads, how do you know if some code is still executing in the old code?). Would it be worthwhile to implement such unloading on systems where that works? Might be for some other reasons (not increasing virtual memory with each load -- not that I think this is a real problem: it's basically just wasted disk space, that's all). But since it wouldn't recompile the sources anyway, another layer on top is what users will want anyway (-> see chjmodule). So the best thing it can do is raise an error.
Christian.