I. introduction to CLU II. Introduction to CLU A. History and Goals 1. History ------------------------ 1968 Algol 68 (lots of coercions, negative influence) (1970s were the golden age of language design, "structured prog") 1971 Pascal 1971 Parnas begins promoting notion of information hiding (modularity) 1973 Barbara Liskov's group at MIT begins design of CLU 1975 initial verision of CLU implemented no exception handling 1978 essentially final version of CLU ------------------------ 2. Goals B. Abstraction in general 1. Abstraction Techniques a. parameterization b. specification 2. Kinds of abstractions a. procedural (lambda) b. data c. control 3. examples ------------------ ; in LISP (set the-empty-tree '(tree)) (define tree-make (left node right) ; : tree, s-exp, tree -> tree (cons 'tree (cons left (cons node (cons right '()))))) (define leaf-make (node) ; : s-exp -> tree (tree-make the-empty-tree node the-empty-tree)) (define post-order2 (tree) (if (null? (cdr tree)) '() (append (post-order2 (cadr tree)) (append (post-order2 (caddr tree)) (cons (caddr (cdr tree)) '()))))) (define tree-empty? (tree) (null? (cdr tree))) (define tree-left (tree) (car (cdr tree))) (define tree-root (tree) (cadr (cdr tree))) (define tree-right (tree) (caddr (cdr tree))) (define append3 (l1 l2 l3) (append l1 (append l2 l3))) (define post-order (tree) (if (tree-empty? tree) '() (append3 (post-order (tree-left tree)) (post-order (tree-right tree)) (list1 (tree-root tree))))) ------------------ ------------------ (set the-empty-tree '()) (define tree-make (left node right) ; : tree, s-exp, tree -> tree (cons left (cons node (cons right '())))) (define leaf-make (node) ; : s-exp -> tree (tree-make the-empty-tree node the-empty-tree)) (define tree-empty? (tree) (null? tree)) (define tree-left (tree) (car tree)) (define tree-root (tree) (cadr tree)) (define tree-right (tree) (caddr tree)) ------------------ ---------------------- ; in CLU (Kamin's version) (cluster Tree ; Export: make, empty, empty?, ; left, right, root (rep lst) ; if lst is empty, tree is empty ; else (List$car lst) is left subtree, ; (List$car (List$cdr lst)) is root, ; (List$car (List$cdr (List$cdr lst))) ; is right subtree (define empty () ; -> Tree (Tree List$nil)) (define make (left node right) ; : Tree, object, Tree -> Tree (Tree (List$cons left (List$cons node (List$cons right List$nil))))) (define empty? (tree) (List$null? (lst tree))) (define left (tree) (List$car (lst tree))) (define root (tree) (List$car (List$cdr (lst tree)))) (define right (tree) (List$car (List$cdr (List$cdr (lst tree))))) ) (define leaf-make (node) ; : Object -> Tree (tree$make Tree$empty node Tree$empty)) (load libraray.clu) (define append (x y) (if (List$null? x) y (List$cons (List$car x) (append (List$cdr x) y)))) (define append3 (l1 l2 l3) (append l1 (append l2 l3))) (define post-order (tree) (if (Tree$empty? tree) List$nil (append3 (post-order (Tree$left tree)) (post-order (Tree$right tree)) (list1 (Tree$root tree))))) ---------------------- ---------------------- (cluster Tree ; Export: make, empty, empty?, ; left, right, root (rep defined l n r) ; if defined = 0, tree is empty ; otw, defined = 1 and l is left subtree ; n is value of the root node, ; r is right subtree (define empty () ; -> Tree (Tree 0 0 0 0)) (define make (left node right) ; : Tree, object, Tree -> Tree (Tree 1 left node right)) (define empty? (tree) (= 0 (defined tree))) (define left (tree) (l tree)) (define root (tree) (n tree)) (define right (tree) (r tree)) ) ---------------------- III. Data Abstraction A. computer systems are abstract data types B. Hiding the representation (thinking abstractly about data structures) 1. representation is a choice of data structure 2. representation independence 3. int 4. notes (degrees of a scale) 5. points (of integers) 6. chords ------------- (cluster Chord ; Export: create, soprano, alto, tenor, bass, display ; SUMMARY: 4-part chords (immutable) (rep b t a s) ; ABSTRACTION FUNCTION: r: rep represents a chord with bass b, ; tenor t, alto a, and soprano s ; REP INVARIANT: b < t < a < s (define create (bs ten alt sop) ; TYPE: Note * Note * Note * Note -> Chord ; REQUIRES: bs < ten < alt < sop ; EFFECT: return the chord with bass bs, tenor ten, alto alt, soprano sop (Chord bs ten alt sop)) (define soprano (c) ; TYPE: Chord -> Note ; EFFECT: Return the soprano note of c (s c)) (define alto (c) ; TYPE: Chord -> Note ; EFFECT: Return the alto note of c (a c)) (define tenor (c) ; TYPE: Chord -> Note ; EFFECT: Return the tenor note of c (t c)) (define bass (c) ; TYPE: Chord -> Note ; EFFECT: Return the bass note of c (b c)) (define display (c) ; TYPE: Chord -> () ; EFFECT: display the sop, alto, tenor and bass of c (in that order) (begin (Note$display (s c)) (Note$display (a c)) (Note$display (t c)) (Note$display (b c)))) ) ; Chord ------------ C. Clusters (modules that implement data abstractions) 1. operation export and hiding 2. representation (rep) IV. Semantic model: objects, environment, assignment, calls A. Objects 1. Mutable objects 2. Immutable objects B. Environment 1. variables C. Assignment D. Calling mechanism ---------- ; example showing mutation and aliasing (define back-rotate (p) ; p:Point ; MODIFIES: p ; EFFECT: rotate p -90 degrees (begin (Point$rotate p) (Point$rotate p) (Point$rotate p))) (define start_up () (begin (set p1 (Point$new 3 5)) (set p2 p1) ; makes p1 and p2 aliases (Point$reflect p1) ; mutates p1 (print (Point$abscissa p2)) ; what is printed here? -3 then -5 (print (Point$ordinate p2)) (back-rotate p1) (print (Point$abscissa p2)) ; what is printed here? 5 then -3 (print (Point$ordinate p2)) (print (Point$abscissa p2)) ; what is printed here? 5 then -3 (print (Point$ordinate p2)))) ---------- V. Type checking in the REAL CLU A. structural (for equates) B. By name for abstract types C. security of data abstraction (langauge enforcement of data abtraction) 1. up 2. down 3. cvt 4. rep type not equal to abstract type D. Across module boundaries (library, type-safe linkage) VI. Exception Handling A. What is an exception? B. Is a language-defined exception handling mechanism necessary? 1. require that caller insure that they don't happen 2. status codes 3. label parameters (gotos) 4. pass procedure to be called in case of exception C. Trade-offs in langauge-defined exception mechanism 1. benefits: 2. problems: D. Trade-offs in use of exceptions (exceptions vs. precondition) E. Exceptions in CLU 1. Where can exceptions be handled? a. single level model (CLU) b. multiple level model (Ada) 2. Declarations ----------- pop = proc(s: stack) signals(empty) ----------- 3. Interaction with type checking 4. Raising an exception (signal statement) ----------------------- if rep$empty(s) then signal empty end ---------------------- a. Effect of raising an exception i. termination model (CLU) ii. resumption model (Mesa, Ceder, ...) 5. Exceptions handlers ----------- stack$pop(foo(mystack)) except when empty: % handler code stream$putl(stderr, "popped empty stack") when foo_ex(i: int) stream$putl(stderr, "foo exception: " || int$unparse(i)) when bar, baz (*): % ignore exception results, if any, of these % bar and baz may have different number and types of exception results others: % all other exceptions handled here but results are lost end % flow continues here ----------- a. scope of exception handlers b. Unhandled exceptions