Chapter 10 - How to Find Your Way Around, Part 1

In this chapter, you'll learn how to find your way around Common Lisp without resorting so often to the manuals. (You do read the fine manuals, don't you?)

Oh, there's one thing you should keep in mind while you're reading this chapter: all of these tools work equally well for the built-in functionality of your Lisp system and for all of the Lisp programs that you write.

APROPOS: I don't remember the name, but I recognize the face

Common Lisp defines 978 symbols. Whatever implementation you use probably defines hundreds of additional symbols for language extensions, additional libraries, a graphical user interface, etc. Are you going to remember the names of all these symbols? Not likely...

What you can do is to remember part of the name. This is pretty easy, because the language and library designers have a limited memory (just like you and me) and they tend to name related objects with similar names. So, most of the mapping functions (see Chapter 12) will have MAP in their names, the GUI library will probably have WINDOW in the names of all the functions, macros, and variables having something to do with windows, and so on.

Once you have a good guess at a part of a name, you can find all of the matching names by using a very handy tool named APROPOS.

? (apropos "MAP" :cl)
MAP, Def: FUNCTION
MAP-INTO, Def: FUNCTION
MAPC, Def: FUNCTION
MAPCAN, Def: FUNCTION
MAPCAR, Def: FUNCTION
MAPCON, Def: FUNCTION
MAPHASH, Def: FUNCTION
MAPL, Def: FUNCTION
MAPLIST, Def: FUNCTION

APROPOS expects a string or a symbol -- this provides the fragment of the name that you'd like to find. An optional second argument designates a package; use it if you'd like to limit your search to the symbols in a particular package. The package designator can be a string or symbol matching the name or nickname of a package (see Chapter 3, Lesson 10), or it can be the package object itself. If you omit the package designator, then APROPOS will search for symbols in all packages.

Your Lisp implementation may produce output that looks somewhat different from that shown here. Generally, you'll see the symbol names listed with a very brief description of the global object named by the symbol.

Here's an example of the output from APROPOS on my Lisp system when I search without a package designator:

? (apropos "SEQUENCE")
       TOOLS::BROWSER-SEQUENCE-TABLE
         CCL::CHECK-SEQUENCE-BOUNDS, Def: FUNCTION
     ITERATE::CHECK-SEQUENCE-KEYWORDS, Def: FUNCTION
       TOOLS::CLASS-BROWSER-SEQUENCE-TABLE
     ITERATE::CLAUSE-FOR-IN-SEQUENCE-0, Def: FUNCTION
     ITERATE::CLAUSE-FOR-INDEX-OF-SEQUENCE-0, Def: FUNCTION
         CCL::CONSED-SEQUENCE
; many lines omitted 
              STREAM-READ-SEQUENCE, Def: STANDARD-GENERIC-FUNCTION
              STREAM-WRITE-SEQUENCE, Def: STANDARD-GENERIC-FUNCTION
   DEFSYSTEM::SYSTEMS-SEQUENCE-DIALOG-ITEM
              TAB-SEQUENCE-ITEM
              TABLE-SEQUENCE, Def: STANDARD-GENERIC-FUNCTION
             :TABLE-SEQUENCE,  Value: :TABLE-SEQUENCE
  SETF::|CCL::TABLE-SEQUENCE|, Def: STANDARD-GENERIC-FUNCTION
              WRITE-SEQUENCE, Def: FUNCTION

Notice that most of the symbols are prefixed with a package name, since they are not imported into the current (COMMON-LISP-USER) package. Again, your Lisp implementation may produce somewhat different results, but it should show you a list of symbols with package prefixes, plus whatever other information the designers of your implementation thought would be helpful yet concise.

In these examples, I've used uppercase strings as arguments to APROPOS. Some implementations perform a case-sensitive match, while others ignore case. Symbol names are case sensitive in Lisp, but the Lisp reader translates symbols to uppercase by default. So if you specify an uppercase name to APROPOS you'll find most -- perhaps all -- of the matching names; you'll miss only those that were intentionally interned using lower case letters. And if your APROPOS ignores case, you'll get all of the matches, regardless of case.

You could also supply a symbol to APROPOS. The only disadvantage of this is that these partial symbols pollute the namespace of the current package. The storage requirement is trivial, but you'll have to be aware that APROPOS may find these partial symbols in future matches, and you'll have to ignore these to find the symbols you'd really like to see.

