CS 541 Lecture -*- Outline -*- * Built-in types of Scheme ad: these are needed for all programming in Scheme effect: understand built-in types and their operations understand different kinds of recursion and their importance ** Fundamental classifications *** atoms: string of characters beginning with letter, digit, or char other than "(" or ")" subdivided into booleans, symbols, strings, numbers, chars #t, #f, symbol, "string", 27.3, #\c, () *** lists: sequence of S-expressions enclosed by parentheses (atom turkey or), (), ((a b) c) *** S-expression: atom, or list atom, (a b), ((a b) c ()), () note that () is both a list and an atom, and same as #f in C-scheme make a table as discuss the following: type constructors observers symbol quote : -> symbol symbol? : object -> boolean eq? : symbol, symbol -> boolean ** symbol ---------------------- (quote a) ;Value: a (symbol? (quote a)) ;Value: #T (eq? (quote a) (quote a)) ;Value: #T (eq? (quote a) (quote b)) ;Value: () (eq? 'a 'A) ; case does not matter for symbols ;Value: #T (eq? '() #f) ;Value: #T ---------------------- Notation: (quote a) is written 'a. *** quotation suppresses evaluation ---------------------- (define a-symbol 3) a-symbol ;Value: 3 'a-symbol ;Value: a-symbol ''a-symbol ;Value: 'a-symbol ; not needed for "self-evaluating" atoms: numbers, strings, booleans 3 ;Value: 3 (quote 3) ;Value: 3 ---------------------- ** Boolean ---------------------- ; false is #f, which in C-scheme is represented by () ; true is #t, and is represented by everything that is not eq? to #f #f ;Value: () #t ;Value: #T (not #t) ;Value: () (not #f) ;Value: #T ---------------------- ---------------------- ; suppose value of e1 is val-e1 and value of e2 is val-e2 (define e1 'val-e1) (define e2 'val-e2) (if #t e1 e2) ;Value: val-e1 (if #f e1 e2) ;Value: val-e2 (and e1 e2) =def= (let ((ve1 e1)) (if (not (null? ve1)) e2 ve1)) (or e1 e2) =def= (let ((ve1 e1)) (if (null? ve1) e2 ve1)) ---------------------- *Note: 'if' is not strict (so neither is 'and' nor 'or')* *** Notation: conditional statement ---------------------- (cond (#t e1)) ;Value: val-e1 (cond (#f e1)) ;Value: () (cond (e11 e12) ... (en1 en2)) =def= (if e11 e12 (cond (e21 e22) ... (en1 en2))) (cond (e1 e2) ... (else en2)) =def= (cond (e1 e2) ... (#t en2)) ---------------------- example: (cond (e1 e2) (#t e3)) =def= (if e1 e2 e3) ** lists cons, car, cdr, null?, equal? ---------------------- ; suppose value of x is x and value of y is y (define x 'x) (define y 'y) ; suppose l is the list (a b c), l2 is list (d e) (define l '(a b c)) (define l2 '((d) (e))) (cons x '()) ;Value: (x) (car (cons x l)) ;Value: x (cdr (cons x l)) ;Value: (a b c) (pair? (cons x l)) ;Value: #T (pair? '()) ;Value: () (null? '()) ;Value: #T (null? (cons x l)) ;Value: () (equal? '() '()) ;Value: #T (equal? (cons x l) (cons y l2)) =def= (and (eqv? x y) (equal? l l2)) ;Value: () (list 'a 'b 'c) =def= (cons 'a (cons 'b (cons 'c '()))) ;Value: (a b c) ---------------------- *** Notation: quotes and quasi-quotes ------------------------ '() ;Value: () '(a b c) =def= (quote (a b c)) ;Value: (A B C) `(e1 e2) =def= (quasiquote (e1 e2)) ;Value: (E1 E2) `(,e1 ,e2) =def= (quasiquote ((unquote e1) (unquote e2))) ;Value: (val-e1 val-e2) `(,@l ,l) =def= (quasiquote ((unquote-splicing l) (unquote l))) ;Value: (A B C (A B C)) (caar l2) =def= (car (car l2)) ;Value: D (cadr l2) =def= (car (cdr l2)) ;Value: E ------------------------ *** Dotted pairs (cons cells, trees): *draw graphical representation* '(a . b) =def= (cons 'a 'b) ;Value: (A . B) '(a . (b . ())) ;Value: (A B) lists always end in '(), dotted pairs don't necessarily. *** Other important type: procedures, will be discussed later *** Examples **** normal recursion on lists, ask if null? first -------- (define (length-recursive x) (if (null? x) 0 (+ 1 (length-recursive (cdr x))))) --------- **** tail recursive: last call in function is recursive, no deferred operations: --------- (define (length-tail-recursive x) (define (length-iter a count) (cond ((null? a) count) (else (length-iter (cdr a) (+ 1 count))))) (length-iter x 0)) --------- *show execution of (length-x '(a b c)) Tail-recursive function can be interpreted using only constant amount of space. Like iteration. **** additional operations on lists ***** append -------- (define (append-recursive x y) (cond ((null? x) y) (else (cons (car x) (append-recursive (cdr x) y))))) --------- No good way to do append tail-recursively (without reversing first argument). ***** reverse --------- (define (reverse-recursive x) (cond ((null? x) x) (else (append (reverse-recursive (cdr x)) (list (car x)))))) (define (reverse-tail-recursive x) (define (reverse-iter y res) (cond ((null? y) res) (else (reverse-iter (cdr y) (cons (car y) res))))) (reverse-iter x '())) ---------- *** Lists can represent other data structures **** arrays -easy (although built-in to most dialects) **** variants - tag (in car) + object (in rest of list) **** records - association lists (or property lists) ***** Association lists (records) list of pairs (each of which represents a key-value association) first association in list is one found by assoc (duplicates allowed) ----------- (define (acons key datum alist) (cons (cons key datum) alist)) (define (assoc key alist) (cond ((null? alist) '()) ((and (pair? (car alist)) (equal? key (caar alist))) (car alist)) (else (assoc key (cdr alist))))) ; tail recursive ----------- ** Eq? vs. eqv? vs. equal? *** eq? compares symbols, booleans, and lists for object identity (same list pointer, name) *** eqv? compares as eq? for symbols, booleans, lists, but guaranteed to work for numbers and strings *** equal? compares structure, using eqv? as basis for comparing atoms. *in functional programs, almost always want to use equal? instead of eq?