Bill Clementson's Blog

Bits and pieces (mostly Lisp-related) that I collect from the ether.

October 2004
Sun Mon Tue Wed Thu Fri Sat
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Sep  Nov

CL Symbols

Friday, October 22, 2004

On c.l.l., the question was asked:

"Is there some (portable) method of getting a list of all the defuns, defvars, defmacros, etc., in a LISP system? The idea is like the 'words' command/function/word in FORTH."
There were a number of solutions suggested (Pascal Bourguignon posted a nice one); however, to be complete, I think you would need to identify for each package in the Lisp image: In some cases, the same symbol will appear multiple times (e.g. -- "cond" will appear as both a "Function" and a "Special operator" in the COMMON-LISP package).

The following function should provide a list of all symbols:
(defun list-all-symbols (package)
  (sort (loop for sym being each external-symbol of package
	   when (and (fboundp sym)
		     (not (or (special-operator-p sym) (boundp sym) (macro-function sym))))
	   collect (list sym "Function")
	   when (macro-function sym) collect (list sym "Macro")
	   when (compiler-macro-function sym) collect (list sym "Compiler Macro")
	   when (and (boundp sym) (constantp sym)) collect (list sym "Constant")
	   when (and (boundp sym) (not (constantp sym))) collect (list sym "Variable")
	   when (special-operator-p sym) collect (list sym "Special Operator")
	   when (not (or (fboundp sym)
			 (macro-function sym)
			 (compiler-macro-function sym)
			 (boundp sym)
			 (special-operator-p sym)))
	   collect (list sym "Nothing Specific"))
	#'string-lessp :key #'car))
So, to print out all of the symbols in the COMMON-LISP package, you would do:
CL-USER> (mapcar (lambda (x) (format t "~a: ~a(~a)~%" 'common-lisp (car x) (cadr x)))
		 (list-all-symbols 'common-lisp))
COMMON-LISP: &ALLOW-OTHER-KEYS(Nothing Specific)
COMMON-LISP: &AUX(Nothing Specific)
COMMON-LISP: &BODY(Nothing Specific)
COMMON-LISP: &ENVIRONMENT(Nothing Specific)
[snip]
To print out all symbols in all packages in your CL image, you would do:
CL-USER> (mapcar (lambda (package)
		   (mapcar (lambda (x) 
			     (format t "~a: ~a(~a)~%" (package-name package) (car x) (cadr x)))
			   (list-all-symbols package)))
		 (list-all-packages))
ACL-SOCKET: *DNS-CONFIGURED*(Nothing Specific)
ACL-SOCKET: *DNS-DOMAIN*(Nothing Specific)
ACL-SOCKET: *DNS-MODE*(Variable)
ACL-SOCKET: *DOMAIN-SEARCH-LIST*(Nothing Specific)
[snip]
Update-2004-10-30: This posting was updated - see comments here.

emacs Copyright © 2005 by Bill Clementson