Skip to Content

PL: Statements and Control Structures

From old CS 471 notes…

Statements, Expressions, and Control Structures (Chs. 7 & 8)

Arithmetic Expressions

I’m skipping all the basics (much has already come up in previous lectures):

  • operator precedence
  • operator associativity
  • order of operand evaluation
  • side effects
  • automatic type conversion

Important or “odd” points are discussed below.

The Modulus Operator

Most languages use “%” to indicate a modulus operation.

Modulus is consistent when both operands are positive, but can vary between languages when both or either operand is negative.

Be careful! Know your modulus operator!

The Ada programming language has both a rem operator (remainder) and a mod operator (modulus) to handle this situation.

Conditional Expressions

Many languages have the C-like ?: conditional expression operator.

This is not the same as the conditional statement if (expr) statement; [else statement;]

The conditional expression returns a value, the statement does not.

Referential Transparency

An expression, function, or any other piece of code has a side effect if it permanently modifies the state of the program:

  • Assigning a new value to a variable that still exists after that piece of code finishes;
  • Writing to an output device;
  • Reading from an input device; (how?)

In expressions, side effects can be caused by operators such as the auto-increment (++) and auto-decrement (–) operators, and by function calls to functions that have side effects.

A function can modify its own local variables without having side effects; the return value is the only allowed result of a side-effect-free function.

Call-by-reference parameters to a function that modifies the parameter is a side effect.

A piece of a program that has no side effects is referentially transparent: it can be substituted and optimized freely, such as common subexpression elimination or function memoization.

Operator Overloading

Most programs already have overloaded operators: using the “+” symbol for both integer addition and floating point addition means that the “+” symbol is overloaded.

Some languages allow user-defined operator overloading, generally only adding new meanings to existing operator symbols.

Text: Ruby allows redefining existing operator meanings.

Short-Circuit Evaluation of Logical Operators

You should all know this by now.

C/C++/Java and many other languages enforce the policy of evaluating the logical AND and logical OR operators in a short circuit evaluation mode.

This means that if the first operand determines the result of the operator, then the second operand is not allowed to be evaluated.

This evaluation mechanism is due to the fact that there are not any machine instructions for these operators: the effect of the operator is simply caused by the constructed control flow.

This is very useful in programming with pointers and references: you can check the pointer/reference for null in the first half, and access it in the second half, knowing that it is safe to access:

if (p && *p != '\0') 

Useful also for checking array indices and the then array element, etc.

Control Structures

Three basic controls needed: sequence, selection, iteration

Then also function call and recursion

Recursion can replace iteration, and vice versa.

Loop Highlights

Two basic loop styles: execute 0 or more times (while, for), and execute 1 or more times (do-while or repeat-until).

Scripting languages often, and now Java too, have an “iterate over collection” loop. Often called foreach, in Java it re-uses the for keyword and allows iteration over any collection class that implements the Iterable interface:

for (String name: customerNames)
{
   System.out.println("Customer " + name);
}

Guarded Commands

A “radical” alternative to normal deterministic selection and iteration constructs that we are used to programming with.

Useful for specifying concurrency and non-deterministic computations.

deterministic: the outcome of a computation is completely predictable and determinable by looking at the program and knowing the input. It will always do the same thing.

non-deterministic: the outcome may potentially randomly change, but not necessarily in an uncontrolled manner.

Used in CSP (Communicating Sequential Processes) and others.

Also used to specify systems that can be model-checked for guaranteeing certain properties.

The Spin model-checking tool uses the Promela modeling language, which has guarded commands as its basic selection and sequencing control structures.

Basic form:

if (do)
[] bool_expr -> statement
[] bool_expr -> statement
...
fi (od)

For the selection (if) statement, exactly one of the statements with a true boolean expression guard is selected for execution. If more than one guard is true, the choice is made nondeterministically.

For iteration, each time through the loop exactly one of the statements with a true boolean expression guard is selected for execution. If more than one guard is true, the choice is made nondeterministically. The guards are re-evaluated every loop iteration. Looping stops when no guards are true.