Today, after two years and a half of (irregular) development, and 465 commits, I have released the first beta version of Declt 4.0, my reference manual generator for Common Lisp libraries.
I seldom release official beta versions of software, let alone make announcements about them, but this one deserves an exception. Since version 3, Declt has been undergoing a massive, SOC-oriented, overhaul. The intent is to reimplement it into a clean 3-stages pipeline. Stage one, the "assessment" stage is in charge of gathering information. Stage two, the "assembly" stage, creates a documentation template specifying how the information is to be organized. Finally, Stage three, the "typesetting" stage, renders the template in a specific output format. Of course, the purpose is to eventually be able to support different kinds of templates and output formats.
Declt 4.0b1 marks the achievement of Stage one, which is now complete. It also contains a lot of new (and long awaited) features and improvements. The user manual has been updated to provide an overview of the new architecture, along with some details about Stage one of the pipeline. From now on, I'm also going to release new versions of Quickref to closely follow the evolution of Declt.
Apart from the aforementioned architecture overhaul, which really boils down to internals shaking and shouldn't affect the end-user much, a lot of new features and improvements are also provided in this release. They are listed below.
Backward Incompatible Changes
For the benefit of Separation of Concerns, but also for other reasons, a number of keyword arguments to the declt
function have been renamed. :hyperlinks
becomes :locations
, :version
becomes :library-version
, :texi-directory
becomes :output-directory
, and :texi-name
becomes :file-name
.
New Features
Default / Standard Values
Declt now has the ability to advertise or hide properties that get default / standard values (e.g. standard method combination, :instance
slot allocation, etc.).
Support for Aliases
Declt now recognizes and advertises "aliases", that is, funcoids which have their fdefinition
, macro, or compiler macro function set manually to another, original, definition.
Support for New Programmatic Entities
Typed structures and setf
compiler macros are now properly detected and documented with all the specific information.
Proper Support for Uninterened Symbols
Such symbols may be encountered on several occasions such as slot names (trivialib
, for example, defines structures with uninterned slot names in order to prevent access to them). Definitions named with uninterned symbols are considered private, and denoted by the empty set package (∅).
SBCL 2.1.2 Required
The following enhancements depend on it:
- short form
setf
expanders now get correct source information,
- method combinations lambda-lists are now documented.
Domestic vs. Foreign Definitions
The concept of domestic (as opposed to foreign) definition has been extended to include those created in one of the sources files of the library being documented, even if the symbol naming the definition is from a foreign package. If the source file is unknown, then the symbol's package must be domestic. The general intent is to consider language extensions as domestic, hence, always documented. For example, a new method on a standard generic function (say, initialize-instance
) will now always appear in the documentation.
This refinement is accompanied by a new option allowing to include foreign definitions in the generated documentation. Of course, only foreign definitions somehow related to the library being documented will appear in the documentation. Also, those definitions will in general be partial: only the parts relevant to the library being documented will appear. Continuing with the initialize-instance
example, new methods normally appear as toplevel, standalone definitions in the documentation (and their parent generic function is simply mentioned). If foreign definitions are included however, there will be a toplevel entry for the generic function, and all methods defined in the library will be documented there (truly foreign methods won't appear at all).
Introspection Heuristic
Until now, there was a single heuristic for finding domestic definitions, which was to start from domestic packages and scan as many connections between symbols as possible. That heuristic is reasonably fast, but may occasionally miss some domestic definitions. Declt now has the ability to scan all symbols in the Lisp image instead of only the ones from domestic packages. This new option ensures that all domestic definitions are found, at the expense of a much greater computation time.
Supported Licenses
The Microsoft Public License has been added.
Info Installation Category
In other words, the value of Texinfo's @direntry
command is now customizable (instead to being hardwired to "Common Lisp").
Improvements
Documentation Thinning
Packages reference lists do not point to methods directly anymore (as they can be reached via the generic function's reference). Also, only slots for which the parent classoid is named from another package are now referenced.
Files reference lists do not point to slots anymore (as they can be reached via the parent classoid's reference). Also, only methods for which the parent generic function is defined in another file are now referenced.
The readability of long references has been improved. In particular, they don't advertise the type of the referenced definitions anymore, when there is no ambiguity.
Slot documentation now advertises the slot name's package only when different from that of the parent classoid.
Non standalone method documentation now advertises the source file only when different from that of the parent generic function.
The rendering of EQL specializers has been inmproved.
The documentation of setf
/ writer methods doesn't render the "new value" argument / specializer anymore.
Merging
Generic definitions containing only reader / writer methods are upgraded to specific reader / writer categories, and definition merging is now only attempted on those.
Lambda Lists
Uninformative parts of lambda lists are now filtered out. This includes &whole
, &environment
, &aux
variables, along with options / keyword variables and default values.
Method specializers in lambda lists now link back to their respective class definitions.
Method Combinations
The method combination discovery scheme has been upgraded to benefit from SBCL 1.4.8's enhancements (themselves following my ELS 2018 paper). The old code didn't break, but prevented unused method combinations from being detected.
Bug Fixes and Workarounds
ASDF
Better handling of missing / unloaded components or dependencies (this can happen for instance with feature-dependent conditional inclusion).
Cope with the lack of specification of the license information in ASDF systems by coercing to a string.
Fix several cases of system files documentation duplication. Declt automatically documents .asd files as special cases of Lisp files. However, some systems have the bad (IMHO) habit of mentioning them explicitly as components (e.g. static files). When this happens, Declt silently discards that definition and keeps its own (at the expense of having a slightly incorrect system documentation).
Anchoring
After years of vain attempts at providing human-readable yet unique anchor names (which was only really useful for Info, BTW), I finally got rid of my last bit of idealism. Anchor names now use numerical definition UIDs, and since Texinfo allows me to expand references with some more information than just the anchor, it's good enough. Besides, it fixes the last remaining rare cases exhibiting the fact that it's just impossible to have anchors that are both human-readable and unique.
Setf
Expanders
Fix the computation of short form setf
epxander lambda lists (which didn't correctly handle the presence of optional or rest arguments before.
Handle the potential unavailability of a setf
expander's update function or short form operator. Document it if applicable. Also signal a warning when the expander is domestic.