CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

31
CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order

Transcript of CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Page 1: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

CSCI 330: Programming Language ConceptsInstructor: Pranava K. Jha

Control Flow-II: Execution Order

Page 2: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Execution Order

• Sequencing: the execution of statements and evaluation of expressions is in the order in which they appear

• Selection: a run-time condition determines the choice among two or more statements or expressions

• Iteration: a statement is repeated a number of times until a run-time condition is met

• Procedural abstraction: subroutines that encapsulate collections of statements and 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

• Nondeterminacy: the execution order is deliberately left unspecified, indicating that any alternative will lead to a correct result

Page 3: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Unstructured Flow

• Goto statements feature prominently in early imperative languages

• Merits and evils of gotos hotly debated throughout the late 1960s and much of the 1970s.

• See the following papers:1. Edsger W. Dijkstra (March 1968), “Goto statement considered

harmful,” Letter to the editor, Communications of the ACM, 11 (3): 147–148.

2. Donald E. Knuth (December 1974), ”Structured Programming with goto Statements,” ACM Computing Surveys, 6 (4): 261 - 301

Page 4: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Unstructured Flow

Gotos are generally considered bad, but are sometimes useful for jumping out of nested loops and for coding the flow of exceptions (when a language does not support exception handling).– Ada, C# allow gotos in limited contexts.– Modula, Clu, Eiffel and Java ban them.– Fortran 90 and C++ allow them primarily for

compatibility.

Page 5: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Spaghetti Code

int foobar(int x, int z, int s) { void* next = &&cell0; int retVal = 0; cell0: next = (s==1) ? &&cell1 : &&cell2; goto *next; cell1: retVal = x*7; goto end; cell2: next = (s==2) ? &&cell3 : &&end; goto *next; cell3: next = (x==z) ? &&cell4 : &&end; goto *next; cell4: { printf("%i\n",x); goto end; } end: return retVal;}

Page 6: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Untangle Spaghetti Code

int foobar(int x, int z, int s) { if (s==1) return x*7; else if (s==2) if (x==z) printf("%i\n",x);}

Page 7: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Structured Flow

• Statement sequencing• Selection with “if-then-else” statements and “switch”

statements• Iteration with “for” and “while” loop statements• Subroutine calls (including recursion)• Alternatives to gotos– Mid-loop exit and continue– Early returns from subroutines– Multilevel returns– Errors and exceptions– Continuation

Page 8: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Sequencing

• Sequencing– specifies a linear ordering on statements• one statement follows another

– very imperative, Von-Neumann-style

Page 9: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Sequencing

• 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 it includes variable declarations.– C, C++, and Java use ‘{’ and ‘}’ to delimit a block.– Pascal and Modula use begin . . . end.– Ada uses declare . . . begin . . . end.– Python uses indentation.

Page 10: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Sequencing

• Pure functional languages do not have sequencing, and they do not need it

• Side effects in functions sometimes desirable• def srand(seed)– # Initialize internal tables– # The pseudo-random generator will return a

different– # sequence of values for each different value of seed

• def rand()– # No arguments; returns a new ``random'' number

• Obviously, rand needs to have a side effect

Page 11: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Selection

Selection– sequential if statements

• if ... then ... else

• if ... then ... elsif ... else

• (cond

(C1 E1)

(C2 E2)

...

(Cn En) (T Et)

)

Page 12: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Selection: If-Then-Else

• From Algol 60:– if condition then statement– else if condition then statement– ...– else statement

• To avoid grammatical ambiguity:– Algol 60 requires begin after then– Pascal requires “disambiguating rule”: associate else with the closest

unmatched then– Algol 68, Fortran 77 and modern ones require a terminating keyword

• Modula-2, Ada use nested if-then-elseIF condition THEN statementELSIF condition THEN statement...ELSE statementEND

Page 13: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Selection

Example:

if ((A > B) and (C > D)) or (E <> F)then then_clauseelse else_clause

Code generated w/o short-circuiting(Pascal)

r1 := A - load

r2 := B r1 := r1 > r2 r2 := C

r3 := Dr2 := r2 > r3

r1 := r1 & r2 r2 := E r3 := F

r2 := r2 $<>$ r3 r1 := r1 $|$ r2 if r1 = 0 goto L2

L1: then_clause

goto L3

L2: else_clause L3:

Page 14: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Selection

Code generated w/ short-circuiting (C)

r1 := A

r2 := B if r1 <= r2 goto L4 r1 := C

r2 := Dif r1 > r2 goto L1

L4: r1 := E

r2 := F if r1 = r2 goto L2

L1: then_clause goto L3 L2: else_clause

L3:

Page 15: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Selection: case/switch

• Variant of nested if-then-else statements (thanks to Tony Hoare).• Designed for efficient implementation• Most programming languages support a switch-like statement• C, C++, and Java:

switch (value) {

case "a": x * 5; break;case "b": x = 7; break;case "c": x – 2; break;default: ...

}

• Python: No switch/case statements, but do we need it?result = {

"a": lambda x: x * 5,"b": lambda x: x + 7,"c": lambda x: x - 2

}[value](x)

Page 16: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Jump Comparison Again

Example:CASE ... OF

1: clause_A2,7: claues_B3..5: clause_C10: clause_DELSE: clause_E

END

r1 := ...if r1 <> 1 goto L1clause_Agoto L6

L1: if r1 <> 2 goto L2 if r1 <> 7 goto L3

L2: clause_B goto L6

