Icon--An Agile Programming Language

It's often the case that a programmer working on a large project encounters small problems that are amenable to being solved with a program but it can be hard to justify the time to develop a solution in whatever language he or she knows best. For example, a Java programmer might have a one-time need to create an XML file based on data residing in a plain text file. A FORTRAN programmer might want to randomly generate files of test data specified by a simple description language. A teaching assistant for a C++ class might want to determine if the class interface in each of several dozen solutions is exactly as specified in an assignment.

Those problems can obviously be solved mechanically (i.e., with a program) but depending on the language used (perhaps Java, FORTRAN, or C++) it might take longer to write the program than to do the task manually, especially if the task needs to be done only once. In situations of this sort an "agile language" often provides a good solution. Agile languages, which are called "scripting languages" by some, are designed to let the programmer work at a high level and write very expressive code. They provide a "critical mass" of types and operations, often with a heavy emphasis on string processing, and give the programmer as much freedom as possible. Agile languages typically have maximum advantage over languages like Java, C++, and VB.NET for small to mid-size programs--10s to 100s of lines.

Three popular agile languages are Perl, Python, and Ruby but a number of programmers have found that Icon is a good choice for an agile language because it has:

Here is the full set of slides for a fifteen-hour course on Icon offered by Mitchell Software Engineering. You can perhaps get a reasonable feel for Icon by browsing through them. Note that the slides are in the public domain--you may use them as you see fit.

A few examples of Icon

Here's a simple example of Icon -- a program that reads lines from standard input and prints the lines in reverse order (last line first; first line last):

procedure main()
    lines := []                     # make an empty list
    while line := read() do {       # loop reading lines from standard input
        push(lines, line)           # push the line on the list
        }

    while line := pop(lines) do {   # loop while lines can be popped off the list
        write(line)                 # write the line out
        }
end

Taking more advantage of Icon's syntax and its notion of expression failure leads to a more concise solution:

procedure main()
    lines := []

    while push(lines, read()) # When read() fails (at EOF) the failure is
                              # propagated to push(...), which fails in turn.
                              # The failure of push() causes the 'while' to fail.

    while write(pop(lines))
end
A slightly different solution is produced by using generators:
procedure main()
    lines := []

    every push(lines, !&input)

    every write(!lines)
end
The unary ! operator generates values from an aggregate. The first every expression generates lines from &input, a value of type 'file' that represents standard input. Each line generated by !&input is pushed on the list.

Icon's generators are far more general than the iterator-based control structures found in other languages. A generator can appear in any Icon expression. Here's an expression that assigns to x the first element of L that is an integer, real, or convertible to same:

x := numeric(!L)
If no element is numeric, x is not changed.

Another problem: Consider a file whose lines consist of zero or more integers separated by white space:

5 10 0 50
200

1 2 3 4 5 6 7 8 9 10

Here is an Icon program to sum the numbers in such a file:

link split
procedure main()
    sum := 0
    while line := read() do {
        nums := split(line, ' \t') # split 'line' on blanks and tabs, producing a list
        every num := !nums do
            sum +:= num
        }
    write("The sum is ", sum)
end

The program can be shortened considerably by using nested generators:

link split
procedure main()
    sum := 0
    every sum +:= !split(!&input, ' \t')

    write("The sum is ", sum)
end

One more change: Don't assume that the input is only numbers and white space. Allow text like this: "July 4, 1776". A slight adjustment accommodates the change:

every sum +:= !split(!&input, ~&digits) # instead of splitting on whitespace, split on non-digits

Consider this: How much code would this program be in the best-suited language you know? Can you write it without using any reference material?

More on Icon

Icon is in the public domain and is a very practical result of a decade of National Science Foundation-funded research on high-level programming language facilities. Icon was developed at the University of Arizona; the principal investigator was Dr. Ralph Griswold, one of the inventors of SNOBOL4.

If you're a designer of an agile language you may find that Icon holds some interesting lessons. For example, some elements of Icon have been incorporated in Python. Implementors of agile languages can perhaps learn a few things from this book: The Implementation of the Icon Programming Language.

If you simply like to think about alternative concepts in computation, Icon provides a lot of food for thought. (For example, Icon's control structures can be modeled using co-expressions, and new control structures can be prototyped.)

Implementations of Icon for a number of platforms, and a variety of Icon-related resources including on-line books can be found at the Icon Home Page.

Here is the source for the Icon Evaluator (ie). An interesting thing about it is that it does no expression evaluation. It simply accumulates expressions, wraps them in a main program, writes it out as a temporary file, and compiles and executes it. It'd be fun to try this in other languages.

There is, of course, an Icon news group.

Icon is very stable and has been so for several years. Unicon, the Unified Extended Dialect of Icon, is the current focus of Icon-related research and development.

Mitchell Software Engineering offers free one-hour and half-day seminars on Icon, delivered at your company or organization, for groups of any size. (Subject to availability, which is limited outside of Arizona.)

CSc 451, The Icon Programming Language, was offered at the University of Arizona in Spring 2003. Here are the course materials for that class. In addition to coverage of the core language there were segments on Icon's graphics facilities and Unicon, with sets of slides available for each. There are also ten programming assignments and three exams, with solutions.