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.