Icon (programming language)
Icon (programming language)
Icon is a high-level language designed mainly for text and string processing. It was created in the 1970s by Ralph Griswold (with others) and grew out of his earlier SNOBOL work. Icon emphasizes goal-directed execution, where expressions can succeed or fail, and this success/failure drives the flow of the program. It’s dynamically typed and blends ideas from SNOBOL, SL5, and ALGOL-like languages to give concise, string-centric code.
Key ideas
- Goal-directed execution: Instead of using traditional true/false tests, Icon uses the success or failure of operations to control flow. If an operation succeeds, execution continues; if it fails, the next alternative is tried or the block ends. This makes many common tasks shorter and more direct when working with strings and patterns.
- Implicit flow control: Symbols like if, while, and until rely on the success of expressions rather than explicit Boolean results. The language can rewind to earlier states when a block fails, a concept known as backtracking.
- Generators: Icon treats procedures as potential value generators. They can return a single value, multiple values, or fail, which allows powerful iteration and data generation without writing explicit loops.
History and influence
Icon was developed after Griswold’s work on SNOBOL and SL5. He aimed to combine SNOBOL’s powerful string handling with more modern, readable syntax influenced by ALGOL-like languages. Icon led to an object-oriented extension called Idol, which evolved into Unicon. Icon’s generator style and pattern-driven text processing inspired Python’s approach to generating values and iterators.
Language features
- Syntax and typing: Icon uses a syntax reminiscent of languages like C and Pascal for structure, but it remains dynamically typed and typeless in practice. There is no separate Boolean type; success or failure of expressions drives decisions.
- Procedures and values: Programs are built from procedures that can return values. A procedure may return a single value, multiple values, or fail. A failure propagates through surrounding constructs, allowing compact, expressive code.
- Backtracking and reversibility: Icon supports backtracking. If a block fails, state can be reset to a previous point, using reversible assignments to undo changes when needed.
- Generators and suspend: Generators produce a sequence of values. The suspend keyword (and related suspend-like behavior) lets a generator pause and resume, enabling elegant iteration patterns.
- Alternators and bang syntax: The alternator concept lets you produce values by trying several tests in turn, similar to an or operation, but integrated with Icon’s generator mechanism. The bang syntax (!) is often used to output values from generators or to force evaluation of a generator step-by-step.
- Strings as first-class text: Strings are treated as lists of characters and are naturally processed with generators. Substrings and slices are supported, and strings can be accessed and modified using subscripting.
- Collections: Icon includes lists, tables (maps/dictionaries), sets, and other collection structures. These are often generators and can be manipulated succinctly with bang-style operations.
- String scanning: The ? operator creates a string-scanning environment where a subject string is passed to a chain of string operations, with the subject and current position tracked automatically. This makes advancing through text with multiple steps concise.
- Substrings and ranges: Strings can be sliced similarly to arrays, enabling powerful text extraction and substitution with compact syntax.
Examples in plain language
- A simple generator and output:
- A function f(x) that returns 1 if x > 0, otherwise it fails. If you call f(-1), you get a fail instead of a value.
- Reading and writing with implicit flow:
- a := read() then write(a) loops, stopping when read fails.
- Backtracking example:
- If a search pattern fails, the state can revert to its previous value automatically, avoiding manual undo code.
- Generating numbers:
- A small generator can yield numbers from i to j, returning each value in turn, and then fail when done.
- String scanning:
- Use the ? operator to pass a string into a chain of string operations, with the engine keeping track of where you are in the string.
Strings and text processing
Icon treats strings as lists of characters, enabling per-character processing with generators. Substrings and slices are first-class, and you can insert or delete parts of a string using subscripting. Scanning utilities allow you to walk through text, extract words, and handle patterns with compact, readable constructs.
Collections and data structures
Icon includes lists (which can act as stacks or queues), tables (maps), and sets. Tables use keys that aren’t necessarily integers, and sets provide standard set operations like union, intersection, and difference. These collections are often generators, making data processing concise and expressive.
Criticisms
- Icon’s reliance on success/fail rather than explicit Boolean logic can be confusing for programmers used to conventional true/false tests. The language also lacks a separate Boolean data type, which can lead to ambiguity in some cases.
- While powerful for pattern matching and string work, much of Icon’s default behavior is tied to generators, so non-generator code can behave differently or be less predictable to newcomers.
- The lack of exceptions in the traditional sense means certain error-handling patterns require different thinking than in many modern languages.
In summary
Icon stands out for its strong focus on strings and text, its goal-directed execution model, and its built-in support for generators and backtracking. It offers concise solutions to complex text-processing tasks and influenced later languages in the area of generator-based computation and pattern matching.
This page was last edited on 28 January 2026, at 20:14 (CET).