;;; This is just to remind you: there is no principled difference ;;; between system-defined functions like + and those you define yourself. ;;; + is just a symbol like any other, it just happens to have a ;;; pre-defined function binding. USER(1): '+ + USER(2): '- - ;;; A symbol has a value binding and a function binding, and there ;;; is no conflict between them. Notice below that there are ;;; two different fields in the data structure. USER(3): (defun sum-of-squares (x y) ) SUM-OF-SQUARES USER(4): (setf sum-of-squares 67.2) 67.2 USER(5): (inspect sum-of-squares) single-float = 67.2 [#x42866666] @ #x1068c36a [1i] USER(6): (inspect 'sum-of-squares) The symbol SUM-OF-SQUARES @ #x1074abc7 which is an INTERNAL symbol in the COMMON-LISP-USER package 0 flags --------> Bit field: #x0000 1 hash ---------> Bit field: #xea07 2 value --------> single-float = 67.2 [#x42866666] 3 reserved -----> Bit field: #x00000000 4 package ------> The COMMON-LISP-USER package 5 func-start ---> Bit field: #x00000000 6 function -----> # 7 name ---------> A simple-string (14) "SUM-OF-SQUARES" 8 plist --------> The symbol NIL [2i] USER(7): :res ;;; Reminder: symbol names are case insensitive (converted to upper ;;; case). The EQ got us talking about equality: USER(8): 'fred FRED USER(9): (eq 'fred 'fReD) T ;;; Here is a case in which v1 and v2 are pointing to the same object, ;;; so they are EQ. USER(10): USER(10): (setf v1 3.75) 3.75 USER(11): (setf v2 v1) 3.75 USER(12): (eq v1 v2) T ;;; But now we set v1 and v2 to two different "copies" of the floating ;;; point number 3.75. They no longer have the same address, ;;; so they are not EQ any more. However, they are numerically equal ;;; because the two (different) objects they point to have the same ;;; numeric value. USER(13): (setf v2 3.75) 3.75 USER(14): (setf v1 3.75) 3.75 USER(15): (eq v1 v2) NIL USER(15): (= v1 v2) T ;;; There was some question about the situation in which V1 and ;;; V2 were pointing to the same address, then V1 was modified, ;;; would V2 be changed too? The answer is no: when we do the ;;; second SETF to V1, it adjusts V1's pointer, not the ;;; internal state of what V1 is pointing to. USER(16): (setf v1 3.75) 3.75 USER(17): (setf v2 v1) 3.75 USER(18): (eq v1 v2) T USER(19): (setf v1 "abc") "abc" USER(20): v1 "abc" USER(21): v2 3.75 ;;; This is more material about equality checking. The important ;;; thing to keep in mind is that every data type has an ;;; appropriate equality tester. For numbers, use =. For symbols, ;;; use EQ. For characters, it turns out CHAR= is the predicate ;;; (which I couldn't remember in class. USER(26): (setf v1 3.75) 3.75 USER(27): (setf v2 3.75) 3.75 USER(28): (eq v1 v2) NIL USER(29): (= v1 v2) T USER(30): (= 0.75 3/4) T USER(31): (= 'fred 'fred) Error: FRED is an illegal argument to = [condition type: TYPE-ERROR] USER(37): (eql #\a #\b) NIL USER(38): (eql #\a #\a) T ;;; Now some discussion of T, NIL, and the Boolean ;;; data type. First of all, T and NIL are just symbols, ;;; but (unlike any others) they are self-evaluating symbols. USER(42): (symbolp 't) T USER(43): (symbolp 'nil) T USER(44): t T USER(47): (inspect 't) The symbol T @ #x1063402f which is an EXTERNAL symbol in the COMMON-LISP package 0 flags --------> Bit field: #x4000 1 hash ---------> Bit field: #x007c 2 value --------> The symbol T 3 reserved -----> Bit field: #x00000000 4 package ------> The COMMON-LISP package 5 func-start ---> Bit field: #x00000000 6 function -----> # 7 name ---------> A simple-string (1) "T" 8 plist --------> <...>, a proper list with 14 elements ;;; Logical operations, like AND OR NOT, and conditionals like IF ;;; generally (but not always) return the canonical truth values ;;; T (for true) and NIL (for false). USER(48): (> 2 3) NIL USER(49): (not t) NIL USER(50): (not nil) T ;;; Notice also that some functions can take a variable ;;; number of arguments. USER(52): (or NIL T NIL) T ;;; Why should this be? I sent out an Email message explaining. USER(53): (or) NIL USER(54): (and) T USER(55): (+) 0 ;;; But the important thing to remember: the real boolean data ;;; type is implemented by letting the symbol NIL be the value ;;; false and *any object other than NIL* be the value true. USER(56): (not 'ABC) NIL USER(57): (not "some-string") NIL ;;; This is a little bit strange, but OR and AND return the ;;; first and last non-NIL value in their arguments, respectively, ;;; when they return true. Note that this is perfectly OK, since ;;; any non-NIL value is equivalent. USER(58): (or "xyz" "www") "xyz" USER(59): (and 'A 'B #\c) #\c USER(58): (or "a" 'X) "a"