Control
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Control

on

  • 487 views

 

Statistics

Views

Total Views
487
Views on SlideShare
487
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Control Presentation Transcript

  • 1. Control in Sequential Languages + some discussion of functional programming John Mitchell CS 242 Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter 4, Section 4.4 (only) Fall 2008
  • 2. JavaScript blocks and scopes
    • { } groups JavaScript statements
      • Does not provide a separate scope
    • Blocks w/scope can be expressed using function
      • (function(){ … })() - create function of no args and call
      • Example
      • var y=0;
      • (function () { // begin block
      • var x=2; // local variable x
      • y = y+x;
      • }) (); // end block
    RECAP
  • 3. Homework 1, Problem 6
      • var x = 5;
      • function f(y) {return (x+y)-2};
      • function g(h){var x = 7; return h(x)};
      • {var x = 10; g(f)};
      • var x = 5;
      • function f(y) {return (x+y)-2};
      • function g(h){var x = 7; return h(x)};
      • {var x = 10; g(f)};
      • (function (){
      • var x = 5;
      • (function (){
      • function f(y) {return (x+y)-2};
      • (function (){
      • function g(h){var x = 7; return h(x)};
      • (function (){
      • var x = 10; g(f);
      • })()
      • })()
      • })()
      • })()
  • 4. Topics
    • Structured Programming
      • Go to considered harmful
    • Exceptions
      • “ structured” jumps that may return a value
      • dynamic scoping of exception handler
    • Continuations
      • Function representing the rest of the program
      • Generalized form of tail recursion
    • Discussion of functional programming
      • Relevant to Haskell, section 4.4 of text
  • 5. Fortran Control Structure
      • 10 IF (X .GT. 0.000001) GO TO 20
      • 11 X = -X
      • IF (X .LT. 0.000001) GO TO 50
      • 20 IF (X*Y .LT. 0.00001) GO TO 30
      • X = X-Y-Y
      • 30 X = X+Y
      • ...
      • 50 CONTINUE
      • X = A
      • Y = B-A
      • GO TO 11
    Similar structure may occur in assembly code
  • 6. Historical Debate
    • Dijkstra, Go To Statement Considered Harmful
      • Letter to Editor, C ACM , March 1968
      • Link on CS242 web site
    • Knuth, Structured Prog. with go to Statements
      • You can use goto, but do so in structured way …
    • Continued discussion
      • Welch, “GOTO (Considered Harmful) n , n is Odd”
    • General questions
      • Do syntactic rules force good programming style?
      • Can they help?
  • 7. Advance in Computer Science
    • Standard constructs that structure jumps
      • if … then … else … end
      • while … do … end
      • for … { … }
      • case …
    • Modern style
      • Group code in logical blocks
      • Avoid explicit jumps except for function return
      • Cannot jump into middle of block or function body
  • 8. Exceptions: Structured Exit
    • Terminate part of computation
      • Jump out of construct
      • Pass data as part of jump
      • Return to most recent site set up to handle exception
      • Unnecessary activation records may be deallocated
        • May need to free heap space, other resources
    • Two main language constructs
      • Declaration to establish exception handler
      • Statement or expression to raise or throw exception
    Often used for unusual or exceptional condition; other uses too
  • 9. JavaScript Exceptions
      • throw e //jump to catch, passing exception object as parameter
      • try { … //code to try
      • } catch (e if e == …) { … //catch if first condition true
      • } catch (e if e == …) { … //catch if second condition true
      • } catch (e if e == …) { … //catch if third condition true
      • } catch (e){ … // catch any exception
      • } finally { … //code to execute after everything else
      • }
    http://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/ Exception_Handling_Statements
  • 10. JavaScript Example
      • function invert(matrix) {
      • if … throw “Determinant”;
      • };
      • try { … invert(myMatrix); …
      • }
      • catch (e) { …
      • // recover from error
      • }
  • 11. ML Example (book discusses ML)
      • exception Determinant; (* declare exception name *)
      • fun invert (M) = (* function to invert matrix *)
      • if …
      • then raise Determinant (* exit if Det=0 *)
      • else …
      • end;
      • ...
      • invert (myMatrix) handle Determinant => … ;
    Value for expression if determinant of myMatrix is 0 try catch
  • 12. C++ Example
      • Matrix invert(Matrix m) {
      • if … throw Determinant;
      • };
      • try { … invert(myMatrix); …
      • }
      • catch (Determinant) { …
      • // recover from error
      • }
  • 13. ML Exceptions (cover briefly so book is useful to you)
    • Declaration
      • exception  name  of  type 
        • gives name of exception and type of data passed when raised
    • Raise
      • raise  name   parameters 
        • expression form to raise and exception and pass data
    • Handler
      •  exp1  handle  pattern  =>  exp2 
        • evaluate first expression
        • if exception that matches pattern is raised,
        • then evaluate second expression instead
        • General form allows multiple patterns.
  • 14. C++ vs ML Exceptions
    • C++ exceptions
      • Can throw any type
      • Stroustrup: “I prefer to define types with no other purpose than exception handling. This minimizes confusion about their purpose. In particular, I never use a built-in type, such as int, as an exception.” -- The C++ Programming Language, 3 rd ed.
    • ML exceptions
      • Exceptions are a different kind of entity than types.
      • Declare exceptions before use
      • Similar, but ML requires the recommended C++ style.
  • 15. Which handler is used?
    • Dynamic scoping of handlers
      • First call handles exception one way
      • Second call handles exception another
      • General dynamic scoping rule
        • Jump to most recently established handler on run-time stack
    • Dynamic scoping is not an accident
      • User knows how to handler error
      • Author of library function does not
        • exception Ovflw;
        • fun reciprocal(x) =
        • if x<min then raise Ovflw else 1/x;
        • (reciprocal(x) handle Ovflw=>0) / (reciprocal(y) handle Ovflw=>1);
    try try catch catch throw
  • 16. Exception for Error Condition
      • - datatype ‘a tree = LF of ‘a | ND of (‘a tree)*(‘a tree)
      • - exception No_Subtree;
      • - fun lsub (LF x) = raise No_Subtree
      • | lsub (ND(x,y)) = x;
      • > val lsub = fn : ‘a tree -> ‘a tree
      • This function raises an exception when there is no reasonable value to return
      • We’ll look at typing later.
  • 17. Exception for Efficiency
    • Function to multiply values of tree leaves
      • fun prod(LF x) = x
      • | prod(ND(x,y)) = prod(x) * prod(y);
    • Optimize using exception
      • fun prod(tree) =
      • let exception Zero
      • fun p(LF x) = if x=0 then (raise Zero) else x
      • | p(ND(x,y)) = p(x) * p(y)
      • in
      • p(tree) handle Zero=>0
      • end;
  • 18. Dynamic Scope of Handler
      • exception X;
      • (let fun f(y) = raise X
      • and g(h) = h(1) handle X => 2
      • in
      • g(f) handle X => 4
      • end) handle X => 6;
    Which handler is used? See JavaScript next slide scope handler
  • 19. Dynamic Scope of Handler
      • try{
      • function f(y) { throw “exn”};
      • function g(h){ try {h(1)} catch(e){return 2} };
      • try {
      • g(f)
      • } catch(e){4};
      • } catch(e){6};
    Which catch catches the throw?
  • 20. Dynamic Scope of Handler
      • try{
      • function f(y) { throw “exn”};
      • function g(h){ try {h(1)}
      • catch(e){return 2}
      • };
      • try {
      • g(f)
      • } catch(e){4};
      • } catch(e){6};
    g(f) f(1) Dynamic scope: find first handler, going up the dynamic call chain JavaScript version catch(e) 6 formal h catch(e) 2 access link formal y 1 access link fun f access link access link fun g catch(e) 4 access link
  • 21. Dynamic Scope of Handler
      • exception X;
      • (let fun f(y) = raise X
      • and g(h) = h(1) handle X => 2
      • in
      • g(f) handle X => 4
      • end) handle X => 6;
    g(f) f(1) Dynamic scope: find first X handler, going up the dynamic call chain leading to raise X. Book version (ML) handler X 6 formal h handler X 2 access link formal y 1 access link fun f access link access link fun g handler X 4 access link
  • 22. Compare to static scope of variables
      • exception X;
      • (let fun f(y) = raise X
      • and g(h) = h(1)
      • handle X => 2
      • in
      • g(f) handle X => 4
      • end) handle X => 6;
      • val x=6;
      • (let fun f(y) = x
      • and g(h) = let val x=2 in
      • h(1)
      • in
      • let val x=4 in g(f)
      • end);
    Book version (ML)
  • 23. Compare to static scope of variables
      • try{
      • function f(y) { throw “exn”};
      • function g(h){ try {h(1)}
      • catch(e){return 2}
      • };
      • try {
      • g(f)
      • } catch(e){4};
      • } catch(e){6};
      • var x=6;
      • function f(y) { return x};
      • function g(h){ var x=2;
      • return h(1)
      • };
      • (function (y) {
      • var x=4;
      • g(f)
      • })(0);
    JavaScript version declaration declaration
  • 24. Static Scope of Declarations
      • var x=6;
      • function f(y) { return x};
      • function g(h){
      • var x=2; return h(1) };
      • (function (y) {
      • var x=4; g(f)
      • })(0);
    g(f) f(1) Static scope: find first x, following access links from the reference to X. JavaScript version var x 6 formal h var x 2 access link formal y 1 access link function f access link access link function g var x 4 access link
  • 25. Static Scope of Declarations
      • val x=6;
      • (let fun f(y) = x
      • and g(h) = let val x=2 in
      • h(1)
      • in
      • let val x=4 in g(f)
      • end);
    g(f) f(1) Static scope: find first x, following access links from the reference to X. Book version (ML) val x 6 formal h val x 2 access link formal y 1 access link fun f access link access link fun g val x 4 access link
  • 26. Typing of Exceptions
    • Typing of raise  exn 
      • Recall definition of typing
        • Expression e has type t if normal termination of e
        • produces value of type t
      • Raising exception is not normal termination
        • Example: 1 + raise X
    • Typing of handle  exn  =>  value 
      • Converts exception to normal termination
      • Need type agreement
      • Examples
        • 1 + ((raise X) handle X => e) Type of e must be int
        • 1 + (e 1 handle X => e 2 ) Type of e 1, e 2 must be int
  • 27. Exceptions and Resource Allocation
      • exception X;
      • (let
      • val x = ref [1,2,3]
      • in
      • let
      • val y = ref [4,5,6]
      • in
      • … raise X
      • end
      • end); handle X => ...
    • Resources may be allocated between handler and raise
    • May be “garbage” after exception
    • Examples
      • Memory
      • Lock on database
      • Threads
    General problem: no obvious solution
  • 28. Continuations
    • Idea:
      • The continuation of an expression is “the remaining work to be done after evaluating the expression”
      • Continuation of e is a function normally applied to e
    • General programming technique
      • Capture the continuation at some point in a program
      • Use it later: “jump” or “exit” by function call
    • Useful in
      • Compiler optimization: make control flow explicit
      • Operating system scheduling, multiprogramming
      • Web site design, other applications
  • 29. Example of Continuation Concept
    • Expression
      • 2*x + 3*y + 1/x + 2/y
    • What is continuation of 1/x?
      • Remaining computation after division
      • var before = 2*x + 3*y;
      • function cont(d) {return (before + d + 2/y)};
      • cont (1/x);
    JavaScript version
  • 30. Example of Continuation Concept
    • Expression
      • 2*x + 3*y + 1/x + 2/y
    • What is continuation of 1/x?
      • Remaining computation after division
      • let val before = 2*x + 3*y
      • fun continue(d) = before + d + 2/y
      • in
      • continue (1/x)
      • end
    Book version (ML)
  • 31. Example: Tail Recursive Factorial
    • Standard recursive function
      • fact(n) = if n=0 then 1 else n*fact(n-1)
    • Tail recursive
      • f(n,k) = if n=0 then k else f(n-1, n*k)
      • fact(n) = f(n,1)
    • How could we derive this?
      • Transform to continuation-passing form
      • Optimize continuation functions to single integer
  • 32. Continuation view of factorial
      • fact(n) = if n=0 then 1 else n*fact(n-1)
      • fact(9)
      • fact(8)
      • fact(7)
      • This invocation multiplies by 9 and returns
      • Continuation of fact(8) is  x. 9*x
      • Multiplies by 8 and returns
      • Continuation of fact(7) is
      •  y. (  x. 9*x) (8*y)
      • Multiplies by 7 and returns
      • Continuation of fact(6) is
      •  z. (  y. (  x. 9*x) (8*y)) (7*z)
    return n 9 ... return n 8 ... return n 7 ...
  • 33. Derivation of tail recursive form
    • Standard function
      • fact(n) = if n=0 then 1 else n*fact(n-1)
    • Continuation form
      • fact(n, k) = if n=0 then k(1)
      • else fact(n-1,  x.k ( n*x) )
      • fact(n,  x.x) computes n!
    • Example computation
      • fact(3,  x.x) = fact(2,  y. ( (  x.x) ( 3*y) ) )
      • = fact(1,  x. ( (  y.3*y)(2*x) ) )
      • =  x. ( (  y.3*y)(2*x) ) 1 = 6
    continuation
  • 34. Tail Recursive Form
    • Optimization of continuations
      • fact(n,a) = if n=0 then a
      • else fact(n-1, n*a )
      • Each continuation is effectively  x.(a*x) for some a
    • Example computation
      • fact(3,1) = fact(2, 3) was fact(2,  y.3*y)
      • = fact(1, 6) was fact(1,  x.6*x)
      • = 6
  • 35. Other uses for continuations
    • Explicit control
      • Normal termination -- call continuation
      • Abnormal termination -- do something else
    • Compilation techniques
      • Call to continuation is functional form of “go to”
      • Continuation-passing style makes control flow explicit
    • MacQueen: “Callcc is the closest thing to a
    • ‘ come-from’ statement I’ve ever seen.”
  • 36. Theme Song: Charlie on the MTA
    • Let me tell you the story Of a man named Charlie On a tragic and fateful day He put ten cents in his pocket, Kissed his wife and family Went to ride on the MTA
    • Charlie handed in his dime At the Kendall Square Station And he changed for Jamaica Plain When he got there the conductor told him, &quot;One more nickel.&quot; Charlie could not get off that train.
    • Chorus:                         Did he ever return,                         No he never returned                         And his fate is still unlearn'd                         He may ride forever                         'neath the streets of Boston                         He's the man who never returned.
  • 37. Capturing Current Continuation
    • Language feature (use open SMLofNJ; on Leland)
      • callcc : call a function with current continuation
      • Can be used to abort subcomputation and go on
    • Examples
      • callcc (fn k => 1);
      • > val it = 1 : int
        • Current continuation is “fn x => print x”
        • Continuation is not used in expression
      • 1 + callcc(fn k => 5 + throw k 2);
      • > val it = 3 : int
        • Current continuation is “fn x => print 1+x”
        • Subexpression throw k 2 applies continuation to 2
    skip callcc, at least for now
  • 38. More with callcc
    • Example
      • 1 + callcc(fn k1=> …
      • callcc(fn k2 => …
      • if … then (throw k1 0)
      • else (throw k2 “stuck”)
      • ))
    • Intuition
      • Callcc lets you mark a point in program that you can return to
      • Throw lets you jump to that point and continue from there
  • 39. Example
    • Pass two continuations and choose one
      • fun f(x,k1,k2) = 3 + (if x>0 then throw k1(x)
      • else throw k2(x));
      • fun g(y,k1) = 2 + callcc(fn k2 => f(y,k1,k2));
      • fun h(z) = 1 + callcc(fn k1 => g(z+1,k1));
      • h(1);
      • h(~2);
    Answers: h(1)  3 h(~2)  2
  • 40. Continuations in Mach OS
    • OS kernel schedules multiple threads
      • Each thread may have a separate stack
      • Stack of blocked thread is stored within the kernel
    • Mach “continuation” approach
      • Blocked thread represented as
        • Pointer to a continuation function, list of arguments
        • Stack is discarded when thread blocks
      • Programming implications
        • Sys call such as msg_recv can block
        • Kernel code calls msg_recv with continuation passed as arg
      • Advantage/Disadvantage
        • Saves a lot of space, need to write “continuation” functions
  • 41. “ Continuations” in Web programming
    • XMLHttpRequest similar to callcc:
      • function callcc(url) {
      • var xhr = new XMLHttpRequest();
      • xhr.open('GET', url, false );
      • xhr.send(null);
      • return xhr.responseText;
      • }
    • Usage: alert(callcc('http://a.com/describe?id=10'));
    • Server invokes continuation by sending a response
    • Unfortunately, this pauses client while server runs
  • 42. “ Continuations” in Web programming
    • Asynchronous XHR also similar to continuations:
      • function callWithContinuation(url, k ) {
      • var xhr = new XMLHttpRequest();
      • xhr.open('GET', url, true );
      • xhr.onreadystatechange = function () {
      • if (xhr.readyState == 4)
      • k (xhr.responseText);
      • }
      • xhr.send(null);
      • }
    • Usage: callWithContinuation('http://a.com/describe?id=10', alert);
    • Client continues while server runs
    • Basis of AJAX Web programming paradigm
  • 43. Continuations in compilation
    • SML continuation-based compiler [Appel, Steele]
      • 1) Lexical analysis, parsing, type checking
      • 2) Translation to  -calculus form
      • 3) Conversion to continuation-passing style (CPS)
      • 4) Optimization of CPS
      • 5) Closure conversion – eliminate free variables
      • 6) Elimination of nested scopes
      • 7) Register spilling – no expression with >n free vars
      • 8) Generation of target assembly language program
      • 9) Assembly to produce target-machine program
  • 44. Coroutines (this is complicated…)
      • datatype tree = leaf of int | node of tree*tree;
      • datatype coA = A of (int* coB) cont (* searchA wants int and B-cont*)
      • and coB = B of coA cont; (* searchB wants an A-continuation *)
      • fun resumeA(x, A k) = callcc(fn k' => throw k (x, B k'));
      • fun resumeB( B k) = callcc(fn k' => throw k (A k'));
      • exception DISAGREE; exception DONE;
      • fun searchA(leaf(x),(y, other: coB)) =
      • if x=y then resumeB(other) else raise DISAGREE
      • | searchA(node(t1,t2), other) = searchA(t2, searchA(t1, other));
      • fun searchB(leaf(x), other : coA) = resumeA(x,other)
      • | searchB(node(t1,t2), other) = searchB(t2, searchB(t1, other));
      • fun startB(t: tree) = callcc(fn k => (searchB(t, A k); raise DONE));
      • fun compare(t1,t2) = searchA(t1, startB(t2));
    skip callcc, at least for now
  • 45. Summary
    • Structured Programming
      • Go to considered harmful
    • Exceptions
      • “ structured” jumps that may return a value
      • dynamic scoping of exception handler
    • Continuations
      • Function representing the rest of the program
      • Generalized form of tail recursion
      • Used in Lisp and ML compilation, some OS projects, web application development, …
  • 46. What is a functional language ?
    • “ No side effects”
    • OK, we have side effects, but we also have higher-order functions…
    • We will use pure functional language to mean
    • “ a language with functions, but without side effects
    • or other imperative features.”
  • 47. No-side-effects language test
    • Within the scope of specific declarations of x 1 ,x 2 , …, x n , all occurrences of an expression e containing only variables x 1 ,x 2 , …, x n , must have the same value.
    • Example
      • begin
      • integer x=3; integer y=4;
      • 5*(x+y)-3
      • … // no new declaration of x or y //
      • 4*(x+y)+1
      • end
    ?
  • 48. Example languages
    • Pure Lisp
      • atom, eq, car, cdr, cons, lambda, define
    • Impure Lisp: rplaca, rplacd
      • lambda (x) (cons
      • (car x)
      • (… (rplaca (… x …) ...) ... (car x) … )
      • ))
      • Cannot just evaluate (car x) once
    • Common procedural languages are not functional
      • Pascal, C, Ada, C++, Java, Modula, …
      • Example functional programs in a couple of slides
  • 49. Backus’ Turing Award
    • John Backus was designer of Fortran, BNF, etc.
    • Turing Award in 1977
    • Turing Award Lecture
      • Functional prog better than imperative programming
      • Easier to reason about functional programs
      • More efficient due to parallelism
      • Algebraic laws
        • Reason about programs
        • Optimizing compilers
  • 50. Reasoning about programs
    • To prove a program correct,
      • must consider everything a program depends on
    • In functional programs,
      • dependence on any data structure is explicit
    • Therefore,
      • easier to reason about functional programs
    • Do you believe this?
      • This thesis must be tested in practice
      • Many who prove properties of programs believe this
      • Not many people really prove their code correct
  • 51. Haskell Quicksort
    • Very succinct program
      • qsort [] = []
      • qsort (x:xs) = qsort elts_lt_x ++ [x]
      • ++ qsort elts_greq_x
      • where elts_lt_x = [y | y <- xs, y < x]
      • elts_greq_x = [y | y <- xs, y >= x]
    • This is the whole thing
      • No assignment – just write expression for sorted list
      • No array indices, no pointers, no memory management, …
  • 52. Compare: C quicksort
      • qsort( a, lo, hi ) int a[], hi, lo;
      • { int h, l, p, t;
      • if (lo < hi) {
      • l = lo; h = hi; p = a[hi];
      • do {
      • while ((l < h) && (a[l] <= p)) l = l+1;
      • while ((h > l) && (a[h] >= p)) h = h-1;
      • if (l < h) { t = a[l]; a[l] = a[h]; a[h] = t; }
      • } while (l < h);
      • t = a[l]; a[l] = a[hi]; a[hi] = t;
      • qsort( a, lo, l-1 );
      • qsort( a, l+1, hi );
      • }
      • }
  • 53. Interesting case study
    • Naval Center programming experiment
      • Separate teams worked on separate languages
      • Surprising differences
      • Some programs were incomplete or did not run
      • Many evaluators didn’t understand, when shown the code, that the Haskell program was complete. They thought it was a high level partial specification.
    Hudak and Jones, Haskell vs Ada vs C++ vs Awk vs …, Yale University Tech Report, 1994
  • 54. Disadvantages of Functional Prog
    • Functional programs often less efficient. Why?
    • Change 3rd element of list x to y
      • (cons (car x) (cons (cadr x) (cons y (cdddr x))))
        • Build new cells for first three elements of list
      • (rplaca (cddr x) y)
        • Change contents of third cell of list directly
    • However, many optimizations are possible
    A B C D
  • 55. Von Neumann bottleneck
    • Von Neumann
      • Mathematician responsible for idea of stored program
    • Von Neumann Bottleneck
      • Backus’ term for limitation in CPU-memory transfer
    • Related to sequentiality of imperative languages
      • Code must be executed in specific order
        • function f(x) { if (x<y) then y = x; else x = y; }
        • g( f(i), f(j) );
  • 56. Eliminating VN Bottleneck
    • No side effects
      • Evaluate subexpressions independently
      • Example
        • function f(x) { return x<y ? 1 : 2; }
        • g(f(i), f(j), f(k), … );
    • Does this work in practice? Good idea but ...
      • Too much parallelism
      • Little help in allocation of processors to processes
      • ...
      • David Shaw promised to build the non-Von ...
    • Effective, easy concurrency is a hard problem