Declarative Languages
Agony Corner

Dear Dr Levine,
I was working away at my lisp session and a console window popped up. None of my lisp windows respond any more. What should I do?
Yours, Erroneous

Dear Erroneous,
You have run into what we in the trade refer to as "deep trouble". Every time your lisp system reports an error to you, you are supposed to do something about it. If you don't, then the errors keep piling up. When they get to about 8 or 9 deep, you get the console window.
Dismiss the console by typing :top into it. Then minimize it (do not close it).
If you decide to deal with errors before you get to that stage, you have the following options:

Dear Dr Levine,
I called my function and I think there must be something wrong because it never returned and that was ten minutes ago. How do I interrupt it?
Yours, Forever.

Dear Forever,
To interrupt the lisp process, type Control-Break into the listener. This should give you a debugging prompt.
Sometimes, you might imagine your code went away and never returned, but in fact you hadn't typed in a complete lisp form yet and the listener is hung reading your form. Test for this by seeing if the listener responds at all to mouse clicks, etc. If it does then it's still waiting for input. Check you closed all your lists, strings, etc. As a last resort, Alt-K will give you a fresh prompt and you can repeat the damage.

Dear Dr Levine,
How do I find out what a function does? How do I find the function I need to do a job?
Yours, Lookitup.

Dear Lookitup,
To find out what a Common Lisp function does, look it up first in Graham. For further detail, try Cltl2 online and / or the HyperSpec (under Help / Manuals menu as "ANSI Common Lisp Standard" or go to LispWorks Browesable Documentation from your start menu). To get direct to the correct HyperSpec entry for a symbol, click on that symbol and use the key combination Control-Shift-D. This will prompt you (see thin window at bottom of listener / editor) to confirm the symbol you're interested in: type return and the html doc will be displayed for you.
To find related functions from a HyperSpec page, try the icon of an up-arrow - this will take you to a dictionary of related concepts.
To get rapidly to see the argument list for any function (yours or system), use the key combination Alt-=.
To get a list of functions with related names, try the lisp function apropos. Example:

CL-USER 14 > (apropos 'apropos 'CL)

APROPOS -- #<function APROPOS 20200D02>

CL-USER 15 >

This gives you every symbol either in Common Lisp, or typed by you, with the word "apropos" anywhere in its name. Output sometimes voluminous, but can be helpful. (Warning: (apropos 'a 'CL) will give you every symbol containing the letter "a". Stand well back.)

Dear Dr Levine,
I get muddled between the listener and the editor, and between files and buffers, and all that. Can you sort me out?
Yours, Troubled.

Dear Troubled,
Think of the listener as a scratch-pad, and the editor as where you generate your code. Points to watch out for:

Once you have written and saved your code, you need to know how to get the lisp image to pay attention to it. As ever, multiple choices for how you do it. Pick a favourite and discard the herd.

Dear Dr Levine,
How do I insert a newline into a function I'm messing with in the listener. Each time I type return it yanks the whole thing down to the prompt. It's getting annoying.
Yours, Annoyed.

Dear Annoyed,
In the listener, Return is bound to the editor command "Execute or Insert Newline or Yank from Previous Prompt" (igh). What you probably wanted was Control-O (letter O not digit 0) which stands for "Open Line". It inserts a newline into the buffer without moving anything anywhere.

Dear Dr Levine,
I wish to cultivate your suggestions for becoming a lazy typist. Can you remind me how it's done?
Yours, Slothful.

Dear Slothful,
What a good idea. Type Alt-Control-I to complete a symbol by comparing what you've typed with all the symbols in memory. Type Alt-/ to complete by looking backwards up the current window.

Dear Dr Levine,
Although it doesn't signal any errors, my code still doesn't do what I want it to? How do I fix it?
Yours, Broken

Dear Broken,
The macros trace and untrace, and the function break will all be of interest to you. Chapter 5 of the "LispWorks User Guide" will be of great use, but the basic idea is that if you trace a function, then every time it is called and every time it returns, you get a line of output in your listener to tell you about it. If the function returns abnormally (e.g by throwing - which we haven't covered yet - or by you aborting from an error), the trace output will say "Throwing".
Function break takes a format string (and format arguments if the string wants them). You insert the function in your code. When it's called, it uses the format information to print a message to the listener, then it enters a debugging loop.

CL-USER 29 > (defun foo (x)
               (if (> x 5)
                     (break "Hello, x is ~a." x)
                     (1- x))
                 (1+ (foo (+ x 2)))))

CL-USER 30 > (trace foo)

CL-USER 31 > (foo -8)
0 FOO > (-8)
  1 FOO > (-6)
    2 FOO > (-4)
      3 FOO > (-2)
        4 FOO > (0)
          5 FOO > (2)
            6 FOO > (4)
              7 FOO > (6)

Hello, x is 6.
  1 (continue) Return from break.
  2 (abort) Return to level 0.
  3 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other options

CL-USER 32 : 1 > :c
              7 FOO < (5)
            6 FOO < (6)
          5 FOO < (7)
        4 FOO < (8)
      3 FOO < (9)
    2 FOO < (10)
  1 FOO < (11)
0 FOO < (12)

CL-USER 33 >

Dear Dr Levine,
I know you're hot on getting indentation right, and I do appreciate that badly indented code is almost impossible to fix because you can't see what's happening where. How do I sort this?
Yours, Jagged.

Dear Jagged,
To indent one line of code, use the Tab key. You do not need to be at the start of the line to get this to work.
To indent a whole lisp form (eg a whole defun) click on the opening left parenthesis and use the key combination Alt-Control-Q.

Dear Dr Levine,
How do I tell whether a function is defined or not? How do I tell if it's a Common Lisp function or one of yours / mine?
Yours, Scatty

Dear Scatty,
To find out whether a symbol is defined as a function or not, use fboundp:
    (fboundp 'mapcar) => true
    (fboundp 'rubbish) => nil
To find out whether it is a Common Lisp symbol, use symbol-package:
    (symbol-package 'defun)  =>  #<PACKAGE COMMON-LISP>
    (symbol-package 'my-own-junk)  =>  #<PACKAGE COMMON-LISP-USER>
To find out whether it's a macro or a function, use macro-function:
    (macro-function 'mapcar) => nil
    (macro-function 'defun) => true
Similarly, special-operator-p will tell you whether a symbol is defined to be a special operator.

Dear Dr Levine,
How will I ever learn to use all the flash features in the Editor?
Yours, Keycode.

Dear Keycode,
I suppose the lazy (from my point of view) answer is to suggest you look in the "Editor User Guide"! A quick flick through chapter 2 may be enough. If you want to know (say) all the commands to do with moving Backwards, use the key combination Control-H A, then type the word backwards to the prompt, and see what you get.

Copyright (C) Nick Levine 1999. All rights reserved.
last modified 1999-11-02
$Id: // $