cl:describe doesn't show documentation for nameless functions (and closures)

Bug #1850662 reported by Mikko Markus Torni
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Undecided
Unassigned

Bug Description

(let ((fun (lambda () "%DOCSTRING%" NIL)))
  (setf (documentation fun 'function) "%SETF-DOCUMENTATION%")
  (describe fun))

This prints:

  #<FUNCTION (lambda ())>
  [...]
  Documentation:
    T
  [...]

I expect to see:

  [...]
  Documentation:
    %SETF-DOCUMENTATION%
  [...]

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/describe.lisp:

(defun describe-function (name function stream)
  (let ((name (if function (%fun-name function) name)))
    ;; CUT ;;
    (describe-documentation name 'function stream)
    ;; ^^^^\ 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.0.DEV::SEQUENCE-EMPTYP :SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO
 :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX
 :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :X86-64 :64-BIT :64-BIT-REGISTERS
 :ALIEN-CALLBACKS :ANSI-CL :AVX2 :C-STACK-IS-CONTROL-STACK :CALL-SYMBOL
 :COMMON-LISP :COMPACT-INSTANCE-HEADER :COMPARE-AND-SWAP-VOPS :CYCLE-COUNTER
 :ELF :FP-AND-PC-STANDARD-SAVE :GENCGC :IEEE-FLOATING-POINT :IMMOBILE-CODE
 :IMMOBILE-SPACE :INTEGER-EQL-VOP :LARGEFILE :LINKAGE-TABLE :LINUX
 :LITTLE-ENDIAN :OS-PROVIDES-BLKSIZE-T :OS-PROVIDES-DLADDR :OS-PROVIDES-DLOPEN
 :OS-PROVIDES-GETPROTOBY-R :OS-PROVIDES-POLL :OS-PROVIDES-PUTWC
 :OS-PROVIDES-SUSECONDS-T :PACKAGE-LOCAL-NICKNAMES :RELOCATABLE-HEAP
 :SB-CORE-COMPRESSION :SB-DOC :SB-EVAL :SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS
 :SB-SIMD-PACK :SB-SIMD-PACK-256 :SB-SOURCE-LOCATIONS :SB-THREAD :SB-UNICODE
 :SB-XREF-FOR-INTERNALS :SBCL :STACK-ALLOCATABLE-CLOSURES
 :STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS
 :STACK-ALLOCATABLE-VECTORS :STACK-GROWS-DOWNWARD-NOT-UPWARD
 :UNDEFINED-FUN-RESTARTS :UNIX :UNWIND-TO-FRAME-AND-CALL-VOP)

Revision history for this message
Mikko Markus Torni (mtorni) wrote :
Revision history for this message
Douglas Katzman (dougk) wrote :

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)
FOO
* (defparameter thing #'foo)
THING
* (defun foo () "no i am foo" 2)
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
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)
COMMON-LISP-USER::FOO
  [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)
COMMON-LISP-USER::BAR
  [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))

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.