L3: if r1 < 3 goto L4 if r1 > 5 goto L4 clause_C goto L6

L4: if r1 <> 10 goto L5 clause_D goto L6

L5: clause_EL6:

Page 17: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Jump Comparison Again

Example:CASE ... OF

1: clause_A2,7: claues_B3..5: clause_C10: clause_DELSE: clause_E

END

goto L6L1: clause_A

goto L7L2: clause_B

goto L7L3: clause_C

goto L7L4: clause_D

goto L7L5: clause_E

goto L7L6: r1 := ...

goto *r1L7:

Page 18: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

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 begin of each iteration.– Posttest loops test condition at the end of each iteration.– Mid-test loops allow structured exits from within loop with exit

conditions.

Page 19: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Enumeration-Controlled Loops: Pascal

• Pascal’s enumeration-controlled loops have two simple and elegant forms for up and down:

for id := expr to expr do stmtfor id := expr downto expr do stmt

• Can iterate over any discrete type, e.g. integers, chars, elements of a set

• Evaluate loop bounds exactly once before the first iteration• Changes to loop indices or bounds are prohibited in the loop

body• Final value of loop counter after the loop is undefined

Page 20: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Enumeration-Controlled Loops: Python

• Python’s enumeration-controlled loops only have one form:

for id in sequence expr : stmt

• Can iterate over any sequence types including iterators/generators

• Changes to loop indices or bounds have no effect in the loop body

• Final value of loop variable after the loop is the value most recently assigned

Page 21: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Enumeration-Controlled Loops: C/C++/C#/Java

• C/C++/C#/Java do not have true enumeration-controlled loops.A “for” loop is essentially a logically-controlled loop .for (i = 1; i <= n; i++)

• Changes to loop indices or bounds are allowed in the loop body.

• Use continue to jump to next iteration• Use break to exit loop• C++/C#/Java also support local scoping for counter variables

for (int i = 1; i <= n; i++)

Page 22: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Iterator

• Iterators are used to iterate over elements of well-defined sets (called containers or collections).

• Iterator objects are also called enumerators or generators.• C++/Java iterators are ordinary objects associated with container objects.• In C++, overloading is used to simulate pointer arithmetic in C’s loops

vector<int> V;for (vector<int>::iterator it=V.begin();it!=V.end();it++)

cout << *it << endl;

• In Java, iterator interface provides methods for initialization, generation of the next index value, and testing for completion

Vector<Integer> V;for (Iterator<Integer> it=V.iterator();V.hasNext();)

System.out.println(V.next());

Page 23: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Iterator

• C#/Python/Ruby provide iterators which are functions running in a separate thread from its caller

• Contains yield statement as well as return statement.• The yield behaves like return, except that when the iterator reenteres,

the control continues where it last left off.• Python’s tree in-order traverse

def inorder(t):if t: for x in inorder(t.left): yield x yield t.dat for x in inorder(t.right):

yield x

Page 24: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Pretest loops

• Logically-controlled pretest loops check the exit condition before the next loop iteration

• Pascal:while cond do stmt

• C/C++:while (cond) stmt

Use break to end loops

• C#/Java: similar to C/C++, but that break can jump to redefined labels

Page 25: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Posttest Loops

• Logically-controlled posttest loops check the exit condition after each loop iteration

• Pascal:repeat stmt until cond

• C/C++:do stmt while cond

• Use break to end loops• C#/Java: similar to C/C++, but that break can jump to

redefined labels

Page 26: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Mid-test Loops

• Logically-controlled mid-test loops check exit conditions anywhere within the loop

• Ada: support labels, allowing exit of outer loops without gotosouter:

....loop stmtexit when cond; stmtexit when cond; ....end loop

Page 27: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

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

• Iteration and recursion are equally powerful in theoretical sense; either can be expressed by the other

• 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

Page 28: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Tail Recursion

• Tail-recursive functions are functions in which no operations follow the recursive call(s) in the function: the return value is simply whatever the recursive call returns.Tail Recursive: Non-Tail Recursive:

def fun(): def fun():... ...return fun() return fun()+1

• Compilers can reuse the space on the run-time stack that belongs to the current subroutine’s frame

• Good compilers may even replace tail-recursive calls by jumps to the beginning of the function

Page 29: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Tail-Recursion Optimization: An Example

Consider the GCD function:def gcd(a, b):

if a==b: return aelif a>b: return gcd(a-b,b)else: return gcd(a, b-a)

A good compiler will optimize the function intodef gcd(a, b):

while 1:if a==b: return aelif a>b: a=a-b continue

else: b=b-a continue

Page 30: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Converting General Recursion to Tail Recursion: An Example

General recursive

def sum(f, l, h): if l == h: return f(l) else: return f(l)+ sum(f, l+1, h)

Tail recursive

def sum(f, l, h, s): if l == h: return f(l)+s else: sum(f, l+1, h, s+f(l))

Page 31: CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha Control Flow-II: Execution Order.

Thinking Recursively• Naive recursion design leads to algorithmically inferior programs.• A naive recursive implementation of Fibonacci function:

def fib(n):if n==0: return 1elif n==1: return 1else: return fib(n-1)+fib(n-2)

runs in time that is exponential in n.• A tail-recursive implementation of Fibonacci function

def fib(n):def fib_helper(f1,f2,i):

if n==i: return f2else: return fib_helper(f2, f1+f2, i+1)

return fib_helper(0,1,0)

runs in time that is linear in n.

o