LECTURE 18. Control Flow

Similar documents
COP4020 Programming Languages. Control Flow Prof. Robert van Engelen

Principles of Programming Languages

CSc 520 Principles of Programming Languages. 26 : Control Structures Introduction

Lecture 15: Iteration and Recursion

CPSC 3740 Programming Languages University of Lethbridge. Control Structures

G Programming Languages - Fall 2012

Control Structures. Outline. In Text: Chapter 8. Control structures Selection. Iteration. Gotos Guarded statements. One-way Two-way Multi-way

Page # Expression Evaluation: Outline. CSCI: 4500/6500 Programming Languages. Expression Evaluation: Precedence

Control Flow. Stephen A. Edwards. Fall Columbia University

! Non-determinacy (unspecified order) Maria Hybinette, UGA 2. 1 Landin adding sugar to a language to make it easier to read (for humans)

Ordering Within Expressions. Control Flow. Side-effects. Side-effects. Order of Evaluation. Misbehaving Floating-Point Numbers.

Control Flow COMS W4115. Prof. Stephen A. Edwards Fall 2006 Columbia University Department of Computer Science

Statement level control structures

Chapter 7. - FORTRAN I control statements were based directly on IBM 704 hardware

int foo() { x += 5; return x; } int a = foo() + x + foo(); Side-effects GCC sets a=25. int x = 0; int foo() { x += 5; return x; }

Ch. 7: Control Structures

Flow Control. CSC215 Lecture

Programming Languages Third Edition. Chapter 9 Control I Expressions and Statements

LECTURE 17. Expressions and Assignment

Chapter 6 Control Flow. June 9, 2015

Chapter 8 Statement-Level Control Structures

2/20/2018. Chapter 6:: Control Flow. control flow or ordering. basic categories for control flow (cont.): basic categories for control flow:

CS 330 Lecture 18. Symbol table. C scope rules. Declarations. Chapter 5 Louden Outline

General Concepts. Abstraction Computational Paradigms Implementation Application Domains Influence on Success Influences on Design

Concepts Introduced in Chapter 7

Introduction to Programming Using Java (98-388)

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Programming Languages, Summary CSC419; Odelia Schwartz

NOTE: Answer ANY FOUR of the following 6 sections:

Chapter 8. Statement-Level Control Structures

MIDTERM EXAMINATION - CS130 - Spring 2003

Iterative Statements. Iterative Statements: Examples. Counter-Controlled Loops. ICOM 4036 Programming Languages Statement-Level Control Structure

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Chapter 8. Statement-Level Control Structures

CSE 452: Programming Languages. Outline of Today s Lecture. Expressions. Expressions and Control Flow

SE352b: Roadmap. SE352b Software Engineering Design Tools. W3: Programming Paradigms

301AA - Advanced Programming

Lecture 9: Parameter Passing, Generics and Polymorphism, Exceptions

Programming Language Pragmatics

Introduction. A. Bellaachia Page: 1

Lecture 9: Control Flow

Chapter 8. Statement-Level Control Structures

The SPL Programming Language Reference Manual

COP4020 Fall 2006 Final Exam


St. MARTIN S ENGINEERING COLLEGE Dhulapally, Secunderabad

Expressions and Statements. Department of CSE, MIT, Manipal

Topic IV. Block-structured procedural languages Algol and Pascal. References:

Functional Programming. Big Picture. Design of Programming Languages

Control Flow. CSE 307 Principles of Programming Languages Stony Brook University

G Programming Languages - Fall 2012

CSC 533: Organization of Programming Languages. Spring 2005

Chapter 8. Statement-Level Control Structures ISBN

Continuations provide a novel way to suspend and reexecute

Topic IV. Parameters. Chapter 5 of Programming languages: Concepts & constructs by R. Sethi (2ND EDITION). Addison-Wesley, 1996.

LECTURE 14. Names, Scopes, and Bindings: Scopes

G Programming Languages - Fall 2012

Attributes of Variable. Lecture 13: Run-Time Storage Management. Lifetime. Value & Location

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

