;;; Here are two examples of objects whose printed representations ;;; look the same as their read representations. Don't be fooled ;;; though: in both of these cases the system starts with a ;;; a character string, which reads to a number, which (self-)evaluates ;;; to a number, which then appears as a character string. ;;; ;;; Also note that since 3 and 3.0 print differently, they are probably ;;; *not* equivalent objects. In this case the former is an integer ;;; and the latter is a float. USER(1): 3 3 USER(2): 3.0 3.0 ;;; Notice in this case the read->eval->print translation actually ;;; does something. USER(3): 3.0000000 3.0 ;;; The printer outputs floats with enough precision to get ;;; the numerical value exactly right. USER(4): 3.00001 3.00001 ;;; This is a new type of number: a ratio of integers. USER(5): (/ 6 8) 3/4 ;;; Here we saw what happens when you make an error (not how ;;; the prompt changes). Also saw how to look at the call stack ;;; and reset out of the error. USER(6): (exp 2 32) Error: EXP got 2 args, wanted at most 1. [condition type: PROGRAM-ERROR] [1] USER(7): (power 2 32) Error: attempt to call `POWER' which is an undefined function. [condition type: UNDEFINED-FUNCTION] Restart actions (select using :continue): 0: Try calling POWER again 1: Return a value 2: Try calling a different function 3: Setf the symbol function of POWER and call it again ;;; Now we have two errors. The next command allows you to ;;; look at the call stack. Note that since it starts with a ;;; colon, it is a directive to the Allegro system, and doesn't ;;; go through the normal Lisp read/eval/print loop. [2] USER(8): :zoom Evaluation stack: (ERROR #) ->(EVAL (POWER 2 32)) (ERROR PROGRAM-ERROR :FORMAT-CONTROL ...) (EXP 268432164) (EXP 268432215) (EVAL (EXP 2 32)) (TPL:TOP-LEVEL-READ-EVAL-PRINT-LOOP) (TPL:START-INTERACTIVE-TOP-LEVEL # # ...) ;;; This gets rid of all the errors on the call stack [2] USER(9): :res USER(10): :zoom Evaluation stack: ->(TPL:TOP-LEVEL-READ-EVAL-PRINT-LOOP) (TPL:START-INTERACTIVE-TOP-LEVEL # # ...) ;;; The function = takes any two numbers and compares their ;;; values. The interesting thing here is that evaluating actually ;;; causes a function to be executed. USER(13): (= 0.75 (/ 6 8)) T ;;; For each data type there is a "predicate" that tells you whether ;;; an object is a member of that data type. It's important to ;;; note the convention that T is true and NIL is false. USER(14): (numberp 3) T USER(15): (numberp T) NIL ;;; The real mystery here is why NIL showed up. It's a two-part ;;; answer: every function has to return something, and by ;;; convention a function returns NIL when the return result ;;; is "useless." The function FORMAT is run for its side ;;; effect (printing something out) rather than for its return ;;; result. USER(16): (format t "hi mom") hi mom NIL ;;; The question is, what is the data type of T. We'll get ;;; to that next time. USER(17): (numberp T) NIL ;;; This last bit tells you how to input characters and ;;; strings. Notice that there is a difference in this ;;; case between upper case and lower case, and also that ;;; there is a difference between a character and a string ;;; with one element. ;;; This is a character, the lower-case letter a [1] USER(21): #\a #\a ;;; This is a string with a single element (the character ;;; lower-case a [1] USER(22): "a" "a" ;;; The character upper-case A [1] USER(23): #\A #\A ;;; And the string with that character as an element USER(24): "A" "A" ;;; This is how you exit from Lisp USER(32): :ex ; killing "Editor Server" ; killing "TCP Listener Socket Daemon" ; killing "Initial Lisp Listener" ; Exiting Lisp