Simple explanation of packages?

Discussion of Common Lisp
ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Simple explanation of packages?

Post by ramarren » Fri Aug 28, 2009 6:31 am

SideEffects wrote: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?
As a side note, usually the extension given to Common Lisp source files is ".lisp", although ".cl" also happens, if rarely.

LOAD is a function. Functions are not executed during compilation. You would have to use EVAL-WHEN (or "#.", but that is even less sane) for the loading of the second file to happen before the rest of the first file is compiled. Doing it this way is not common, because it quickly gets messy as systems grow in size, and ASDF is pretty simple anyway.

Note that ASDF is a perfectly normal library, so if you wanted to you could duplicate its functionality (ie. it is not "needed" for anything), but why?

findinglisp
Posts: 447
Joined: Sat Jun 28, 2008 7:49 am
Location: Austin, TX
Contact:

Re: Simple explanation of packages?

Post by findinglisp » Sun Aug 30, 2009 7:11 pm

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?

S.E.
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.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/

Post Reply