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 always precedes its output with a newline. Prin1 is just like print except that it does not do a new line before printing.> (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 is thus equivalent to terpri followed by prin1. This function will behave just like print when passed a single argument.> (+ (prin1 1) (prin1 2)) 12 3
Princ and prin1 are the same except in the way they print strings. Princ does not print the quote marks around a string:(defun my-print (x) (terpri) (prin1 x))
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:> (prin1 "this string") "this string" ;; printed "this string" ;; returned > (princ "this string") this string ;; no quotes can be more readable "this string" ;; string returned
You try the function out and get this:(defun foo (x y) (if (eq x y) (list (second x) (first y)) (list y (rest x))))
But you expected to get (S A) since you expected to get the list of the second of x with the first of y.> (foo '(a s d f) '(a s d f)) ((A S D F) (S D F))
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:
Now when you try the same call, the following happens:(defun foo (x y) (if (eq x y) (list (print (second x)) (print (first y))) (list y (rest x))))
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:> (foo '(a s d f) '(a s d f)) ((A S D F) (S D F))
And try it out:(defun foo (x y) (if (equal x y) (list (print (second x)) (print (first y))) (list y (rest x))))
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.> (foo '(a s d f) '(a s d f)) S A (S A)
© Colin Allen & Maneesh Dhagat