Packages organization and exporting symbols
I’ve started to re-design my main library for evolutionary computation. One of the main things I did for the new version was a complete new organization of the packages (and respective files/modules). Before I had essentially two main packages, the library itself and the examples. Although simple, it became a pain to use this model when I extended it heavily with more algorithms and related utilities. I hope I am not going now in the opposite direction (too complicated) but so far I like the new organization.
In short, there is a package for each main branch of algorithms (e.g., GA, GP) with everything specific that kind, which imports from a core package with the common components. These “sub-packages” are gathered together in a single package (the main library package). This way, it is possible to use in a project everything or simply just the desired component (e.g., if you just want GP). Furthermore, an extra package for the users is also provided to allow REPL experimentation without being on the library main package.
However, while implementing this scheme I realized that I wanted to have all the exported symbols from the packages that compose the library, also exported by the library main package. This way, all the symbols that compose the library are easily seen on the main package. For me this is very useful since it allows exploration of a library, especially if it has many things. Since I have never done something like this before, I went and search for a way to solve this minor problem in an easy way.
The answer is basically use do-external-symbols. With this macro you iterate over the exported symbols of a given package and then export them again on the package you want. Do this inside an eval-when form and when the library is loaded and the main package will contain all the symbols. If *library-sub-packages* is a list with the packages labels that compose your library:
(eval-when (:compile-toplevel :compile-toplevel :execute)
(dolist (package *library-sub-packages*)
(do-external-symbols (symbol (find-package package))
(export symbol (find-package *library-main-package*)))))
Making all the exported symbols of internal packages also exportable by the main package turn out to be an easy thing to do. I don’t recall seing do-external-symbols (or the related macros) but I’m glad such a macro is provided. As always, the HyperSpec is your friend :-)