statement level flow of control selection structures copyright © 2003-2014 by curt hill
TRANSCRIPT
Copyright © 2003-2014 by Curt Hill
Control Structures• In the beginning was FORTRAN• FORTRAN reflected the machine
that it was designed on: IBM 704• It had five control structures:
– Unconditional GOTO– Logical If– Arithmetic If– Do loop– Computed GOTO
• We should be critical but they just did not know any better
1 and 2 of the Five• Unconditional GOTO
GOTO 5– FORTRAN was column oriented and
statement labels were numbers– These resided in columns 1-5
• Logical ifif (a.gt.e) GOTO 12– It could only have one statement
following it and not every statement either
– Usually an assignment or goto
Copyright © 2003-2014 by Curt Hill
3 and 4 of the Five• Arithmetic if
if(a)10,20,30– A must be an integer– Then we branched to one of the three labels
based on A negative, zero or positive
• Do loopdo 15,i=1,10,2– Similar to the counting for of many languages– First number was the last statement of the loop– There was an assignment, limit and increment– The do was actually a trailing decision loop
Copyright © 2003-2014 by Curt Hill
Last of the Five
• Computed GOTOgoto (10,15,20,5,30), i– Precursor to a case– If i = 1 goto first label– If i = 2 goto second label etc
– All of these translated directly into 704 machine language
Copyright © 2003-2014 by Curt Hill
Is that the best we can do?• In those days we did not know what
would make for good programming practices, but in the early sixties the goto wars began
• Those who only knew Assembly or FORTRAN or COBOL got carried away and used gotos to make some rather beastly execution flows– These were motivated by efficiency– Machines were quite expensive and
people still relatively inexpensive (>$5/CPU second)
Copyright © 2003-2014 by Curt Hill
What’s wrong with this?
Copyright © 2003-2014 by Curt Hill
IF (A.GT.B) GOTO 20. . .
50 IF (A.EQ.C) GOTO 70 A = B * C20 IF(C.EQ.0) GOTO 90
A = A * 2IF (R.GT.2) GOTO 40C = A+B*2-CIF(B.GT.C) GOTO 50READ(*,5)R,C
40 B = B + R - CGOTO 50. . .
70 CONTINUE . . .90 CONTINUE
The GOTO Wars• The Structured Programming
types coined the term spaghetti code to describe how these programs used flow of control– These were led by Dijkstra and
others
• The war was fought in the Journals– Titles: goto considered harmful
Copyright © 2003-2014 by Curt Hill
Crushing Victory
• In 1966 Bohm and Jacoppini proved that any program could be written with just three structures: sequence, if and while– This cut the theoretical ground
out from under the GOTO proponents
– The war did last several more years
Copyright © 2003-2014 by Curt Hill
Last Shot• The last shot was in 1974 when
D.E. Knuth published Structured Programming with GOTOs– Among other things it said that
good programmers used the GOTO in a way that was reasonable before there were languages that supported it
– This was almost a face saving article on behalf of the GOTO crowd and marked the end of the war
Copyright © 2003-2014 by Curt Hill
Preprocessors• By the late sixties there were a
number of preprocessors for FORTRAN that would make real control structures and translate them into if-goto structures– These did what the compiler did in
assembly language: convert nice structures into what the machine has
• However the languages that supported structured programming rapidly supplanted FORTRAN as the king of the languages
Copyright © 2003-2014 by Curt Hill
Three or More?• Just because you can program
with just the three does not mean that we should only have the three– Writability is aided by more– Structured programming does
demand that each control structure be single entry and single exit
– The worst control structure ever created was a multiple entrance, multiple exit loop
– However, multiple exit loops are not a problem
Copyright © 2003-2014 by Curt Hill
Compound statements• FORTRAN’s flow of control would
not have been near the problem if the IF could have had multiple statements
• Forcing a GOTO after an IF made it seem like the GOTO was the correct statement– Recall Sapir Whorf hypothesis
• ALGOL 60 introduced the compound statement, which was a BEGIN - END similar to what we see in its descendants Pascal and Ada
Copyright © 2003-2014 by Curt Hill
Compound Statements
• The ALGOL 60 compound statement was called a block and was stronger than the compound statement in Pascal or C– It allowed declaration of variables
and scope
• C++ and Java also allow this more general block in that you can declare variables but not always new functions
Copyright © 2003-2014 by Curt Hill
Selection statements
• The design issues:– How many ways?
•1, 2, many
– What controls the selection? Form and type?
– What restrictions on what statement(s) are controlled?
– Nesting of selections?
Copyright © 2003-2014 by Curt Hill
One way• The FORTRAN IF was one way• It had a one statement then• It had no else, which if needed
was constructed using GOTOs• A boolean controlled it, but the
statement was only executed on true
• It also used negative logic– The if said when to GOTO which
bypassed the next statements rather than the condition to execute them
– Thus the next statement was an elseCopyright © 2003-2014 by Curt Hill
Two Way• ALGOL 60 had the one way and
also had two way• It introduced the THEN and
ELSE as well as the block• Most languages have followed
this pattern since then• FORTRAN 66 did not but 77 did
Copyright © 2003-2014 by Curt Hill
Nesting• The two way if makes nesting a
problem• If an if is in an if who gets the
else?• The Pascal solution is to give
the else to the first unmatched if– Use a compound statement to
override that approach– This takes a disambiguation rule,
since the grammar is actually ambiguous on this point
Copyright © 2003-2014 by Curt Hill
Language Choices• The ALGOL 60 solution is to
disallow an if as the then statement– Especially since it introduced blocks– C and C++ follow Pascal
• Perl forces all thens and elses to be compound statements
• Ada has different endings for different things– Thus an IF always starts an implied
compound statement
• Python uses indentationCopyright © 2003-2014 by Curt Hill
Python Example
Copyright © 2003-2014 by Curt Hill
if sum == 0 : if count == 0 : result = 0 else : result = 1
Syntactic boundaries• Where does the condition end and
the executable statement begin?• In FORTRAN I you could only compare
a variable to a variable or constant– There were ANDs/ORs added later– Thus it was easy to tell what came next
• In most later languages an expression may be on both sides of a the relational and there are complications added by ANDs and Ors
Copyright © 2003-2014 by Curt Hill
Boundaries• Pascal has a THEN to terminate
its if condition• C/C++/Java enclose the condition
in parentheses so do not need a Then
• All of these only allow a single statement for the then or else, so the compound statement is heavily used
• When an END or } is encountered it is not obvious what started it
Copyright © 2003-2014 by Curt Hill
Ada and Boundaries• Ada uses another approach
– It uses end if to terminate an if so does not need the compound statement
– The then part starts with THEN and ends with ELSE or END IF
– This also straightens out the nesting issues
• Modula 2 closes every control structure with end, which is somewhat similar to Ada but less readable
Copyright © 2003-2014 by Curt Hill
Need for Multiways
• Very often we run into situations like the following– Series of Ifs– The then part does something– The else part is another IF– The comparison condition is
always the same: variable = constant
– All ifs have the same variable, but different constants
Copyright © 2003-2014 by Curt Hill
Multiway Selectors• The design issues:
– About the same as Ifs– What controls the selection? Form
and type?– What restrictions on what
statement(s) are controlled? Single, sequences or compound statements?
– How to encapsulate the statement?– May just a single segment be
executed?– What to do about unrepresented
values?
Copyright © 2003-2014 by Curt Hill
FORTRAN• The FORTRAN arithmetic if and
computed goto are the first• Computed GOTO
goto (10,15,20,5,30), i– If i = 1 goto first label– If i = 2 goto second label etc
• Arithmetic ifif(a)10,20,30– Then we branched to one of the
three labels based on A negative, zero or positive
Copyright © 2003-2014 by Curt Hill
FORTRAN Problems
• These are much more insidious than modern cases because the target labels can be anywhere in the program – before or after
• Moreover these labels may be accessed by other GOTOs– This violates single entry principle
• These are strongly based on IBM 704
Copyright © 2003-2014 by Curt Hill
A Modern Case?• ALGOL-W was the first with a
near modern case• The statements are numbered
by occurrence without a label• The case selector must be a
positive integer• Each statement may be a
compound statement
Copyright © 2003-2014 by Curt Hill
ALGOL W Case
Copyright © 2003-2014 by Curt Hill
case j of begin x:=5; // Chosen by j=1 begin // Chosen by j=2 r := 2; s := x*r; end; z := 0;// Chosen by j=3 end
Pascal generalizes this• Case labels explicitly identify the value • The label and the selector must match
and be ordinal type• The labels can be in logical not
numeric order• This allows negative and non-
contiguous values as well• Subranges of values and lists of values
are allowed• No option for an ELSE clause though
most dialects have a non-standard way to do it
Copyright © 2003-2014 by Curt Hill
Pascal Case
Copyright © 2003-2014 by Curt Hill
case color of blue: x := 5; red,green: begin
r := 2; j := 5; end; end;
C Family
• The C, C++, Java switch is primitive– The lack of a break allows multiple
segments to be executed– The case makes for difficult ranges– However the default is good
• The Ada case follows Pascal in function (slightly different form) but has an others clause
• FORTRAN 90 is similar to AdaCopyright © 2003-2014 by Curt Hill
C Example
Copyright © 2003-2014 by Curt Hill
switch (i) { case 2: r = 4; j = 5; // allows drop into case 5: x = 7; break; default: x = 0; }
Ruby Example
Copyright © 2003-2014 by Curt Hill
leap = case
when year % 400 == 0 then true
when year % 100 == 0 then false
else year % 4 == 0
end
Implementation
• Conversion into nested if then else• Table of addresses
– Search it– Hash into it– Jump into it
• This only works for contiguous values
Copyright © 2003-2014 by Curt Hill
Multiple nested ifs• Recall that the switch or case
statement is not very general– Series of Ifs– The then part does something– The else part is another IF– The comparison condition is always the
same: variable = constant– All ifs have the same variable, but
different constants
• In some sense the case generalizes the if from Boolean to other ordinal values
Copyright © 2003-2014 by Curt Hill
Is that good enough?• There are many more situations
where this kind of structure does not work but we still have the if then else if then else if form– But the form of the condition is
different
• How can this be handled?• The default is that each if should
have its own complete structure– Pascal, C family– This can be error prone when it is
deeply nestedCopyright © 2003-2014 by Curt Hill
Ada Does Better
• Ada allows an elsif which condenses the amount of writing for deeply nested if then elses
• It also allows fewer end items• Notice that the difference
between a case and nested if is that the case only examines one expression to determine the selection
Copyright © 2003-2014 by Curt Hill
Ada Example
Copyright © 2003-2014 by Curt Hill
-- Increment NumPos/Neg/ZeroIF X > 0 THEN NumPos := NumPos + 1;ELSIF X < 0 THEN NumNeg := NumNeg + 1;ELSE -- X is zero NumZero := NumZero + 1;END IF;