ASDF PSA: defpackage in .asd is not obligatory
Wednesday, November 25th, 2009 17:06There seems to be a recurring misconception about writing .asd files. It is not necessary to start your asd with (defpackage :foo.system ...) (in-package :foo.system) to “avoid polluting the package asdf loads your system in”.
Every time an .asd file is loaded, ASDF creates a fresh package to load it in. The relevant code from ASDF is:
(defun make-temporary-package ()
(flet ((try (counter)
(ignore-errors
(make-package (format nil "ASDF~D" counter)
:use '(:cl :asdf)))))
(do* ((counter 0 (+ counter 1))
(package (try counter) (try counter)))
(package package))))
(defun find-system (...)
...
(let ((package (make-temporary-package)))
(unwind-protect
(let ((*package* package))
...
(load on-disk))
(delete-package package)))
...)
So, whenever you load an asd file, the package is fresh and :uses CL and ASDF.
There are reasons to define a package for your asdf system definition.
- If you are creating any classes, such as custom ASDF component types, then, since classes are not garbage collected (MOP specifies that the list of a class's subclasses can be retrieved, and no implementation I know of uses weak references for the purpose), naming them with symbols in a consistent package (rather than the asdf temporary package) ensures that reloading the system definition does not create useless additional copies of the classes.
- If you are defining functions or other named entities in your system definition (which should of course only be done if they are also necessary to load the system) and want to be able to refer to them, such as for debugging, with nice interned symbol names.
- If you want to be able to
(load "foo.asd")rather than going through asdf:find-system.
The disadvantages I can think of for defining a package for your system definitions are that the package list becomes more cluttered (only noticeably if for some strange reason you're loading many system definitions and not loading the defined systems), you're using more of the global package namespace (probably not a significant concern if you use a naming scheme like foo and foo.system), and your code is marginally more complex.
So there are good reasons for (and maybe some against) defpackage in your asd, but package hygiene is not one of them.
[Edited 2009-11-26 to be less worded against defpackage after consideration and feedback.]
Re: Documentation agrees with Kevin
Date: 2009-11-27 07:19 (UTC)and explicitly qualify symbols from the ASDF package, you can have both,
no DEFPACKAGE form, and still be able to manually load the .asd file.