Hello,
After some discussion on comp.lang.lisp a few weeks ago, I asked Pascal Costanza whether a CDR document could specify that implementations of the document's interface should push features to advertise purported conformance with the CDR document. He encouraged me to send a draft here for comment.
The writeup is in apprxomately the form of the cl-cleanup committee's issues, since I expect everybody will be familiar with that structure, though it doesnt actually propose any changes to ANSI. I'll mark it up in LaTeX later, if people think it's worth submitting to the editors.
Comments?
-- RmK
* Issue
CDR-FEATURES-CONVENTION
* References
Pitman, K.M. (1991). Issue COMMON-FEATURES. Issue 56, X3J13, ANSI. http://www.lisp.org/HyperSpec/Issues/iss056-writeup.html
Pitman, K. and Chapman, K., editors (1994). Information Technology Programming Language Common Lisp. Number 2261994 in INCITS. ANSI.
Rhodes, Christope. (2004). "Maintaining Portable Lisp Programs" http://www-jcsu.jesus.cam.ac.uk/~csr21/papers/features.pdf
* Related Issues
ANSI Issue 56, more or less.
* Category
Recommendation ; "Recommendation wasn't a category in the cl-cleanup ;committee, but the CDR process isn't really the same ;thing.
* Problem Description
A document in the Common Lisp Document Repository (CDR) may describe programmers' interfaces or propose emendations or extensions to the ANSI Common Lisp standard. Such a document should specify one or more features so that programs may easily distinguish environments that may be expected to conform to the document's specification.
* Proposal
We propose a convention for naming symbols meant to be included in *FEATURES* for the purpose of advertising purported conformance with a CDR document's specifications, and encourage CDR document authors, Common Lisp implementors, and library authors to follow such conventions when providing purported implementations of such specifications.
CDR documents that describe programmers' interfaces should enumerate a set of symbols in the KEYWORD package whose names begin with a prefix consisting of the string "CDR-" followed by the decimal representation of the number of the CDR document with no leading zeroes. If the CDR document defines only one level of conformance with the document's specifications (e.g., the document specifies no subsets), then the enumeration of keyword symbols should contain the symbol whose name is the prefix. If the CDR document defines levels of conformance of its total specification (such as subsets, or even mutually incompatible interfaces), then for each defined level of conformance, the enumeration of keyword symbols should should contain a symbol whose name begins with the prefix, followed by a hyphen, followed by some descriptive name for the subset.
Implementors of an interface described in a CDR document that enumerates a set of keyword symbols as above should ensure that the appropriate symbols occur in the *FEATURES* list when the Lisp environment has been configured to behave in conformance with the specification. Configuring the Lisp environment might involve loading files, invoking functions, etc.; or the environment may conform to the specification when the host Lisp is initialized, in which case the implementation should include the appropriate symbols in *FEATURES* as early as initialization time. If, after configuring the Lisp environment to conform to the CDR document's specification, it should be possible to reconfigure the Lisp environment to fail to conform to the specification, whether the corresponding symbol remains in the *FEATURES* list after so reconfiguring is not defined by this proposal, but may be defined by a CDR document or an implementation of a CDR document's interface.
Implementations of Lisps that provide non-standard lettercase customs in their symbol names are permitted to vary the lettercase of the names of the enumerated keyword symbols as necessary to furnish the appropriate effects on those implementations.
Finally, programmers are discouraged from adding keyword symbols to *FEATURES* whose names begin with "CDR-" except as part of implementations of interfaces described in CDR documents.
* Examples
** Example 1
Suppose CDR document number 42 defines no subsets of its specification; in this case, the document might include text such as the following:
"Implementations of the interface described in this document should ensure that the symbol :CDR-42 occurs in the *FEATURES* list when the Lisp environment is configured to behave as described in this document."
Next, suppose that Lisp implementation BAR only conforms in case the user calls the function ENABLE-CDR-42-API, and that Lisp implementation QUUX only conforms in case a particular file is loaded. In this case, a program that can work only in environments conforming to CDR 42's specification might begin with
#+(and bar (not cdr-42)) (eval-when (:compile-toplevel :load-toplevel) (enable-cdr-42-api)) #+(and quux (not cdr-42)) (eval-when (:compile-toplevel :load-toplevel) (load "sys:source;cdr-42")) ;; If, after all that, CDR-42 still isn't present, bail out. #-cdr-42 (eval-when (:compile-toplevel :load-toplevel) (error "Can't run this program in a non-CDR-42 environment."))
** Example 2
Suppose that CDR 704 defines two subsets of its specification, called "BASIC" and "BELLS-N-WHISTLES"; in this case the document might include text such as the following:
"Implementations of the interface identified in this document as BASIC should ensure the symbol :CDR-704-BASIC occurs in the *FEATURES* list when the Lisp environment is configured to behave in conformance with the BASIC interface. Implementations of the interface identified in this document as BELLS-N-WHISTLES should ensure that the symbol CDR-704-BELLS-N-WHISTLES occur in the *FEATURES* list when the Lisp environment is configured to behave in conformance with the BELLS-N-WHISTLES interface."
Now suppose a program needs a function FROB that's in BELLS-N-WHISTLES but not in BASIC, but that can be defined portably (albeit perhaps not maximally efficiently), given BASIC. Then the program might begin with
#+(and cdr-704-basic (not cdr-704-bells-n-whistles)) (eval-when (:compile-toplevel :load-toplevel) (defun frob ...)) #-cdr-704-basic (eval-when (:compile-toplevel :load-toplevel) (error "Can't run this program without BASIC CDR 704~ compliance."))
* Rationale
Since CDR documents are not constrained to describe only those interfaces that can be implemented in portable Common Lisp, an individual document may define what is in effect a new dialect that's slightly different from ANSI Common Lisp. Thus, by the logic of ANSI Issue 56,
"Users need this to get a foothold as they try to port between dialects in transition."
In particular, it is not possible in general to programmatically investigate the semantics of a new dialect. For example, a CDR document might specify some behavior for an operator that has undefined consequences in ANSI Common Lisp; a program that exercised the operator to test for conformance with the CDR document might crash a Lisp implementation that conforms to ANSI but not to the CDR document's specification.
Even for interfaces that could be programmatically detected safely (interfaces that can be implemented in "modules" or "libraries"), it may nonetheless be desirable to distinguish the environment's purported conformance to an interface from the presence of a particular implementation of the interface. For example, it may be desirable from time to time for one library to supersede another while providing an upwardly compatible interface (perhaps modulo package names), or for an implementor to provide an implementation of an interface with extensions or optimizations that can't be written portably. In such cases, it may be difficult to detect all the ways that the environment might conform to the interface, and so an advertisement by the provider of the interface should simplify programs that depend on the interface.
* Current practice
As of Aug 2007, no existing CDR document does as this document describes. It is unlikely that anyone is already using keywords of the form :CDR-<NN> in their *FEATURES*.
* Cost to Implementors
Negligible. CDR document authors are encouraged to add a bit of boilerplate to their documents, and authors of programs that purport to conform to CDR document standards will have to arrange to push some symbols onto *FEATURES*.
* Cost to Users
Negligible, if any.
* Cost of non-adoption
It can be difficult to take advantage of interfaces described in the Common Lisp Document Repository, even when these interfaces are implemented.
* Performance Impact
None.
* Benefits
The CDR project might be more effective at spurring progress in Common Lisp.
Users who desire to write programs that produce equivalent results and observable side effects on a subset of possible implementations might face an easier task if implementations advertised their purported conformance with defined, if non-ANSI, interfaces.
* Esthetics
It's slightly ugly to call for symbols such :CDR-<nn>-FOO-BAR-BAZ to be members of *FEATURES*, but alternatives are bad or worse. Specifically,, it's inconvenient to use read-time conditionals to check for anything other than the presence of keyword symbols in *FEATURES*, and it seemed like overkill to call for a package (say, "CDR") solely for the names of CDR document interfaces.
* Notes
Rhodes (2004) provides many examples of the pitfalls of read-time feature conditionals as a means for maintaining portable programs; this document does not dispute any of Rhodes's observations or suggestions. However, while Rhodes suggests various ways to organize implementation-specific code to minimize the use of read-time conditionals, it is hoped that the conventions detailed above will promote convergence of implementations in areas ANSI leaves implementation-specific or does not address, thereby reducing the amount of such implementation-specific code in programs intended for use in different Lisp environments.
Note that this document does not constrain CDR documents from calling for elements of *FEATURES* other than those that follow the conventions proposed here, nor constrain implementors from providing symbols other than ones that follow the conventions proposed here.
* Discussion
It is not intended that identifiers of the form CDR-<NN> supplant descriptive, mnemonic names for interfaces, libraries, packages, systems, etc.