[2/10/99] =============================================================================== * Due to hour and mental state, not all examples appear in text. =============================================================================== * A quick overview of basic Scheme types, go over these really quick: 123 - integers 12/13 - rationals 0.92 - floats 1+3i - complexes +inf.0 and -inf.0 - special floating values "xxx" - strings (some useful functions like string-append etc). #\space - characters Coming up - compund values - lists. Note - in a need for some type, go to the documentations to find out what functions you have for it. Quick note - there are some conversion functions in Scheme such as string->number, char->number, number->string etc. =============================================================================== * More games with "let" form, remind the equivalence -------------------- (let ((x 1) (y 2)) (+ x y)) vs. ((lambda (x y) (+ x y)) 1 2) -------------------- and how: -------------------- (define x 1) (define x 2) (let ((x y) (y x)) (+ x x y)) -------------------- evaluates. A problem, that comes from this definition: -------------------- (let ((f (lambda (n) (if (zero? n) 1 (* n (f (- n 1))))))) (f 3)) -------------------- doesn't work because the way that let is defined (its semantics that we get be the semantics of lambda abstraction and application) - here's an example why: -------------------- ((lambda (f) (f 3)) (lambda (n) (if (zero? n) ...))) ((lambda (n) (if (zero? n) ...)) 3) (if (zero? 3) ... f...) -------------------- And it is clear now that f is unbound. We will see a solution later. =============================================================================== * Many times, we want to bind local values, and use these values for more local bindings. For this we have let*: -------------------- (let* ((v1 exp1) (v2 exp2) ...) body...) == (let ((v1 exp1)) (let ((v2 exp2)) (... body ...))) == (((((lambda (v1) (lambda (v2) (... body ...))) exp1) exp2) ...) expn) -------------------- Some simple example - what now happens to: -------------------- (define x 1) (define x 2) (let* ((x y) (y x)) (+ x x y)) -------------------- This is still not enough for local recursive functions, example: -------------------- (let* ((f (lambda (x) (+ x 1))) (f (lambda (x) (f (+ x 1))))) (f 4)) -------------------- will terminate with 6. =============================================================================== * Lists: Quick introduction to simple lists (not dotted lists): -------------------- empty - the empty list (sometimes "'()" or just "()") (cons x l) - list constructor: get some value x, and a list l, create the list that starts with x and continues with l. Examples. (head l) - returns the head of a list. Also first (and the standard: car). (tail l) - returns the tail of a list. Also rest (and the standard: cdr). (list x1 x2...) - short for (cons x1 (cons x2 (cons ... empty))) second, third... - useful functions (std: cadr, caddr...). -------------------- A quick note about the old age of the car/cdr names. Another note - you might see these car/cdr in documentations, and also in error messages. The only thing we care about with lists is that they behave according to a well defined _contract_: -------------------- (head (cons x l)) --> x (tail (cons x l)) --> l -------------------- ===============================================================================