Previous Table of Contents Next


At the statement labeled loop, the value of i, 0 initially, is incremented by one. In the following statement, a line containing the word, a separating colon, and the count is written (assigning a value to output causes its value to be written). As long as i is in bounds, control is transferred back to the statement labeled loop. When i exceeds the length of the array, however, the statement fails and the program terminates by flowing into the statement labeled end.

SNOBOL4, which is still in use today, is one of the most powerful programming languages ever developed. It has problems, however: an idiosyncratic syntax, a lack of control structures, and a separation of language facilities into two quite different sublanguages—pattern matching and traditional computation.

Work on the SNOBOL languages moved to the University of Arizona in 1971 with attempts to resolve the problems with SNOBOL4. This work led to SL5 (SNOBOL Language 5; Hanson & Griswold, 1978), which generalized the concepts in SNOBOL4 and provided a more conventional syntax with control structures. SL5 used a very general coroutine mechanism to support the search-and-backtracking facilities of pattern matching. The result was a very powerful but large and complicated language that is difficult to use and understand. SL5 never became popular, but it provided the inspiration for Icon.

Icon arose from the realization that a full coroutine mechanism was not necessary to support pattern matching. Instead, pattern matching could be accomplished using generators and goal-directed evaluation.

Generators in Icon are expressions that can produce more than one result and suspend computation between results. Goal-directed evaluation automatically searches for a successful result, using alternative results from generators.

At the time, this approach was seen as a simplification of SL5’s pattern-matching mechanism. In fact, generators and related control structures became a pervasive aspect of Icon and are useful in many different kinds of computation. Icon is a much more powerful and general programming language than was originally perceived and, in fact, pattern matching became a natural consequence of generators and goal-directed evaluation.

The first version of Icon appeared in 1978 (Griswold, 1978), followed by successive versions that smoothed out rough spots and added additional facilities. The last major version of Icon, Version 9, added extensive graphics facilities.

The heritage of SNOBOL, as well as the different approach taken by Icon, can be seen in this Icon program for counting words:

    procedure main()

       wordcnt := table(0)

       while line := read() do {
          line ? {
             while tab(upto(&letter)) do
                  wordcnt[tab(many(&letters))] +:= 1
             }
          }

       wordcnt := sort(wordcnt, 3)

       while write(get(wordcnt), “ : “, get(wordcnt))

    end

Unlike the SNOBOL languages, Icon has a familiar syntax and conventional control structures. The concepts of success and failure are still used, as in controlling loops. Instead of the patterns of SNOBOL4, Icon uses matching procedures and string-analysis functions to provide more control over string analysis.

6.2. The Language

6.2.1. Basics

6.2.1.1. Program Structure

As in most imperative programming languages, an Icon program consists of declarations: procedure declarations that include executable code, declarations for record structures, scope declarations for identifiers, and so on.

Icon uses a reserved-word syntax; procedure, end, global, if, then, and so forth have special syntactic meanings.

Every Icon program must have a main procedure; program execution begins with the invocation of this procedure. Here’s a simple Icon program that just writes a greeting:

    procedure main()

       write(“Welcome to Mars.”)

    end

Computation is performed by evaluating expressions, such as the function write() in the example. The main kinds of expressions are

operators, such as countdown – 1
function and procedure calls, such as write(“Earthling go home!”)
control structures, such as if countdown = 0 then write(“Ignition.”)

Icon is an expression-based language. It has no statements; even control structures produce values. Icon also has no block structure. Expressions are separated by semicolons and can be grouped using braces, as in

    if countdown = 0 then {
       write(“Ignition.”);
       write(“Lift off.”)
    }

When an expression ends at the end of a line, no semicolon is needed, as illustrated by

    if countdown = 0 then {
       write(“Ignition.”)
       write(“Lift off.”)
    }

6.2.1.2. Assignment

The operation := assigns a value to a variable, as in

    count := 0
          ...
    countdown := countdown – 1

As in this assignment, the assigned value often is obtained by a computation on the value of the variable to which the assignment is then made. Icon provides augmented assignment operations that combine the assignment operation with the operation to be performed on the variable. An example is

    countdown –:= 1

which decrements the value of countdown.

There are augmented assignment operations for all infix (binary) operations except assignment itself.

6.2.1.3. Comments

The character # indicates the beginning of a comment. The # and all subsequent characters up to the end of the current line are ignored.

An example is

    write(“Welcome to Mars.”)    # might as well be friendly …


Previous Table of Contents Next