Next: , Previous: , Up: Assessment   [Contents][Index]


6.1.2 Introspection Levels

In order to discover both domestic and relevant foreign definitions, Declt uses a heuristic which establishes different tradeoffs between performance and accuracy. Remember that this is controlled by the :introspection-level option to declt or assess. This heuristic is based on the assumption that most libraries out there are implemented within packages of their own.

Consequently, this is what happens by default (that is, at introspection level 1). After the library has been loaded, Declt scans all live packages and selects the domestic ones. It then scans all symbols from these packages to find domestic definitions.

Note that if we were to stop there, we would probably miss many domestic definitions, namely, those on foreign symbols such as methods on standard generic functions such as make-instance. Fortunately, a lot of these will be recovered later on anyway, when Declt computes cross-references between definitions in the so-called finalization phase.

Suppose for instance that the library provides a new method on make-instance. This method is domestic because it is defined in one of the library’s files, but at introspection level 1, Declt only scans domestic symbols, so it will miss it (common-lisp, the home package of the make-instance symbol, is foreign). On the other hand, it is very likely that this method exists because it specializes on a domestic class already known to Declt. When Declt finalizes a class definition, it looks up methods that specialize on it (among other things). These methods are in fact accessible through the class by introspection (they are called “direct methods”). Consequently, Declt will eventually discover the new make-instance method, figure out that it is a domestic one, and add it to the documentation.

In the end, it is probable that most domestic definitions end up being discovered, either during the initial scanning phase, or later on, during the finalization phase when cross-references are computed. This is why the default introspection level is probably good enough most of the time.

On the other hand, some (rare?) domestic definitions may still escape the discovery process at that level. For example, if you define a foreign global variable in one of your library’s files, chances are that there won’t be any domestic definition cross-referencing it. This is why Declt provides a second level of introspection, in which it initially scans all symbols in the Common Lisp image, rather than just the ones from domestic packages. The resulting documentation will then be more complete, although at the expense of a much greater computation time.

And yes, you have just noticed that I said “more complete” rather than “exhaustive”, and mind you, this is not because my vocabulary is limited. The thing is that even with an initial scan of all symbols, we may still miss some information. To be precise, we won’t miss any domestic definition. It is the cross-referencing information that may remain incomplete, and that is because the finalization phase doesn’t re-scan each and every symbol in the Lisp image again; only the definitions that have been created so far. Let’s take an example (granted, a contrived one; but aren’t they all?). You define a regular domestic function, and it is used as the update function in a foreign setf expander. Even with an initial scan of all symbols in the Lisp image, you’ll get a definition for your domestic function, but that’s it. Later on, during the finalization process, there’s no way to go from the function to the setf expander, so that information remains unknown. In order to fix that, the finalization process would need to re-scan the whole Lisp world again, and that would become introspection level 3. Not sure it’s actually worth it; maybe one day...


Next: Reports, Previous: Domesticity, Up: Assessment   [Contents][Index]