CS323 Lecture: Control Structures last revised 3/4/09

Formal Specification and Verification

Expressions vs statements

UNIT 3

TYPES, VALUES AND DECLARATIONS

Chapter 7 Control I Expressions and Statements

1 Lexical Considerations

LECTURE 1. Overview and History

Software Engineering using Formal Methods

Chapter 5. Names, Bindings, and Scopes

Names, Bindings, Scopes

CSE 307: Principles of Programming Languages

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

MIDTERM EXAM (Solutions)

CS 314 Principles of Programming Languages

Special Topics: Programming Languages

Imperative Programming Languages (IPL)

Homework. Reading: Chapter 17 Homework: All exercises from Chapter 17 Due: 10/27 Correction: Chapter 16 homework is due 10/25

Java Programming: Guided Learning with Early Objects Chapter 5 Control Structures II: Repetition

Expressions and Assignment

Why are there so many programming languages? Why do we have programming languages? What is a language for? What makes a language successful?

Chapter 7:: Data Types. Mid-Term Test. Mid-Term Test (cont.) Administrative Notes

The PCAT Programming Language Reference Manual

Structure of Programming Languages Lecture 5

INF 212 ANALYSIS OF PROG. LANGS ELEMENTS OF IMPERATIVE PROGRAMMING STYLE. Instructors: Crista Lopes Copyright Instructors.

Introduction to C/C++ Lecture 3 - Program Flow Control

Question No: 1 ( Marks: 1 ) - Please choose one One difference LISP and PROLOG is. AI Puzzle Game All f the given

Software Engineering using Formal Methods

Flow of Control Execution Sequence

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University


Com S 541. Programming Languages I

Organization of Programming Languages CS3200 / 5200N. Lecture 06

C-LANGUAGE CURRICULAM

Answer: Early binding generally leads to greater efficiency (compilation approach) Late binding general leads to greater flexibility

Control Structures. Lecture 4 COP 3014 Fall September 18, 2017

CSCI312 Principles of Programming Languages!

A Tour of Language Implementation

An Activation Record for Simple Subprograms. Activation Record for a Language with Stack-Dynamic Local Variables

Control Abstraction. Hwansoo Han

Transcription:

LECTURE 18 Control Flow

CONTROL FLOW Sequencing: the execution of statements and evaluation of expressions is usually in the order in which they appear in a program text. Selection (or alternation): a run-time condition determines the choice among two or more statements or expressions. Iteration: a statement is repeated a number of times or until a run-time condition is met. Procedural abstraction: subroutines encapsulate collections of statements and subroutine calls can be treated as single statements. Recursion: subroutines which call themselves directly or indirectly to solve a problem, where the problem is typically defined in terms of simpler versions of itself. Concurrency: two or more program fragments executed in parallel, either on separate processors or interleaved on a single processor. Non-determinacy: the execution order among alternative constructs is deliberately left unspecified, indicating that any alternative will lead to a correct result.

STRUCTURED AND UNSTRUCTURED FLOW Unstructured Control Flow: the use of goto statements and statement labels to implement control flow. Featured in early versions of Fortran, Cobol, and PL/I. Supported by most early Algol-family languages. Generally considered bad. Most can be replaced with structures with some exceptions. Java, Clu, Eiffel, and Modula have no goto statement. Ada, C#, Fortran90, and C++ only allow gotos in a limited context or to maintain compatibility.

STRUCTURED AND UNSTRUCTURED FLOW Structured Control Flow Statement Sequencing. Selection with if-then-else statements and switch statements. Iteration with for and while loop statements. Subroutine calls (including recursion). All of which promotes structured programming. Mostly pioneered by Algol 60.

STRUCTURED AND UNSTRUCTURED FLOW The trend of moving from unstructured to structured flow relied on the ability to find structured solutions to these common uses of goto. Mid-loop exit and continuation: replaced with one-and-a-half loop constructs, and keywords like break and continue. Early returns from subroutines: most languages now allow an early return rather than explicit goto. Multi-level returns: nonlocal gotos replaced by return-from in Lisp, catch and throw blocks. Exceptions: strongly related to multi-level returns. Also replaced by catch/throw blocks.

