(Resent, with Cc: cdr-devel@common-lisp.net)
Juan Jose Garcia-Ripoll juanjose.garciaripoll@googlemail.com writes:
I have been reading the CDR documents and none of them seems to mandate the inclusion of some feature to signal the presence of a CDR in an implementation. *features* right now is quite populated and I would not want to fill it with further names that may collide with other users's. Does anybody have a strong opinion or is better informed than me in this respect?
The presence of some features need to be determined at read-time.
Even for features that can be determined at run-time, you would have to use a variable or a function, the presencce of which will have to be determined at read-time.
So it seems to me that we need a keyword on *features*.
Basically, you have the choice between:
(when (and (find-package "CDRn") (find-symbol "FN" "CDRn") (fboundp (find-symbol "FN" "CDRn"))) (funcall (find-symbol "FN" "CDRn")))
and:
#+CDRn (cdrn:fn)
Now, we could define a CDR that would allow us to determine at run-time, if a specific CDR is implemented. Something like:
(cdr:max-implemented-cdr-number) --> integer (cdr:implementedp n) --> boolean
Which would allow us to write things like:
(dotimes (i (1+ (cdr:max-implemented-cdr-number))) (when (cdr:implementedp i) (format t "~A implements CDR~D~%" (lisp-implementation-type) i)))
but as you can see, we need a *feature*
#+cdr (dotimes (i (1+ (cdr:max-implemented-cdr-number))) (when (cdr:implementedp i) (format t "~A implements CDR~D~%" (lisp-implementation-type) i))) #-cdr (format t "~A implements no CDR~%" (lisp-implementation-type))
So the minimum number of keyword on *features* that would be required is one, but for that we would have to define an additionnal CDR as above.
Now, for CDRs that don't involve new symbols, eg. CDR7, you can just write:
(defun cl-user::fmt (stream argument colonp atsignp &rest params) (declare (ignore stream argument colonp atsignp)) (format t "~S" params))
(format t "~/fmt/ and ~:*~,/fmt/ ~:[may be different~;should be the same~].~%" nil #+cdr (cdr:implementedp 7) #-cdr nil)
but again, it might be easier to write:
(format t "~/fmt/ and ~:*~,/fmt/ ~:[may be different~;should be the same~].~%" nil (member :cdr7 *features*))
or just:
#+cdr7 (format t "cdr7 implemented~%") #-cdr7 (format t "cdr7 not implemented~%")
It seems to me that the CDRs of the kind of CDR7 will be much rarer, and in either case, the convenience of *features* and read-time conditionnalisation is overwhelming.
Even if we can always write things like:
#+#.(cl:if (cl:and (cl:find-package "CDR") (cl:find-symbol "IMPLEMENTEDP" "CDR") (cl:fboundp (cl:find-symbol "IMPLEMENTEDP" "CDR")) (cl:funcall (cl:find-symbol "IMPLEMENTEDP" "CDR") 7)) '(:and) '(:or)) (format t "cdr7 implemented~%")
it is clear that what's really wanted, is a keyword on *features* for each CDR.
Finally, I would like to add a note to CDR writers. The purpose of the CDR proccess is to improve or evolve the standardization of Common Lisp, by adding missing features, or precising existing features (eg. CDR9). In this spirit, I would suggest that CDRs should not specify implementation dependent behavior. For example, CDR9 says:
The API to the requested functionality can be as simple as providing a function called make-variable-file-local in whatever extension package a Common Lisp implementation happens to use [...].
This is very bad, because this will force us to write code such as:
#+(and cdr9 clisp) (ext:make-variable-file-local '*my-var*) #+(and cdr9 ccl) (ccl:make-variable-file-local '*my-var*) #+(and cdr9 sbcl) (sb-ext:make-variable-file-local '*my-var*) #+(and cdr9 (not (or clisp ccl sbcl))) (error "CDR9 is implemented, but ~ I don't know where it is!") #-cdr9 (error "CDR9 is not implemented")
which is shameful and a bore. Clearly, this kind of CDR are no gain, and we would be better without.
On the other hand, if the CDRs specify new symbols, they should always specify CDNn as a package name (or nickname) where these symbols must be exported from. I think that even if another package name is specified, a CDRn nickname should also be specified, to allow for different versions to be present (the implementation may able to provide several versions in a single package, with several CDRn nicknames, or as different packages).
So given such a correction to CDR9:
The API to the requested functionality must be implemented by providing a function called cdr9:make-variable-file-local.
we could write:
#+cdr9 (cdr9:make-variable-file-local '*my-var*) #-cdr9 (error "CDR9 is not implemented")