DESCRIBE: Tell me more about yourself

Once you know the name of a symbol, you can get additional information by using the DESCRIBE function. As with APROPOS, the output of DESCRIBE varies among Lisp implementations. Here's an example generated using my Lisp system:

; Describe a symbol 
? (describe 'length)
Symbol: LENGTH
Function
EXTERNAL in package: #<Package "COMMON-LISP">
Print name: "LENGTH"
Value: #<Unbound>
Function: #<Compiled-function LENGTH #x34C39B6>
Arglist: (SEQUENCE)
Plist: (:ANSI-CL-URL "fun_length.html")
; Describe a string 
? (describe "LENGTH")
"LENGTH"
Type: (SIMPLE-BASE-STRING 6)
Class: #<BUILT-IN-CLASS SIMPLE-BASE-STRING>
Length: 6
0: #\L
1: #\E
2: #\N
3: #\G
4: #\T
5: #\H
; Describe a function 
? (describe #'length)
#<Compiled-function LENGTH #x34C39B6>
Name: LENGTH
Arglist (declaration): (SEQUENCE)

This example used three different argument types: a symbol, a string, and a function. These are all correct, but you get what you ask for. These all have their uses, but you will generally want to supply a symbol argument to DESCRIBE, because it tends to produce the most information.

INSPECT: Open wide and say "Ah..."

INSPECT is like DESCRIBE, but instead of printing the information it presents the information in some kind of interactive display; typically either a command loop in the current listener or a new window with its own user interface. You should experiment with INSPECT on your own Lisp system to learn how it behaves.

INSPECT is very handy for exploring complex nested data structures, since you can "drill down" to just the information that interests you at the moment. Most INSPECTs offer specialized viewers for certain types of data, such as functions and CLOS objects. Many implementations of INSPECT also allow you to edit the data being inspected.

DOCUMENTATION: I know I wrote that down somewhere

Sometimes, you need to know more about a variable than you can discover with INSPECT. And for functions, you really need the programmer's description (unless you're willing to read assembly language code, see Chapter 16 if you have these urges). The DOCUMENTATION function gives you access to the programmer's innermost thoughts (or at least what she was willing to write in a documentation string).

The DOCUMENTATION function expects two arguments. The first is an object for which you wish to retrieve documentation, or a symbol naming that object. The second is a symbol designating the kind of documentation (there are several) you wish to retrieve.

The interface described above is the one required by the ANSI Common Lisp specification. Some implementations still support an interface which predates the ANSI specification -- these expect a symbol for both arguments. We'll use that convention in our examples, since it works in both ANSI and pre-ANSI implementations.

Several Lisp constructs let you provide an optional documentation string. The following table shows the second DOCUMENTATION argument (first line of each pair) together with the Lisp constructs for which documentation strings are retrieved.

'variable
defvar, defparameter, defconstant
'function
defun, defmacro, special forms
'structure
defstruct
'type
deftype
'setf
defsetf

The list above works in both ANSI and pre-ANSI Lisp implementations. The following list shows the documentation types which have been added for ANSI implementations.

'compiler-macro
define-compiler-macro
'method-combination
define-method-combination
t
Documentation returned depends upon type of first argument.

Here are some examples:

? (documentation 'length 'function)
"returns the number of elements in sequence."
? (defun a-function-with-docstring ()
    "This function always returns T."
    t)
A-FUNCTION-WITH-DOCSTRING
? (documentation 'a-function-with-docstring 'function)
"This function always returns T."

If you specify a symbol for which there is no documentation, or a documentation type which does not select documentation defined for the symbol, then DOCUMENTATION will return NIL.

A Lisp implementation is permitted to discard documentation strings. If documentation strings from your own program are not accessible via the DOCUMENTATION function, consult your implementation's manual to find out whether there's a way to retain documentation strings (there usually is). If documentation strings are missing from Common Lisp functions or from vendor supplied libraries, consult your vendor.


Contents | Cover
Chapter 9 | Chapter 11
Copyright © 1995-1999, David B. Lamkins
All Rights Reserved Worldwide

This book may not be reproduced without the written consent of its author. Online distribution is restricted to the author's site.