[Ecls-list] APROPOS issues, proposed enhancement
Matthew Mondor
mm_lists at pulsar-zone.net
Wed Jun 27 06:23:07 UTC 2012
I noticed that the native APROPOS (not SLIME's) returns duplicate
symbols, it seems to happen notably for symbols of the COMMON-LISP
package:
> (apropos '#:most-positive)
MOST-POSITIVE-LONG-FLOAT Constant: 1.7976931348623157d308
MOST-POSITIVE-FIXNUM Constant: 2305843009213693951
MOST-POSITIVE-DOUBLE-FLOAT Constant: 1.7976931348623157d308
MOST-POSITIVE-SHORT-FLOAT Constant: 3.4028235e38
MOST-POSITIVE-SINGLE-FLOAT Constant: 3.4028235e38
MOST-POSITIVE-LONG-FLOAT Constant: 1.7976931348623157d308
MOST-POSITIVE-FIXNUM Constant: 2305843009213693951
MOST-POSITIVE-DOUBLE-FLOAT Constant: 1.7976931348623157d308
MOST-POSITIVE-SHORT-FLOAT Constant: 3.4028235e38
MOST-POSITIVE-SINGLE-FLOAT Constant: 3.4028235e38
This is of course allowed by the standard (actually an APROPOS-LIST
issue, although it can be annoying and some implementations avoid
this, such as SBCL), but if we specify a package designator to tell
APROPOS to only return symbols from C, for instance, it seems that we
are getting unintended symbols from the COMMON-LISP package, and way
more duplicates of them:
> (apropos '#:push :c)
C::C1STACK-PUSH Function
C::C1STACK-PUSH-VALUES Function
C::PUSH-VARS Function
C::C2STACK-PUSH-VALUES Function
C::P1STACK-PUSH-VALUES Function
C::COMPILER-PUSH-EVENTS Function
C::STACK-PUSH
C::STACK-PUSH-VALUES
VECTOR-PUSH-EXTEND Function
PUSHNEW Macro
VECTOR-PUSH Function
PUSH Macro
VECTOR-PUSH-EXTEND Function
PUSHNEW Macro
VECTOR-PUSH Function
PUSH Macro
VECTOR-PUSH-EXTEND Function
PUSHNEW Macro
VECTOR-PUSH Function
PUSH Macro
VECTOR-PUSH-EXTEND Function
PUSHNEW Macro
VECTOR-PUSH Function
PUSH Macro
[...] more duplicates from COMMON-LISP package [...]
Is this part a bug?
Sample SBCL output:
* (apropos '#:most-positive)
MOST-POSITIVE-DOUBLE-FLOAT (bound)
MOST-POSITIVE-FIXNUM (bound)
MOST-POSITIVE-LONG-FLOAT (bound)
MOST-POSITIVE-SHORT-FLOAT (bound)
MOST-POSITIVE-SINGLE-FLOAT (bound)
SB-C::MOST-POSITIVE-BOUND
MOST-POSITIVE-WORD (bound)
SB-KERNEL:MOST-POSITIVE-EXACTLY-DOUBLE-FLOAT-FIXNUM (bound)
SB-KERNEL:MOST-POSITIVE-EXACTLY-SINGLE-FLOAT-FIXNUM (bound)
SB-VM:MOST-POSITIVE-COST
* (apropos '#:most-positive '#:sb-c)
SB-C::MOST-POSITIVE-BOUND
Sample CLisp output:
[1]> (apropos '#:most-positive)
MOST-POSITIVE-DOUBLE-FLOAT constant
MOST-POSITIVE-FIXNUM constant
MOST-POSITIVE-LONG-FLOAT variable
MOST-POSITIVE-SHORT-FLOAT constant
MOST-POSITIVE-SINGLE-FLOAT constant
[2]> (apropos '#:push '#:system)
SYSTEM::APPLY&PUSH
SYSTEM::CALL&PUSH
SYSTEM::CALL1&PUSH
SYSTEM::CALL2&PUSH
SYSTEM::CALLC&PUSH
SYSTEM::CALLCKEY&PUSH
SYSTEM::CALLS1&PUSH
SYSTEM::CALLS2&PUSH
SYSTEM::CALLSR&PUSH
SYSTEM::CAR&PUSH
SYSTEM::CDR&PUSH
SYSTEM::CONS&PUSH
SYSTEM::CONST&PUSH
SYSTEM::CONST&SYMBOL-FUNCTION&PUSH
SYSTEM::COPY-CLOSURE&PUSH
SYSTEM::FUNCALL&PUSH
SYSTEM::GETVALUE&PUSH
SYSTEM::HANDLER-BEGIN&PUSH
SYSTEM::INSERT-COMBINED-LAPS-NILPUSHER-P
SYSTEM::JSR&PUSH
SYSTEM::LIST&PUSH
SYSTEM::LIST*&PUSH
SYSTEM::LOAD&CAR&PUSH
SYSTEM::LOAD&CDR&PUSH
SYSTEM::LOAD&DEC&PUSH
SYSTEM::LOAD&INC&PUSH
SYSTEM::LOAD&PUSH
SYSTEM::LOADC&PUSH
SYSTEM::LOADI&PUSH
SYSTEM::LOADV&PUSH
SYSTEM::MAKE-STRING-PUSH-STREAM function
SYSTEM::MAKE-VECTOR1&PUSH
SYSTEM::NIL&PUSH
PUSH macro
SYSTEM::PUSH-*DENV* function
SYSTEM::PUSH-*VENV* function
SYSTEM::PUSH-NIL
SYSTEM::PUSH-SPECIALS function
SYSTEM::PUSH-UNBOUND
PUSHNEW macro
SYSTEM::T&PUSH
VECTOR-PUSH function
VECTOR-PUSH-EXTEND function
In this case above some packages outside of SYSTEM are still shown,
though...
Here is a replacement which doesn't care that APROPOS-LIST might return
duplicates, but which strips duplicates and sorts results for output.
Perhaps somewhat of a hack; I initially tried using PUSHNEW in vein,
then thought about using a hash table to eliminate duplicates, but
since I wanted sorted results anyway, it seemed best to simply sort
backwards and remove duplicates in a second pass. Using the existing
PRINT-SYMBOL-APROPOS and later dealing with strings was simpler than
dealing with qualified and unqualified, exported and unexported symbols
for matching and sorting...
(defun apropos (string &optional package)
"Args: (string &optional (package nil))
Prints those symbols whose print-names contain STRING as substring. If
PACKAGE is non-NIL, then only the specified PACKAGE is searched."
(setq string (string string))
(mapc #'princ
(loop
with dupes = (sort
(mapcar #'(lambda (symbol)
(with-output-to-string (stream)
(let ((*standard-output* stream))
(print-symbol-apropos symbol))))
(apropos-list string package))
#'string-greaterp)
with set = '()
with last = nil
for item in dupes
do
(unless (and last (string-equal last item))
(push item set))
(setq last item)
finally (return set)))
(values))
New results with it:
> (apropos '#:most-positive)
MOST-POSITIVE-DOUBLE-FLOAT Constant: 1.7976931348623157d308
MOST-POSITIVE-FIXNUM Constant: 2305843009213693951
MOST-POSITIVE-LONG-FLOAT Constant: 1.7976931348623157d308
MOST-POSITIVE-SHORT-FLOAT Constant: 3.4028235e38
MOST-POSITIVE-SINGLE-FLOAT Constant: 3.4028235e38
> (apropos '#:push '#:c)
C::C1STACK-PUSH Function
C::C1STACK-PUSH-VALUES Function
C::C2STACK-PUSH-VALUES Function
C::COMPILER-PUSH-EVENTS Function
C::P1STACK-PUSH-VALUES Function
C::PUSH-VARS Function
C::STACK-PUSH
C::STACK-PUSH-VALUES
PUSH Macro
PUSHNEW Macro
VECTOR-PUSH Function
VECTOR-PUSH-EXTEND Function
Thanks,
--
Matt
More information about the ecl-devel
mailing list