Control in Sequential Languages Mooly Sagiv Original slides by John Mitchell Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter 3, Sections 3.3, 3.4.2,

Slides:



Advertisements
Similar presentations
Intermediate Code Generation
Advertisements

Compilation 2011 Static Analysis Johnni Winther Michael I. Schwartzbach Aarhus University.
Control Structures Any mechanism that departs from straight-line execution: –Selection: if-statements –Multiway-selection: case statements –Unbounded iteration:
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 7: User-Defined Functions II.
CSE 332: C++ exceptions Overview of C++ Exceptions Normal program control flow is halted –At the point where an exception is thrown The program call stack.
1 Lecture 11 Interfaces and Exception Handling from Chapters 9 and 10.
Implementing Subprograms
(1) ICS 313: Programming Language Theory Chapter 10: Implementing Subprograms.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 18.
Chapter 8 Runtime Support. How program structures are implemented in a computer memory? The evolution of programming language design has led to the creation.
Chapter 9 Subprogram Control Consider program as a tree- –Each parent calls (transfers control to) child –Parent resumes when child completes –Copy rule.
1 Languages and Compilers (SProg og Oversættere) Sequence control and Subprogram Control.
Exceptions in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Control in Sequential Languages John Mitchell CS 242.
Misc. Announcements Assignment available end of the day today –Due back in 11/03 (after break) Will also update slides on website –Today Midterm next week.
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy1 Declarative Computation Model Kernel language semantics Carlos Varela RPI Adapted with permission.
Control in Sequential Languages Today’s Slides are from John Mitchell’s Stanford University CS 232 Course.
Run time vs. Compile time
Catriel Beeri Pls/Winter 2004/5 environment 68  Some details of implementation As part of / extension of type-checking: Each declaration d(x) associated.
The environment of the computation Declarations introduce names that denote entities. At execution-time, entities are bound to values or to locations:
Compiler Summary Mooly Sagiv html://
Chapter 9: Subprogram Control
1 Run time vs. Compile time The compiler must generate code to handle issues that arise at run time Representation of various data types Procedure linkage.
7/2/20151 Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC Based in part on slides by Mattox.
Slide 1 Vitaly Shmatikov CS 345 Scope and Activation Records.
Chapter TwelveModern Programming Languages1 Memory Locations For Variables.
Chapter 7: Runtime Environment –Run time memory organization. We need to use memory to store: –code –static data (global variables) –dynamic data objects.
Control in Sequential Languages + some discussion of functional programming John Mitchell CS 242 Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter.
1 Names, Scopes and Bindings Aaron Bloomfield CS 415 Fall
10/14/20151 Programming Languages and Compilers (CS 421) Grigore Rosu 2110 SC, UIUC Slides by Elsa Gunter, based.
10/16/2015IT 3271 All about binding n Variables are bound (dynamically) to values n values must be stored somewhere in the memory. Memory Locations for.
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Chapter Twenty-ThreeModern Programming Languages1 Formal Semantics.
Slide 1 Vitaly Shmatikov CS 345 Imperative Programming.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
Implementing Subprograms What actions must take place when subprograms are called and when they terminate? –calling a subprogram has several associated.
CSE 425: Control Abstraction I Functions vs. Procedures It is useful to differentiate functions vs. procedures –Procedures have side effects but usually.
1 Languages and Compilers (SProg og Oversættere) Bent Thomsen Department of Computer Science Aalborg University With acknowledgement to John Mitchell and.
CSE 332: C++ Statements C++ Statements In C++ statements are basic units of execution –Each ends with ; (can use expressions to compute values) –Statements.
Slide 1 WEEK 8 Imperative Programming Original by Vitaly Shmatikov.
Exception Handling in Java Topics: Introduction Errors and Error handling Exceptions Types of Exceptions Coding Exceptions Summary.
CS212: Object Oriented Analysis and Design Lecture 19: Exception Handling.
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
RUNTIME ENVIRONMENT AND VARIABLE BINDINGS How to manage local variables.
Implementing Subprograms
CMSC 202 Computer Science II for Majors. CMSC 202UMBC Topics Exceptions Exception handling.
Slide 1 Vitaly Shmatikov CS 345 Exceptions. slide 2 Reading Assignment uMitchell, Chapter 8.2.
Procedure Definitions and Semantics Procedures support control abstraction in programming languages. In most programming languages, a procedure is defined.
Scope, Function Calls and Storage Management John Mitchell CS Reading: Chapter 7, Concepts in Programming Languages.
CSE 332: C++ Exceptions Motivation for C++ Exceptions Void Number:: operator/= (const double denom) { if (denom == 0.0) { // what to do here? } m_value.
Chapter 14 Functions.
Control in Sequential Languages
Run-Time Environments Chapter 7
Why exception handling in C++?
Programming Languages and Compilers (CS 421)
Memory Locations For Variables
User-Defined Functions
Chapter 9 :: Subroutines and Control Abstraction
Programming Languages and Compilers (CS 421)
Closure Representations in Higher-Order Programming Languages
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Autumn 2018.
Chapter 7: User-Defined Functions II
UNIT V Run Time Environments.
Madhusudan Parthasarathy
Languages and Compilers (SProg og Oversættere)
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Zach Tatlock Winter 2018.
Scope, Function Calls and Storage Management
Recursive Procedures and Scopes
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Spring 2019.
CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion Dan Grossman Autumn 2017.
Presentation transcript:

Control in Sequential Languages Mooly Sagiv Original slides by John Mitchell Reading: Chapter 8, Sections 8.1 – 8.3 (only) Chapter 3, Sections 3.3, 3.4.2, 3.4.3, 3.4.5, (only)

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

Fortran Control Structure 10 IF (X.GT ) GO TO X = -X IF (X.LT ) GO TO IF (X*Y.LT ) GO TO 30 X = X-Y-Y 30 X = X+Y CONTINUE X = A Y = B-A GO TO 11 … Similar structure may occur in assembly code

Non-Local goto in C syntax 4

Non-local gotos in C setjmp remembers the current location and the stack frame longjmp jumps to the current location (popping many activation records) 5

Non-Local Transfer of Control in C 6

Historical Debate Dijkstra, Go To Statement Considered Harmful – Letter to Editor, C ACM, March 1968 Knuth, Structured Prog. with go to Statements – You can use goto, but please 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?

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

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 – Establish exception handler to catch exception – Statement or expression to raise or throw exception Often used for unusual or exceptional condition; other uses too

JavaScript Exceptions throw e //jump to catch, passing exception object 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 }

JavaScript Example function invert(matrix) { if … throw “Determinant”; … }; try { … invert(myMatrix); … } catch (e) { … // recover from error }

C++ Example Matrix invert(Matrix m) { if … throw Determinant; … }; try { … invert(myMatrix); … } catch (Determinant) { … // recover from error }

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.

ML determinant example 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

Using Pattern Matching exception Signal of int; fun f(x) = if x =0 then raise Signal(0) else if x =1 then raise Signal(1) else if x>10 then raise Signal(x-8) else (x-2) mod 4 f(10) = handle Signal(0) => 0 | Signal(1) => 1 | Signal(x) => x+8;

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

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;

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){return 4}; } catch(e){return 6}; Which catch catches the throw? JavaScript version scope handler

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? Book version (ML)

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){return 4}; } catch(e){return 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

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)

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

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)

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

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)

