* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download My Python-oriented slides
Survey
Document related concepts
Scala (programming language) wikipedia , lookup
Name mangling wikipedia , lookup
Go (programming language) wikipedia , lookup
Java performance wikipedia , lookup
Structured programming wikipedia , lookup
Object-oriented programming wikipedia , lookup
Reactive programming wikipedia , lookup
Functional programming wikipedia , lookup
One-pass compiler wikipedia , lookup
C Sharp syntax wikipedia , lookup
Recursion (computer science) wikipedia , lookup
Standard ML wikipedia , lookup
Transcript
CSC 310 – Theory of Programming Languages, Spring, 2009 Chapter 6: Control Flow Control flow = sequence of execution of instructions / data access • Sequence – use order of appearance or precedence. • Selection – alternation and short-circuited evaluation • Iteration – Repetition determined at compile time (loop control constants) or run time (variables). • Procedural abstraction, a.k.a. functions or methods. • Recursion – tail calls, direct & indirect recursion. • Concurrency – multithreading and distributed procedures. • Nondeterminacy – partially ordered sequences. Operator precedence and associativity • Precedence and associativity in algebraic expressions determines order of evaluation, and therefore instruction sequence. • • • • • • >>> 3 + 4 ** 2 * 5 83 >>> (3 + 4) ** (2 * 5) 282475249 >>> (3 + 4) ** 2 * 5 245 • Parent-child node relationships in a syntax tree can reflect precedence and associativity. Assignments, Values and References • An l-value corresponds to a symbol appearing in the left-hand-side of an assignment. An l-value is a reference for the target of the assignment. • An r-value corresponds to a symbol appearing in the right-hand-side of an assignment or expression. An rvalue is a value of the symbol binding. • Syntax for the two may be identical or different. • d=a; • a=b+c Value versus reference model. • In a value model language, every data object is a value. Value semantics typically apply to primitive data types, e.g., ints and floats in C/C++ and Java. • A reference model implicitly treats every variable binding as a pointer. Java uses a reference model for class objects. Python uses a reference model for all data objects. • Because C/C++ uses a value model, pointers are treated as explicit pointer values. The distinction between an object and a pointer to an object leads to added syntax and programming complexity, the benefit being efficiency in avoiding unnecessary pointer dereferencing and heap-based object allocation and recovery. • C++ has also added reference variables and parameters to the value model of C. Boxing • Compiler automatically places a primitive datum into an object when needed. • Old Java. • void f(char key, int value, java.util.Map map) – map.put(new Character(char), new Integer(value)) • Newer Java. • void f(char key, int value, java.util.Map map) – map.put(char, value) Short circuited and lazy evaluation • condition1 or condition2 or condition3 • Stop evaluation on the first true result. • Python equates 0 with False, non-0 with True. – >>> 0 or 0 or 7 or 5 –7 • condition1 and condition2 and condition3 • Stop evaluation on the first false result. – – – – >>> 1 and 5 and 7 and 9 9 >>> 1 and 5 and 0 and 9 0 Short circuiting for safety • Short circuiting supports writing safe conditional tests. • • • • • • • • • • >>> mylist = [1, 2, 3, 4, 5] >>> i = 17 >>> if (i < len(mylist) and mylist[i] <= 3): ... print mylist[i] ... >>> i = 2 >>> if (i < len(mylist) and mylist[i] <= 3): ... print mylist[i] ... 3 Alternation (selection) is short circuited in programming languages. • In an if-else construct, code in the branch not taken is never evaluated. • The code in the branch not taken can include value errors (divide by 0, invalid array indices, etc.), and in Python, invalid types. – – – – – – – – – – – – – – >>> i = 3 >>> if (type(i) == int): ... print i + 7 ... else: ... print str(i) + " stringy" ... 10 >>> i = 'a string' >>> if (type(i) == int): ... print i + 7 ... else: ... print str(i) + " stringy" ... a string stringy • Boolean expression short circuiting is a similar case. • Switch / case statements select 1 alternative from many, compile into jump tables for contiguous cases. Normal order (lazy) evaluation generalizes this approach. • Evaluate expressions only if / when you need them, and in a functional language, evaluate them only once. Applicative evaluation evaluates expressions and parameters immediately. • • • • • • • • • fun returndiv(quotient, divisor) = if divisor <> 0 then quotient else ~1000 ; (* Like a C conditional statement. *) returndiv(8 div 2, 2); returndiv(8 div 0, 0); // applicative evaluation in ML -bash-3.00$ sml mldemo.sml val it = 4 : int uncaught exception Div [divide by zero] raised at: mldemo.sml:113.13-113.16 Normal-order evaluation in Haskell • returndiv quotient divisor • = if (divisor /= 0) then quotient else -1000 • -- returndiv (div 8 2) 2 • -- returndiv (div 8 0) 0 • Main> returndiv (div 8 2) 2 • 4 • Main> returndiv (div 8 0) 0 • -1000 Normal order is a generalization of the short-circuited boolean tests and alternation constructs in other languages. Iteration • While and for loops test at the top. • For loops build loop control variables into the syntax. • >>> for x in range(1,5): sys.stdout.write(str(x) + " ") • ... • 1 2 3 4 >>> • Until loops run the loop once and test at the bottom. • Selection and iteration compile to jumps and conditional jumps in machine code. Recursion • Direct recursion -- a function invokes itself. • Indirect recursion – a function invokes another function that, directly or indirectly, invokes the first function. • Tail recursion – a direct recursive call that returns immediately. • The compiler can compile tail calls to jumps back to the start of the function after re-binding the parameters. • Optimizing tail calls is important in functional languages that discourage or disallow iteration and re-assignment of variable- value bindings. • • • • • • • • • >>> def sum(l, cursum=0): ... if (len(l)): ... tmpsum = cursum + l[0] ... return sum(l[1:], tmpsum) ... else: ... return cursum ... >>> sum([1, 2, 3, 4, 5]) 15 Continuations support coroutines – multiple activation stacks • (define buffer '()) ;the shared resource • • • • • • • • (define producer (lambda (consumer-continuation count) (set! buffer (list "tuna sandwich #" count)) (display "producer making ") (display buffer) (newline) (sleep 1) ;slowing things down a bit (producer (call/cc consumer-continuation) (+ count 1)))) • • • • • • • • (define consumer (lambda (producer-continuation) (display "consumer eating ") (display buffer) (newline) (set! buffer '()) ;accessing the shared resource (sleep 1) ;slowing things down a bit (consumer (call/cc producer-continuation)))) • ;(trace producer consumer) • (producer consumer 0) ;getting the ball rolling • • • • • • producer making (tuna sandwich # 0) consumer eating (tuna sandwich # 0) producer making (tuna sandwich # 1) consumer eating (tuna sandwich # 1) producer making (tuna sandwich # 2) consumer eating (tuna sandwich # 2) • Code by Liz Kalter, CSC 580