next up previous
Contents Next: Nicer Output Using Up: Input and Output Previous: Input and Output

Basic Printing

Frill-free printing in LISP is achieved with print, prin1, princ and terpri. The simplest uses of print, prin1, and princ involve a single argument. Terpri, which produces a newline, can be called with no arguments.

All these are functions. In addition to causing output, they return values. With print, princ, and prin1, the value returned is always the result of evaluating the first argument. Terpri always returns nil.

Here are examples using print:

>(print 'this)

THIS                            ;; printed
THIS                            ;; value returned

>(print (+ 1 2))

3                               ;; printed
3                               ;; returned

>(+ (print 1) (print 2))

1                               ;; first print
2                               ;; second print
3                               ;; returns sum
Print always precedes its output with a newline. Prin1 is just like print except that it does not do a new line before printing.

>(+ (prin1 1) (prin1 2))
Print is thus equivalent to terpri followed by prin1. This function will behave just like print when passed a single argument.

(defun my-print (x)
  (prin1 x))
Princ and prin1 are the same except in the way they print strings. Princ does not print the quote marks around a string:

>(prin1 "this string")
"this string"         ;; printed
"this string"         ;; returned

>(princ "this string")
this string           ;; no quotes can be more readable
"this string"         ;; string returned
The print family of functions is useful as a debugging tool. Since they return the values of their arguments, they can be inserted into a previously defined function to reveal what is going on. For example, suppose you have a function defined as follows:

(defun foo (x y)
  (if (eq x y) (list (second x) (first y))
    (list y (rest x))))
You try the function out and get this:

>(foo '(a s d f) '(a s d f))
((A S D F) (S D F))
But you expected to get (S A) since you expected to get the list of the second of x with the first of y.

You would like to know why foo returned this. One way to help you see what is going on is to insert print statements into the definition. If for example you want to see what is being listed if the test is true, you can modify the definition like this:

(defun foo (x y)
  (if (eq x y) (list (print (second x)) (print (first y)))
    (list y (rest x))))
Now when you try the same call, the following happens:

>(foo '(a s d f) '(a s d f))
((A S D F) (S D F))
But this is just the same as before! Neither print function got called, so you deduce that the test must have returned nil. This should help you to recall the difference between eq and equal. Now you modify the definition of foo again:

(defun foo (x y)
  (if (equal x y) (list (print (second x)) (print (first y)))
    (list y (rest x))))
And try it out:

>(foo '(a s d f) '(a s d f))

(S A)
This time you see the effects of the prints, and what values get combined to produce the result. Thus print helps you to debug your code.

next up previous
Contents Next: Nicer Output Using Up: Input and Output Previous: Input and Output

© Colin Allen & Maneesh Dhagat
November 1999