cl:describe doesn't show documentation for nameless functions (and closures)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
(let ((fun (lambda () "%DOCSTRING%" NIL)))
(setf (documentation fun 'function) "%SETF-
(describe fun))
This prints:
#<FUNCTION (lambda ())>
[...]
Documentation:
T
[...]
I expect to see:
[...]
Documentation:
%SETF-
[...]
or even:
[...]
Documentation:
%DOCSTRING%
[...]
A clue to what's happening is:
(let ((fun (lambda () "%DOCSTRING%" nil)))
(setf (sb-impl::%fun-name fun) 'CAR)
(describe fun))
[...]
Documentation:
Return the 1st object in a list.
[...]
The culprit seems to in DESCRIBE-FUNCTION in src/code/
(defun describe-function (name function stream)
(let ((name (if function (%fun-name function) name)))
;; CUT ;;
(describe-
;; ^^^^\ Should perhaps be FUNCTION instead of NAME?
;; CUT ;;
I have included a patch making the above change.
$ sbcl --version
SBCL 1.4.16.debian
$ uname -a
Linux premium 4.9.0-2-amd64 #1 SMP Debian 4.9.18-1 (2017-03-30) x86_64 GNU/Linux
CL-USER> *features*
(:CLOSER-MOP :SPLIT-SEQUENCE :NAMED-READTABLES :CL-PPCRE
ALEXANDRIA.
:ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX
:NON-BASE-
:ALIEN-CALLBACKS :ANSI-CL :AVX2 :C-STACK-
:COMMON-LISP :COMPACT-
:ELF :FP-AND-
:IMMOBILE-SPACE :INTEGER-EQL-VOP :LARGEFILE :LINKAGE-TABLE :LINUX
:LITTLE-ENDIAN :OS-PROVIDES-
:OS-PROVIDES-
:OS-PROVIDES-
:SB-CORE-
:SB-SIMD-PACK :SB-SIMD-PACK-256 :SB-SOURCE-
:SB-XREF-
:STACK-
:STACK-
:UNDEFINED-
I wonder if you wouldn't mind seeing how this affects some strange cases as in the following example? I don't have a good idea of what things "should" do, but it might be nice to put in comments about expected behaviors, rather than just having it be quasi-random/ inexplicable and then changing it be a different behavior that is equally so.
(I'm certainly not suggesting that the patch breaks anything - it looks good to me).
* (defun foo () "i am foo" 1) LISP-USER: :FOO in DEFUN
FOO
* (defparameter thing #'foo)
THING
* (defun foo () "no i am foo" 2)
WARNING: redefining COMMON-
FOO
* (setf (symbol-function 'bar) #'foo)
#<FUNCTION FOO>
* (setf (documentation #'bar 'function) "here is a string for bar")
"here is a string for bar"
* (describe 'foo) LISP-USER: :FOO
COMMON-
[symbol]
FOO names a compiled function:
Lambda-list: ()
Derived type: (FUNCTION NIL (VALUES (INTEGER 2 2) &OPTIONAL))
Source form:
(LAMBDA () "no i am foo" (BLOCK FOO 2))
* (documentation #'foo 'function)
"here is a string for bar"
* (describe 'bar) LISP-USER: :BAR
COMMON-
[symbol]
BAR names a compiled function:
Lambda-list: ()
Derived type: (FUNCTION NIL (VALUES (INTEGER 2 2) &OPTIONAL))
Source form:
(LAMBDA () "no i am foo" (BLOCK FOO 2))
* (describe #'bar)
#<FUNCTION FOO>
[compiled function]
Lambda-list: ()
Derived type: (FUNCTION NIL (VALUES (INTEGER 2 2) &OPTIONAL))
Documentation:
here is a string for bar
Source form:
(LAMBDA () "no i am foo" (BLOCK FOO 2))