The dspec system is used to keep track of global definitions in many ways, and global definition macros usually tell the dspec system when the definition changes.
The main purpose of the system is to keep track of where the definition was located, but it also allows fine-tuned control of redefinitions.
Locations are mainly something the dspec system just stores and retrieves. :inside
locations are used to describe definitions located as subforms of other definitions.
:inside
locations are usually not explicitly specified, but arise as a result of having two nested definitions, both of which use the def and location macros to handle the name and location info.
The types of locations and their meanings are:
A pathname |
A definition existed in the file named or an editor buffer with that name. |
The keyword :listener | |
A definition was executed interactively in the listener or an editor buffer not associated with a file. | |
The keyword :unknown | A definition was found in the image (these are entered when a location query does not find any information already in the database). |
The keyword :implicit | |
A definition for a part was recorded, but no information exists for the aggregate. |
The location information is entered into the database when the definition is executed, by the defining function calling record-definition.
record-definition performs various checks, and returns true or false depending on whether the definition was allowed or not. In particular, it checks whether the same name has already been defined in a different location (or more than once in the same file) and if so a warning or error can be signaled depending on the value of *redefinition-action*. See record-definition for details.
You should not usually call record-definition, since all the system-provided definers call it.
However, for new classes of definition which you add with define-dspec-class, you should call record-definition for dspecs in their new classes, as shown in 7.3.1.1 Complete example of a top-level dspec class.
LispWorks has a mechanism for protecting packages against defining any of their external symbols. By default, all the LispWorks implementation packages are protected. For example, an error is signaled if you attempt to put a function definition on the symbol cl:*read-base*. This is configurable by the variables *packages-for-warn-on-redefinition* and *handle-warn-on-redefinition*.
The protection is useful because it is relatively easy to redefine an external symbol by mistake, and it leads to undefined behavior which is difficult to debug. However, in some circumstances you may want to force such definition. In this case, you can rebind either of *packages-for-warn-on-redefinition* or *handle-warn-on-redefinition* around the definition to avoid the error. Bear in mind that the default configuration protects the stability of the system, so if you need to prevent such errors it is better to bind one or both of these variables around specific defining forms, rather than setting their global values.
You can also protect your packages by adding their names to the global value of *packages-for-warn-on-redefinition*.
With suitable compilation options (see toggle-source-debugging), the LispWorks debugger will automatically identify the exact subform in the source code for each stack frame. In addition, the Stepper tool in the LispWorks IDE can step subforms in the source code.
This also works for a subform that occurs within a macro expansion, provided that the subform is eq to the original subform in the call to the macro. In the rare case where a macro copied a subform, making it non-eq, you can use the replacement-source-form macro to indicate which original subform should be identified as the source code for the new form.
LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:19