SEQUENCING Principle means of controlling execution order in imperative programming (which relies on side-effects for state changes). A list of statements in a program text is executed in top-down order. A compound statement is a delimited list of statements. A compound statement is called a block when preceded by declarations. C, C++, and Java use { and } to delimit a block. Pascal and Modula use begin... end. Ada uses declare... begin... end.

SELECTION Implemented as some variant of an if then else structure, as introduced by Algol 60. If-else selection statements in C and C++ if (<expr>) <stmt> [else if (<expr>) <stmt>] [else <stmt>] Condition is a bool, integer, or pointer. Grouping with { and } is required for statement sequences. Syntax ambiguity is resolved with an else matches the closest if rule. Conditional expressions, e.g. if and cond in Lisp and a?b:c in C. Java syntax is like C/C++, but condition must be Boolean.

SELECTION Case/switch statements allow an expression to be tested against multiple constants to select statement(s) in one of the arms of the case statement: In C, C++, and Java: switch (<expr>) { case <const>: <statements> break; case <const>: <statements> break;... default: <statements> } A break is necessary to transfer control at the end of an arm to the end of the switch statement. Most programming languages support a switch-like statement, but do not require the use of a break in each arm. A switch statement can be much more efficient compared to nested if-then-else statements.

ITERATION Enumeration-controlled loops repeat a collection of statements a number of times, where in each iteration a loop index variable takes the next value of a set of values specified at the beginning of the loop. Logically-controlled loops repeat a collection of statements until some Boolean condition changes value in the loop. Pretest loops test condition at the beginning of each iteration. while loop in C/C++ Posttest loops test condition at the end of each iteration. do-while loop in C/C++ Midtest loops allow structured exits from within loop with exit conditions. for ( ) { ; if ( ) break; } in C/C++

ENUMERATION-CONTROLLED LOOPS Fortran-IV: DO 20 i = 1, 10, 2... 20 CONTINUE which is defined to be equivalent to i = 1 20... i = i + 2 if i <= 10 goto 20 Problems: - Requires positive constant loop bounds (1 and 10) and step size (2). - If loop index variable i is modified in the loop body, the number of iterations is changed compared to the iterations set by the loop bounds. - gotos can jump out of the loop and also from outside into the loop. - The value of counter i after the loop is implementation dependent. - The body of the loop will be executed at least once (no empty bounds).

ENUMERATION-CONTROLLED LOOPS Algol-60 combines logical conditions in combination loops: for <id> := <forlist> do <stmt> where the syntax of <forlist> is <forlist> <enumerator> [, enumerator]* <enumerator> <expr> <expr> step <expr> until <expr> <expr> while <cond> Many forms that behave the same: for i := 1, 3, 5, 7, 9 do... for i := 1 step 2 until 10 do... for i := 1, i+2 while i < 10 do...

ENUMERATION-CONTROLLED LOOPS C, C++, and Java do not have true enumeration-controlled loops. A for loop is essentially a logically-controlled loop: for (i = 1; i <= n; i++)... which iterates i from 1 to n by testing i <= n before the start of each iteration and updating i by 1 in each iteration. Why is this not enumeration controlled? Assignments to counter i and variables in the bounds are allowed, thus it is the programmer's responsibility to structure the loop to mimic enumeration loops. Use continue to jump to next iteration. Use break to exit loop C++ and Java also support local scoping for counter variable.

ENUMERATION-CONTROLLED LOOPS Other problems with C/C++ for loops emulating enumeration-controlled loops are related to the mishandling of bounds and limits of value representations. This C program never terminates (do you see why?) #include <limits.h> // INT_MAX is max int value int main() { int i; for (i = 0; i <= INT_MAX; i++) printf( Iteration %d\n, i); } This C program does not count from 0.0 to 10.0, why? int main() { float n; for (n = 0.0; n <= 10; n += 0.01) printf( Iteration %g\n, n); }

