docstrings for functions in :final deprecation stage are bogus

Bug #1439151 reported by Douglas Katzman on 2015-04-01
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

Example:

(define-deprecated-function :final "1.2.10" dont-use-this use-that-instead (x) (use-that-instead x))
(define-deprecated-function :final "1.2.10" hey-heres-another other-better-fun (x) (other-better-fun x))

(documentation 'dont-use-this 'function) =>

"SB-IMPL::HEY-HERES-ANOTHER has been deprecated as of SBCL 1.2.10.

Use SB-IMPL::OTHER-BETTER-FUN instead."

The root cause is that attaching documentation to closures affects the underlying simple-fun.
There is simply no place to store the documentation in a closure.
There are three solutions to this problem for deprecation, not the general limitation.

1) Store the documentation in globaldb keyed by the name of the closure.
Now that we have re-nameable closures, this is a cinch. (And again, re-naming is not something to be exposed to users - it works just well enough to do some nice system-internal things, because it changes the identity of the closure, which is undesirable)

2) don't try to use closures to reduce storage size. Just use DEFUN.

3) use a hashtable keyed by the closure. For the more general case this should be a weak hashtable.

It seems to me that (1) is most appropriate here.

On Wed, 2015-04-01 at 11:55 +0000, Douglas Katzman wrote:

> 1) Store the documentation in globaldb keyed by the name of the closure.
> Now that we have re-nameable closures, this is a cinch. (And again, re-naming is not something to be exposed to users - it works just well enough to do some nice system-internal things, because it changes the identity of the closure, which is undesirable)
>
> 2) don't try to use closures to reduce storage size. Just use DEFUN.
>
> 3) use a hashtable keyed by the closure. For the more general case this
> should be a weak hashtable.
>
> It seems to me that (1) is most appropriate here.

I'm in favor of something like (1). I would like to store the actual
deprecation information for functions in globaldb (as is already done
for variables). I previously sent a draft patch for doing that and
making deprecation information available to users via
SB-CLTL2:{VARIABLE,FUNCTION}-INFORMATION to sbcl-devel (attached here
for convenience). Ideally the type of
(info :{variable,function} :deprecated NAME) would be a structure
containing state, since and replacements instead of the current list.

This solution would require/allow handling deprecated functions in ir1
conversion and would free us (I think) from the difficulties of the
current :LATE deprecation implementation for functions.

What do you think?

Douglas Katzman (dougk) wrote :

I think that idea is basically fine, but with a couple remarks:
- Fewer possible ways to express the same thing are better. globaldb can't prevent you from expressing conflicting information. So as pertains to this patch, what would it mean if the compiler-macro didn't exist but the :deprecated property did? The availability of (setf (compiler-macro-function)) means that it could be set to nil externally, and globaldb can't enforce it.
- globaldb mostly assumes that you never never change a piece of info - you just build up information. So if you do rewrite information, the semantics are unclear, e.g. does a new DEFUN clear the new :deprecated property? Should (setf (symbol-function 'foo)) not in the context of a DEFUN clear it?
In fact, we don't even consistently have an answer to that: see example [*] below.

Granted the coupling between the function and compiler-macro is already loose, but one more piece of state is just one more place to think about: does changing this change that? So maybe it would be nicer if the macro didn't exist, and the :deprecated info were authoritative internally to the compiler, and took precedence.

Either way, I've got a change to store docstrings correctly, and will commit that shortly.

[*] in terms of it being tricky to maintain globaldb consistency, consider the following (entered at the REPL, having nothing to do with the file compiler) which prints "2" in SBCL (and CMUCL), prints "4" in at least 3 other Lisps, and is a continuable error in another-
(setf (macro-function 'hi) (lambda (form env) `(1- ,(second form))))
(setf (symbol-function 'hi) (lambda (x) (1+ x)))
(defun f (x) (hi x))
(f 3) => either 4 or 2

Douglas Katzman (dougk) on 2015-05-07
Changed in sbcl:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers