IA010: Principles of Programming Languages

IA010: Principles of Programming Languages 4. Control Flow Jan Obdržálek [email protected] Faculty of Informatics, Masaryk University, Brno IA01...
Author: Gilbert King
13 downloads 0 Views 151KB Size
IA010: Principles of Programming Languages 4. Control Flow

Jan Obdržálek

[email protected]

Faculty of Informatics, Masaryk University, Brno IA010

4. Control Flow

1

Evaluation order For imperative languages the order of evaluation is of utmost importance. What affects the order? 1

expression evaluation order

2

sequential order of statements

3

branching (conditional statement, unconditional jumps)

4

iterations (loops)

5

subroutines

6

recursion

7

concurrent execution

8

exception handling

9

nondeterminism

IA010

4. Control Flow

2

Outline

Expressions Assignment statements Control statements Selection statements Iterative statements (loops) Iteration over data structures Other branching constructs

IA010

4. Control Flow

3

Expressions

IA010

4. Control Flow

4

Expressions • fundamental means of expressing computation (in any programming paradigm) • built from • simple objects (constants, variables), using • function/operator application, and • parentheses • basic expression types: • arithmetic • boolean • relational

Operators and operands • operator – built-in function, special syntax • typically does not need parenthesis • placement: prefix, infix, postfix

• operand – operator argument IA010

4. Control Flow

5

Operator evaluation order • For prefix/postix notation the order is implicit. • For infix operators given by 1 precedence rules 2 associativity rules

Precedence (priority) • states which operators are “more important” • these are evaluated first • the number of levels is language-dependent

Associativity • how to group operators with the same priority? • left-to-right, or right-to-left • can depend on the operator IA010

4. Control Flow

6

Example: C operator precedence Operator Type Primary Expression Operators Unary Operators Binary Operators

Ternary Operator Assignment Operators Comma IA010

4. Control Flow

Operator () [] . -> expr++ expr--

Associativity left-to-right

* & + - ! ∼ ++expr --expr (typecast) sizeof / % * + > < > = == != & ˆ | && || ?: = += -= *= /= %= >>= boolean op. 2

exponentiation priority A ** B ** C

! Fortran -- associates to the right

Ada: malformed expression, parentheses necessary 3

unary v. binary operators a + - b + c

// what should we do here?

(illegal, solution: a + (-b) + c)

Programmers rarely remember the precedence hierarchy!

Using parentheses saves lots of headache. IA010

4. Control Flow

8

Operand evaluation order Example 1

Example 2

a = 10; b = a + foo(a);

int a = 5; int bar() { a = 17; return 3; }

/* what if foo changes */ /* the value of a to 20? */

void main() { a = a + bar(); }

side effects • if a function changes either 1 2

one of its parameters, or a global variable

• remember: mathematics does not know side-effects! IA010

4. Control Flow

9

Operand evaluation order II How to deal with side-effects? 1 prohibit them (problematic – e.g. no writing to globals in functions) 2

give a fixed operand evaluation order e.g. Java (left-to-right) (limits possible compiler optimization)

Referential transparency • two expression with the same value can be swapped one for the other with no effect on the result • if no side-effects, result1 = result2 result1 = (fun(a) + b) / (fun(a) - c); temp = fun(a); result2 = (temp + b) / (temp - c);

• advantages: programs are easier to understand • true for purely functional languages IA010

4. Control Flow

10

Operator overloading • if one operator name is used for a number of different operations (e.g. “+” for both integer and real addition) • acceptable, if such an operator does not decrease • readabilty • reliability • problematic overloading example: x = &y; (“&” is either bitwise-and or address-of operator (by context) ) • a similar problem: minus (unary, binary) (ML solution: two different symbols ~ and -) • C++, C#: user-overloaded operators (but e.g. “::” and “.” cannot be overloaded) (Java does not allow user-overloaded operators) • suitable usage: A * B + C * D instead of MatrixAdd(MatrixMult(A,B), MatrixMult(C,D)) IA010

4. Control Flow

11

Short-circuit evaluation • the result can be determined without evaluating all

operands/operators • can be very useful, e.g. in the following code: index = 0; while ((index < listlen) && (list[index] != key)) index = index + 1;

• subtle errors when combined with side-effects: (a > b) || ((b++) / 3)

• languages with short-circuit evaluation:

C-based languages, ML, F#, Python . . . • Ada: both versions – and/and then; or/or else (best of both worlds) IA010

4. Control Flow

12

Assignment statements

IA010

4. Control Flow

13

Assignment statements • the assignment statement is one of the central constructs

in imperative languages • dynamically alters bindings of values to variables

conditional targets ($flag ? $count1 : $count2) = 0;

# Perl

compound assignment operators • shorthands for oft-used forms of assignment a = a + b =⇒ a += b

unary assignment operators • ++ (increment) and -- (decrement) • both prefix and postfix versions • stand-alone (count++;) or in expressions (a = count++;) IA010

4. Control Flow

14

Assignment statement II multiple assignment ($first, $second, $third) = (20, 40, 60); ($first, $second) = ($second, $first);

assignments as expressions • assignment statement can return a value • in that case it can be used in place of an expression • examples: C-style languages, JavaScript, Perl while ((c = getchar()) != EOF) {...}

(parentheses are necessary, low priority of "=") • possible problems: • introduces side-effects: a = b + (c = d/b) - 1 • less effective error detection: if (x=y) vs if (x==y) IA010

4. Control Flow

15

Control statements

IA010

4. Control Flow

16

Control statements • change the flow of execution of a program • control structure • control statement plus • the collection of statements, whose execution it controls • we distinguish • selection statements • iterative statements • uncoditional branching (goto)

Theorem (Böhm, Jacopini 1966) All algorithms that can be expressed by flowcharts can be coded in a programming language with two control statements: a choice between two paths and logically controlled iterations. Corollary: goto is superfluous IA010

4. Control Flow

17

Two-way selection statement The general form: if control_expression then clause else clause

Main issue: nesting selectors Typical syntax in BNF: -> if then | if then else

Which if does the else belong to in the code below? if (sum == 0) if (count == 0) result = 0; else result = 1; IA010

4. Control Flow

18

Matching else to if Several approaches have been used: • nearest previous unpaired then clause (Java) • all then and else clauses must be compound (Perl) • compulsory indentation (Python, F#) • explicit end of if (Fortran, Ada, Ruby) if sum == 0 then if count == 0 then result = 0 else result = 1 end end

IA010

4. Control Flow

if sum == 0 then if count == 0 then result = 0 end else result = 1 end

19

Multiple-selection statements switch (expression) { // C case constant_expression_1: statement_1; ... case constant_expression_n: statement_n; [default: statement_(n+1)] }

Branching at the end of segments • at the end of a segment the control can be transfered • to the next segment (fall-through) • to some other segment (goto) • after the selection statement letter_case = lower; switch (c) { case 'A' : letter_case = upper; case 'a' : ... break; ... 4. Control Flow IA010

// fall through

20

Multiple-selection statements III C/Java: • no implicit branching (rarely used) • branching can be requested explicitly using break • case can be almost anywhere in C (disallowed in Java) switch (x) default: if (prime(x)) case 2: case 3: case 5: case 7: process_prime(x); else case 4: case 6: case 8: case 9: case 10: process_composite(x);

IA010

4. Control Flow

21

Multiple-selection statements III C#: • requires explicit branch statement (break/goto) at the end

of each segment • braching expressions can be of type string

Perl, Python: no multiple-selection statement switch vs a chain of if-then-else statements

• if can use any condition (e.g. < 1, < 10, < 100) • switch evaluates the expression only once • to increase the readability of nested if-then-else constructions keywords elif/elseif are often introduced

IA010

4. Control Flow

22

Iterative statements (loops) basic classification – according to 1 the condition used • loops with a counter (for) • loops with a boolean condition (while-do, do-while, repeat-until ...) • combination of the two 2

location of the control mechanism • top of the loop

(test is performed before executing the loop) • bottom of the loop

(test is performed after executing the loop)

alternative to loops: iterating over data structures

IA010

4. Control Flow

23

Counter-controlled loops 10 FOR I = 1 TO 100 STEP 2

• associated loop variable • loop parameters • initial value • terminal value • step size

C-based languages for (expression_1; expression_2; expression_3) loop body

• combines counting and logical control • all expressions and body are optional • in C89 the test is expression_2 > 0 • loop variable(s) can be modified in the loop body! (disallowed in Ada) IA010

4. Control Flow

24

Counter-controlled loops II Python for loop_variable in object: loop_body [else: else clause]

Examples: for xxx in [42, 50, 1729] for yyy in range(5) # [0,1,2,3,4]

Purely functional languages // F# - counter loop emulation let rec forLoop loopBody reps = if reps -> ... ->

• each branch is “guarded” by a condition • when executed all conditions are evaluated • if more than one test suceeds, the branch is chosen

nondeterministically • related to concurrency and verification • used to define functions in Haskell (patterns) if x >= y -> max := x [] y >= x -> max := y fi IA010

4. Control Flow

32