Chapter 8 Part 2 CPL
pretest
means that the test for loop completion occurs before the loop body is executed.
posttest
means that the test occurs after the loop body is executed.
body
of an iterative statement is the collection of statements whose execution is controlled by the iterative statement.
iteration based on data structures
A general data-based iteration statement uses a user-defined data structure and a user-defined function (the iterator) to go through the structure's elements. The iterator is called at the beginning of each iteration, and it returns an element from the data structure in some desired order. Loop terminates when the iterator returns null. C's for can be used to build a user-defined iterator: for (p=root; p==NULL; traverse(p)){ ... } Ada allows the range of a loop iterator and the subscript range of an array to be connected with subranges. subtype MyRange is Integer range 0..99; MyArray: array (MyRange) of Integer; for Index in MyRange loop . . . end loop; PHP has some built-in iterators to provide iterative access to PHP's arrays. - current points at one element of the array. - next moves current to the next element. - prev moves current to the previous element. - reset moves current to the first element. Java 5.0 uses for, although it is called foreach as a built-in iterator: for (String myElement : myList) { ... } C# and F# (and the other .NET languages) have generic library classes, like Java 5.0 (for arrays, lists, stacks, and queues). Can iterate over these classes with the foreach statement. User-defined collections can implement the IEnumerator interface to use foreach. Ruby blocks are sequences of code, delimited by either braces or do and end Blocks can be used with methods to create iterators. It has some built-in iterator methods (times, each, upto). - Ruby has a for statement, but Ruby converts them to upto method calls
counter controlled loop examples
Ada for var in [reverse] discrete_range loop ... end loop Design choices: Type of the loop variable is that of the discrete range (A discrete range is a sub-range of an integer or enumeration type). The reverse reserved word is optional indicates that the values of the discrete range are assigned to the loop variable in reverse order. Loop variable does not exist outside the loop. The loop variable cannot be changed in the loop, but the discrete range can; it does not affect loop control. The discrete range is evaluated just once. Cannot branch into the loop body. C-based languages for ([expr_1] ; [expr_2] ; [expr_3]) loop body The expressions can be whole statements, or even statement sequences, with the statements separated by commas. The value of a multiple-statement expression is the value of the last statement in the expression. All of the expressions are optional. If the second expression is absent, it is an infinite loop. Design choices: There are no explicit loop variable or loop parameters. Everything can be changed in the loop. The first expression is evaluated once, but the other two are evaluated with each iteration. - It is legal to branch into the body of a for loop in C. C++ differs from C in two ways: The control expression can also be Boolean. The initial expression can include variable definitions (scope is from the definition to the end of the loop body). Java and C#: Differs from C++ in that the control expression must be Boolean. Python for loop_variable in object: - loop body [else: - else clause] The object is often a range, which is either a list of values in brackets ([2, 4, 6]), or a call to the range function (range(5), which returns 0, 1, 2, 3, 4. The loop variable takes on the values specified in the given range, one for each iteration. The else clause, which is optional, is executed if the loop terminates normally.
User-Located Loop Control Examples
C , C++, Python, Ruby, Java, and C# have unconditional unlabeled exits (break). Java and Perl have unconditional labeled exits (break in Java, last in Perl). C, C++, Java, and Python have an unlabeled control statement, continue, that skips the remainder of the current iteration, but does not exit the loop. Java and Perl have labeled versions of continue.
logically controlled loops examples
C and C++ have both pretest and posttest forms, in which the control expression can be arithmetic: 1) Top loop (pretest): while (control_expr) loop body 2) Bottom loop (posttest): do loop body while (control_expr) - In both C and C++ it is legal to branch into the body of a logically-controlled loop. Java is like C and C++, except: The control expression must be Boolean. The loop body can only be entered at the beginning. F# As with counter-controlled loops, logically-controlled loops can be simulated with recursive functions. let rec whileLoop test body = if test() then body() whileLoop test body else ();; This defines the recursive function whileLoop with parameters test and body, both functions. test defines the control expression.
guarded command rationale
Connection between control statements and program verification is strong. Verification is impossible with goto statements. Verification is possible with 1) only selection and logical pretest loops. 2) or only guarded commands. Verification is relatively simple with only guarded commands.
counter controlled loops design issues
Design Issues: What are the type and scope of the loop variable? Should it be legal for the loop variable or loop parameters to be changed in the loop body, and if so, does the change affect loop control? Should the loop parameters be evaluated only once, or once for every iteration?
guarded commands
Designed by Dijkstra. Purpose: to support a new programming methodology that supported verification (correctness) during development. Basis for two linguistic mechanisms for concurrent programming (in CSP and Ada). Basic Idea: if the order of evaluation is not important, the program should not specify one (nondeterminism).
counter control loops functional
F# Because counters require variables, and functional languages do not have variables, counter-controlled loops must be simulated with recursive functions. let rec forLoop loopBody reps = if reps <= 0 then () else loopBody() forLoop loopBody, (reps - 1) This defines the recursive function forLoop with the parameters loopBody (a function that defines the loop's body) and the number of repetitions. () means do nothing and return nothing
loop guarded commands
Form do <Boolean> -> <statement> [] <Boolean> -> <statement> ... [] <Boolean> -> <statement> od Semantics: for each iteration Evaluate all Boolean expressions. If more than one are true, choose one non-deterministically; then start loop again. If none are true, exit loop
selection guarded commands
Form if <Boolean expr> -> <statement> [] <Boolean expr> -> <statement> ... [] <Boolean expr> -> <statement> fi Semantics: when construct is reached, Evaluate all Boolean expressions. If more than one are true, choose one non-deterministically. If none are true, it is a runtime error.
design issue for iteration control statements
General design issues for iteration control statements: 1. How is iteration controlled? 2. Where is the control mechanism in the loop?
logically controlled loops
Repetition control is based on a Boolean expression. Logically controlled loops are more general than counter-controlled loops. Every counting loop can be built with a logical loop, but the reverse is not true. Design issues: Should the control be pretest or posttest? Should the logically controlled loop be a special case of the counting loop statement or a separate statement?
User-Located Loop Control Mechanisms
Sometimes it is convenient for the programmers to decide a location for loop control (other than top or bottom of the loop). Simple design for single loops (e.g., break). Design issues for nested loops Should the conditional mechanism be part of the exit? Should control be transferable out of more than one loop?
iterative statements
The primary possibilities for iteration control are logical, counting, or a combination of the two. The main choices for the location of the control mechanism are the top or the bottom of the loop.
iteration or recursion
The repeated execution of a statement or compound statement is accomplished either by
motivation for use located control
The target of a goto can be many places in the program, both above and below the goto itself. The targets of user-located loop exits (break, continue, or last) must be below the exit.
unconditional branching
Unconditional branching statement transfers execution control to a specified place in the program (goto statement). Represented one of the most heated debates in 1960's and 1970's. It is powerful but harmful for readability. Some languages do not support goto statement (e.g., Java, Python, Ruby). C# offers goto statement (can be used in switch statements). Loop exit statements are restricted and somewhat camouflaged goto's.
conclusion
Variety of statement-level structures. Choice of control statements beyond selection and logical pretest loops is a trade-off between language size and writability. Functional and logic programming languages use quite different control structures.
counting iterative statements
has a loop variable, and a means of specifying the initial and terminal, and stepsize values.
iterative statements
is one that causes a statement or collection of statements to be executed zero, one, or more times.