Previous | Table of Contents | Next |
6.2.1.4. Control Flow
Expressions are evaluated in the order in which they appear unless a control structure is encountered. By definition, a control structure is an expression that may change the sequential order of evaluation.
An important and distinguishing characteristic of Icon is that control decisions are based on the success or failure of conditional operations and not on boolean values. For example,
countdown = 0
compares the value of countdown with 0. If countdown is equal to 0, the comparison expression succeeds; otherwise, it fails.
An example of the use of success and failure to control program flow is
while line := read() do process(line)
The function read() attempts to read a line of text from standard input. It succeeds if there is a line and produces the line as its value, which is then processed. However, if there is no more data, read() fails. The while-do control structure uses the failure of read() to terminate the loop.
Failure is not an error; failure occurs when an operation is meaningful but cannot be carried out in a specific situation.
6.2.1.5. Data Types
Icon has no type declarations; a variable can have a value of any type. Values are typed, however, and when computations are performed, types are checked to be sure they are appropriate.
Icon has several data types. The numeric types are integer and real (floating point). Icon has no character type, but instead it has a string type. A string is a sequence of characters in which order is significant. Strings can be arbitrarily long. Icon also has a cset (character set) type. Csets are unordered collections of distinct characters.
Icon supports four structure types: records, lists (vectors), sets, and tables with associative lookup.
Types are converted (coerced) automatically when possible. For example, in
year := 2010 write(year)
the integer 2010 is automatically converted to a string for the purpose of writing.
A type that cannot be converted to an appropriate one causes a runtime error that terminates program execution. For example, in
countdown 1
the string 1 is converted to the integer 1, but
countdown i
is erroneous and causes program termination because i does not represent an integer.
The type of any value can be determined during program execution by using the function type (x), which produces the string name for the type of x. For example, type(year) produces integer.
Values can be converted from one type to another explicitly, as in
date := string(year)
which assigns the string 2010 to date. Explicit type conversion fails instead of causing error termination if the conversion cannot be performed. For example, integer(i) fails.
The null value is a special value that is the initial value of variables. The null value is illegal in most computations, so attempting to perform an operation on a variable that has not been assigned a value explicitly usually produces an error.
The operations /x and \x succeed and fail if x has a null or non-null value, respectively. They can be used to determine if a value has been assigned to a variable, as in
if /state then #initialize state
6.2.1.6. Control Structures
Icon has a large repertoire of control structures that includes ones that are common to most imperative programming languages. These are
if expr1 then expr2 else expr3 while expr1 do expr2 until expr1 do expr3
The control structure
repeat expr
evaluates expr repeatedly and is equivalent to an expression such as
while 1 do expr
Any looping control structure can be terminated by the expression break, as in
repeat { if faults > 0 then break }
if faults is greater than 0, the repeat loop is terminated and control is transferred to the point immediately after it.
The expression next, on the other hand, returns control to the beginning of the loop in which it appears, as in
while countdown > 0 do { if okay = 0 then next else correct() }
The not control structure inverts success and failure. It fails if its argument succeeds and succeeds, producing the null value, if its argument fails. For example,
if not expr then write(evaluation failed)
writes evaluation failed if expr fails.
The case control structure selects an expression to evaluate based on a value. For example,
case name of { Napoleon: write(French) DeGaulle: write(French) Hitler: write(German) Churchill: write(English) default: write(unknown) }
The values can be of any type and need not all be of the same type.
Icon has several unconventional control structures. One is alternation (or):
expr1 | expr2
In alternation, expr1 is evaluated first. If it succeeds, its value is the result of alternation. If it fails, expr2 is evaluated; if it succeeds, its value is the result of alternation. If both expr1 and expr2 fail, the alternation control structure fails. For example, in
if (countdown > 0) | (hold > 0) then report()
report() is evaluated if either countdown or hold is greater than 0.
Many expressions can be linked together in alternation to produce the alternation of many values:
expr1 | expr2 | expr3 | | exprn
Control structures that use other aspects of expression evaluation are described in section 6.2.2.
Previous | Table of Contents | Next |