For a long time I’ve been confused about where various bits of my Lisp code should go. In particular what’s a ‘hack’, what’s a ‘tool’ and what should have its own existence? I think I’ve probably sorted it out now, so here’s my current idea. Probably this is not interesting to anyone who is not me, but I wanted to remember.
Although many things have separate system definitions, I almost never use them: they only exist to make life better for people who live in the ASDF world. For almost all purposes I use require-module
and its tools for almost everything: A source file saying (needs :org.tfeb.hax.iterate)
is just far easier to understand than a vast system definition file1. This applies even for multi-file things.
Modules provide
their names, and live in packages with the same name they provide. Always use heirarchical package names so require-module
knows where to look.
Collections of modules, like hax, traditionally have some system definition which will compile & load all of them, and perhaps run all the tests. But that’s all it’s for: there’s no useful reason to do this normally: just load the modules as you need them (or, well, as you need
them).
I don’t want thousands of public repos. Particularly this is true because almost all of this stuff comes from a single internal repo, and each publication repo requires its own little bit of glue to make it work2.
In particular I’m completely fine with there being more than one ‘system’ per repo.
So anything you might run from the command line or wherever should have its own repo. For instance warranted
has its own repo.
Anything which redefines bits of CL gets its own repo. An example is conduit packages, which redefines defpackage
& other package-related functionality.
An example is reeder. ‘More than one file’ excludes the system definition file where there is one.
These are things that might help you build programs, such as require-module
and its associated command. Each module has an ASDF defsystem
for compatibility, autogenerated.
These are things which might help you write stuff. Some of these might be fairly elaborate, such as collecting
& its relations. Again each module has an ASDF defsystem
for compatibility.
Some of these will make their way elsewhere. Toys are all modules. Nothing other than toys can depend on toys (this is important).
slog
slog
is currently a toy, as it’s perhaps not complete and certainly not tested. It’s not enormous but it’s also not tiny. It is also a standalone module: it depends on some other modules but it’s a thing you might well want to load on its own. But it’s not a program: it’s part of a program. So it will end up as a hack, not in its own repo3.
This is how Racket puts systems together for instance, and largely how Python does as well, if I remember. It’s just a better approach to let a system’s source files describe their own needs in my view. And ASDF is just … ick. ↩
There’s no chance the internal repo will get published as it has a large amount both of of idiosyncratic code and things I just don’t want to be public. So don’t ask. ↩
Before it does, simple-loops
will need to be promoted however. ↩