Presentation is loading. Please wait.

Presentation is loading. Please wait.

Control in Sequential Languages + some discussion of functional programming John Mitchell CS 242 Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter.

Similar presentations


Presentation on theme: "Control in Sequential Languages + some discussion of functional programming John Mitchell CS 242 Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter."— 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 u{ } groups JavaScript statements Does not provide a separate scope uBlocks 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 uStructured Programming Go to considered harmful uExceptions “structured” jumps that may return a value dynamic scoping of exception handler uContinuations Function representing the rest of the program Generalized form of tail recursion uDiscussion 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 uDijkstra, Go To Statement Considered Harmful Letter to Editor, C ACM, March 1968 Link on CS242 web site uKnuth, Structured Prog. with go to Statements You can use goto, but do so in structured way … uContinued discussion Welch, “GOTO (Considered Harmful) n, n is Odd” uGeneral questions Do syntactic rules force good programming style? Can they help?

7 Advance in Computer Science uStandard constructs that structure jumps if … then … else … end while … do … end for … { … } case … uModern 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 uTerminate 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 uTwo 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 trycatch

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) uDeclaration exception  name  of  type  gives name of exception and type of data passed when raised uRaise raise  name   parameters  expression form to raise and exception and pass data uHandler  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 uC++ 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. uML 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? uDynamic 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 uDynamic 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 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 u Function to multiply values of tree leaves fun prod(LF x) = x | prod(ND(x,y)) = prod(x) * prod(y); uOptimize 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; scope handler Which handler is used? See JavaScript next slide

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}; catch(e)6 formal h catch(e)2 access link formal y1 access link g(f) f(1) fun f access link fun g Dynamic scope: find first handler, going up the dynamic call chain catch(e)4 access link JavaScript version

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; handler X6 formal h handler X2 access link formal y1 access link g(f) f(1) fun f access link fun g Dynamic scope: find first X handler, going up the dynamic call chain leading to raise X. handler X4 access link Book version (ML)

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

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); var x6 formal h var x2 access link formal y1 access link g(f) f(1) function f access link function g Static scope: find first x, following access links from the reference to X. var x4 access link JavaScript version

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); val x6 formal h val x2 access link formal y1 access link g(f) f(1) fun f access link fun g Static scope: find first x, following access links from the reference to X. val x4 access link Book version (ML)

26 Typing of Exceptions uTyping 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 uTyping 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 =>... uResources may be allocated between handler and raise uMay be “garbage” after exception uExamples Memory Lock on database Threads … General problem: no obvious solution

28 Continuations uIdea: 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 uGeneral programming technique Capture the continuation at some point in a program Use it later: “jump” or “exit” by function call uUseful in Compiler optimization: make control flow explicit Operating system scheduling, multiprogramming Web site design, other applications

29 Example of Continuation Concept uExpression 2*x + 3*y + 1/x + 2/y uWhat 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 uExpression 2*x + 3*y + 1/x + 2/y uWhat 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 uStandard recursive function fact(n) = if n=0 then 1 else n*fact(n-1) uTail recursive f(n,k) = if n=0 then k else f(n-1, n*k) fact(n) = f(n,1) uHow 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 n9... return n8... return n7...

33 Derivation of tail recursive form uStandard function fact(n) = if n=0 then 1 else n*fact(n-1) uContinuation form fact(n, k) = if n=0 then k(1) else fact(n-1, x.k ( n*x) ) fact(n, x.x) computes n! uExample 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 uOptimization 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 uExample 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 uExplicit control Normal termination -- call continuation Abnormal termination -- do something else uCompilation 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 uLet 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 uCharlie handed in his dime At the Kendall Square Station And he changed for Jamaica Plain When he got there the conductor told him, "One more nickel." Charlie could not get off that train. uChorus: 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 uLanguage feature (use open SMLofNJ; on Leland) callcc : call a function with current continuation Can be used to abort subcomputation and go on uExamples 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 uExample 1 + callcc(fn k1=> … callcc(fn k2 => … if … then (throw k1 0) else (throw k2 “stuck”) )) uIntuition 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 u 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 uOS kernel schedules multiple threads Each thread may have a separate stack Stack of blocked thread is stored within the kernel uMach “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 uXMLHttpRequest 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')); uServer invokes continuation by sending a response uUnfortunately, this pauses client while server runs

42 “Continuations” in Web programming uAsynchronous 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); uClient continues while server runs uBasis of AJAX Web programming paradigm

43 Continuations in compilation uSML 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 uStructured Programming Go to considered harmful uExceptions “structured” jumps that may return a value dynamic scoping of exception handler uContinuations 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 ? u“No side effects” uOK, 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. uExample 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 uPure Lisp atom, eq, car, cdr, cons, lambda, define uImpure Lisp: rplaca, rplacd lambda (x) (cons (car x) (… (rplaca (… x …)...)... (car x) … ) )) Cannot just evaluate (car x) once uCommon procedural languages are not functional Pascal, C, Ada, C++, Java, Modula, … Example functional programs in a couple of slides

49 Backus’ Turing Award uJohn Backus was designer of Fortran, BNF, etc. uTuring Award in 1977 uTuring 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 uTo prove a program correct, must consider everything a program depends on uIn functional programs, dependence on any data structure is explicit uTherefore, easier to reason about functional programs uDo 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 uVery 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 = x] uThis 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 uNaval 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 ABCD

55 Von Neumann bottleneck uVon Neumann Mathematician responsible for idea of stored program uVon Neumann Bottleneck Backus’ term for limitation in CPU-memory transfer uRelated 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 uNo side effects Evaluate subexpressions independently Example –function f(x) { return x<y ? 1 : 2; } –g(f(i), f(j), f(k), … ); uDoes 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... uEffective, easy concurrency is a hard problem


Download ppt "Control in Sequential Languages + some discussion of functional programming John Mitchell CS 242 Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter."

Similar presentations


Ads by Google