SideEffects wrote:Thank you Dave, that is the best explanation I've read yet. Until now I hadn't really understood the relationship between LOAD and packages. I had assumed that the IN-PACKAGE was somehow doing the loading, or that asdf was needed to load packages. I don't think this is made clear in Siebel's book either.
You're welcome. Glad that I could help. As Ramarren says, ASDF is simply a library, nothing more. It's simply automating all this loading and compiling using yet another dependency data structure that you create in another file.
If I understand what you wrote, and I have (load "B.cl") inside A.cl, and then I enter (load (compile-file "A.cl")), then the (compile-file "A.cl") will also compile the code in B.cl, right?
Not really. The problem is in your use of "compile" vs. "load." Again, these are only semi-related things. LOAD will load either files that are compiled or uncompiled. It doesn't matter. The effect is the same: the file is loaded and the forms that are in the file (whether compiled or not) essentially are "executed" as if they had been typed in the REPL. So, if you have a (LOAD "B.LISP") inside A.LISP, and you (LOAD "A.LISP"), then during the loading of A.LISP, it will load B.LISP, as you might expect (that's why the BIGHONKINGFILE.LISP example works).
Now, when you (COMPILE-FILE "A.LISP"), it will only compile A.LISP. However, it will compile code into the A.FASL that will execute a (LOAD "B.LISP"), but you'll still have to compile B.LISP separately. So, if you (LOAD (COMPILE-FILE "A.LISP")) it will compile A.LISP and load the resulting FASL, but that won't compile B.LISP. But because there is a LOAD form inside A.LISP, it will load B.LISP.
This whole thing is something a defsystem like ASDF will manage do for you. You can use it to recompile all your code and it will do so in the right order, again with dependencies being satisfied. This can get hairy, for instance, when you have files that have macro libraries in them that are only needed at compile-time, and not at runtime, for instance, but again, that's for the advanced class.
Another thing to note is that some implementations will try to load exactly
what you say to load. Thus, if you say (LOAD "B.LISP") inside A.LISP, then when you execute it, the loader might look for exactly
file B.LISP, not B.FASL if B has been compiled. Most implementations allow you to say (LOAD "B") and it will automatically try to load B.FASL first, and then fall back to B.LISP if it can't find B.FASL. Some implementations will do the right thing in any case. My habit is to only say "B" and let the implementation do the right thing.
So, again, loading is not related to compiling, other than the loader can deal with loading compiled files, and you can insert a LOAD form inside a compiled file just as if you put it into the source file. The effect of loading a compiled file should be the same as loading the uncompiled version of the same file, again with some advanced stuff happening when you use EVAL-WHEN.