Programming Languages (CSC-302 98S)
Outline of Class 16: Control
Held: Monday, February 23, 1998
- My office appears to have eaten most of
so I won't be grading it (I'd meant to tell you at the time, but
- Enough of you have decided to take a little bit longer on
assignment 3 that I
also don't have that graded for today.
- Today's brown-bag lunch seems particularly interesting, as its on
Mapping the Internet: Yesterday, Today, and Tomorrow. It's
by Gordon Bell, who is a particularly noted speaker.
- Any questions from the
exam review sheet? One of you asked to
have up to two hours on the exam, and I'm amenable to that. I've
still tried to write a one hour exam.
- Every language needs a way to sequence the basic operations, if only
to ensure that there is a way to translate to assembly code (which is
- Sometimes this sequencing will be explicit (e.g., in many languages,
statements listed in sequence will be executed in sequence).
- Sometimes the sequencing will be implicit (e.g., in 3 + 4 * 5).
- A key feature of most imperative languages is that they provide a
variety of explicit control structures.
- What are the key control structures? At the most primitive level,
there are only three:
- Sequencing: Except when other control structures apply,
statements are executed in sequence.
- Unconditional branch: Specifies the next statement to be
executed (often not the one directly after the current statement).
- Conditional branch: Specifies a test to execute and a next
statement to be used if the test succeeds.
- However, use of only these three structures makes programs difficult
- Analysis of an individual statement often requires a clear understanding of
what can/must be true before that statement is executed.
- This allows us to gain a better understanding of what is true after
the statement is executed.
- For example, if we know that y is 2, then after x = 3*y we know
that x is 6.
- However, branches make it difficult to determine what holds true
before a statement, since we don't know what led to the statement
(and because the control that leads to that statement can be scattered
throughout the program).
- Hence, language designers include high-level control structures
that abstract away from the underlying implementation.
- What do we want from our control structures?
- Locality. One can only reach statements through some local action.
- Restricted environment. The ability to restrict the effect
of the rest of the program on statements within the structure.
- Limited entry. Related to the two previous concepts ... there
are only a limited number of ways we can enter a control structure.
- Limited exit. There are only a limited number of ways we can
exit the control structure, and only a limited number of subsequent
statements. (Hopefully, "limited" == "one".)
- What are some of the more popular high-level control structures?
- Procedure/function calls
- Blocks illustrate many of the principles. In general, you enter a block
only at the top and exit it only at the bottom. This means that for a
particular statement within the block, you know exactly what statements
were executed previously.
- A conditional is a form of control in which the statements executed
are determined by one or more tests. Common conditionals include
if statements and case statements.
- In some sense, conditionals select which statements to execute.
- Conditionals are both useful and important as they allow programs to
exhibit significantly different behavior (in terms of the statements
executed) depending on the inputs.
- Languages without some form of selection have less power (formally
- While we have a general sense of the simplest conditionals (conditional
branches and if statements), there are many design issues in
- A case statement consists of a case expression and a sequence
of value/statement pairs. The expression is evaluated and used to
select a particular value/statement pair.
- There are a number of interesting design decisions in case statements:
- What are the possible types of values in the pairs?
- Must those values form a continuous range?
- Do we permit a "default" value?
- What do the values "look like"? Must they be constants? Constant
expressions? Can they be variables?
- Can multiple value/statement pairs have the same value? If so, what is
- If we were to include guarded conditionals in our language, we would
have to consider a number of issues.
- Should the implementation be required to be nondeterministic? Why
or why not?
- Should the implementation be required to execute all the guards? Why
or why not?
- In what order should the guards be executed?
- Can guards have side-effects?
- Should we permit a default (other than "true")?