Where is an exception caught? Dynamic scoping of handlers – Throw to most recent catch on run-time stack – Recall: stacks and activation records Which activation record link is used? – Access link? Control link? Dynamic scoping is not an accident – User knows how to handler error – Author of library function does not

ML Typing of Exceptions Typing of raise  exn  – Definition of ML 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

Exceptions and Resource Allocation exception X (let y = ref [1, 2, 3] in … raise X … end) handle X => … ;

Exceptions and Resource Allocation Resources may be allocated inside try block May be “garbage” after exception Examples – Memory (problem in C/C++) – Lock on database – Threads – … General problem: no obvious solution

Detour Denotational Semantics We try: – S .  : Stm  (      ) S  skip   =  S  s 0 ; s 1   = S  s 1  (S  s 0   ) S  if b then s 0 else s 1   = if B  b   then S  s 0   else S  s 1   S  l : s 0   = S  goto l   =

Detour Denotational Semantics if x = 0 then goto zero // c1 res = y / x // c2 goto end // c3 zero: res = 0 // c4 end: skip // c5 continue(c1, true) = [c4 ; c5] continue(c1, false) = [c2 ; c3 ; c5] continue(c2) = [c3 ; c5] continue(c3) = [c5] continue(c4) = [c5]

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 – Denotational Semantics – Compiler optimization: make control flow explicit – Operating system scheduling, multiprogramming – Web site design, other applications

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

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)

Using Continuations for Error Handling Book version (ML) fun divide (numerator, denominator, normal_cont, error_con) = if denominator > then normal_cont(numerator/denominator) else error_cont() fun f(x, y) let val before = 2.0 *x *y fun continue(quote) = before + quote + 2.0/y fun error_continu() = before/5.2 in divide(1.0, x, continue, error_continu) end

Using Exceptions for Error Handling Book version (ML) Exception Div; fun f(x, y) (2.0 *x *y + 1/ if x > then x else raise Div) / y ) handle Div => (2.0 *x *y)/ 5.2

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 (automatic) – Optimize continuation function to single integer

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... continuation fact(n-1) = continuation fact(n)  x. n*x

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

Tail Recursive Form Optimization of continuations fact(n, k) = if n=0 then k(1) else fact(n-1, x.k ( n*x) )  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

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.”

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

Continuations in Web programming Use continuation-passing style to allow multiple returns function doXHR(url, succeed, fail) { var xhr = new XMLHttpRequest(); // or ActiveX equivalent xhr.open("GET", url, true); xhr.send(null); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) succeed(xhr.responseText); else fail(xhr); } }; } See

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

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, "One more nickel." 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.

Missing Garbage collection Haskel exceptions

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/Scheme compilation, some OS projects, web application development, …