ITERATORS Iterators are used to iterate over elements of containers such as sets and data structures such as lists and trees. Iterator objects are also called enumerators or generators. C++ iterators are associated with a container object and used in loops similar to pointers and pointer arithmetic: vector<int> V; for (vector<int>::iterator it = V.begin(); it!= V.end(); ++it) // access element of vector

ITERATORS IN FUNCTIONAL LANGUAGES Iterators typically need special loops to produce elements one by one, e.g. in Clu: for i in int$from_to_by(first, last, step) do end While Java and C++ use iterator objects that hold the state of the iterator, Clu, Python, Ruby, and C# use generators ( true iterators ) which are functions that run in parallel to the loop code to produce elements. Without side effects, all intermediate states must be maintained to generate the elements in each iteration.

LOGICALLY-CONTROLLED PRETEST LOOPS Logically-controlled pretest loops check the exit condition before the next loop iteration. Not available in Fortran-77. Ada has only one kind of logically-controlled loops: midtest loops. Pascal: while <cond> do <stmt> where the condition is a Boolean-typed expression. C, C++: while (<expr>) <stmt> where the loop terminates when the condition expression evaluates to 0, NULL, or false. Use continue and break to jump to next iteration or exit the loop. Java is similar C++, but condition is restricted to Boolean.

LOGICALLY-CONTROLLED POSTTEST LOOPS Logically-controlled posttest loops check the exit condition after each loop iteration. Pascal: repeat <stmt> [; <stmt>]* until <cond> where the condition is a Boolean-typed expression and the loop terminates when the condition is true. C, C++: do <stmt> while (<expr>) where the loop terminates when the condition expression evaluates to 0, NULL, or false.

LOGICALLY-CONTROLLED MIDTEST LOOPS Ada supports logically-controlled midtest loops which check exit conditions anywhere: loop <statements> exit when <cond>; <statements> exit when <cond>;... end loop Ada also supports labels, allowing exit of outer loops without gotos: outer: loop... for i in 1..n loop... exit outer when a[i]>0;... end loop; end outer loop;

RECURSION Recursion: subroutines that call themselves directly or indirectly (mutual recursion). Typically used to solve a problem that is defined in terms of simpler versions. For example, to compute the length of a list, remove the first element, calculate the length of the remaining list as n, and return n+1. If the list is empty, return 0. Iteration and recursion are equally powerful in theoretical sense. Iteration can be expressed by recursion and vice versa. Recursion is more elegant to use to solve a problem that is naturally recursively defined, such as a tree traversal algorithm. Recursion can be less efficient, but most compilers for functional languages are often able to replace it with iterations.

TAIL-RECURSIVE FUNCTIONS Tail-recursive functions are functions in which no operations follow the recursive call(s) in the function, thus the function returns immediately after the recursive call: Tail-Recursive Not Tail-Recursive int trfun() int rfun() { { return trfun(); return rfun()+1; } } A tail-recursive call could reuse the subroutine's frame on the run-time stack, since the current subroutine state is no longer needed. Simply eliminating the push (and pop) of the next frame will do. In addition, we can do more for tail-recursion optimization: the compiler replaces tail-recursive calls by jumps to the beginning of the function.

TAIL-RECURSIVE FUNCTION Consider the GCD function: Can be optimized as: Which is just as efficient as the iterative version: int gcd(int a, int b){ if (a==b) return a; else if (a>b) return gcd(a-b, b); else return gcd(a, b-a); } int gcd(int a, int b){ start: if (a==b) return a; else if (a>b) { a = a-b; goto start; } else { b = b-a; goto start; } } int gcd(int a, int b){ while (a!=b) if (a>b) a = a-b; else b = b-a; return a; }

WHEN RECURSION IS INEFFICIENT The Fibonacci function implemented as a recursive function is very inefficient as it takes exponential time to compute: int fib(n) { if (n=1) return 1; if (n=2) return 1; return fib(n-1) + fib(n-2); }