Icon
A high-level programming language with novel features for string processing and goal-directed evaluation
Created by Ralph Griswold
Icon is a high-level programming language designed by Ralph Griswold at the University of Arizona, first conceived in 1977. It’s famous for its innovative approach to expression evaluation and its powerful string-processing facilities, inherited from its predecessor SNOBOL but wrapped in a more conventional syntax.
History & Origins
Ralph Griswold was one of the principal designers of SNOBOL at Bell Labs in the 1960s. When he moved to the University of Arizona, he wanted to create a new language that preserved SNOBOL’s powerful pattern matching while using a more modern, structured syntax.
From SNOBOL to Icon
SNOBOL (StriNg Oriented and symBOlic Language) was revolutionary for its time, offering pattern matching capabilities far beyond other languages. However, its syntax was unusual - more like assembly language than the structured languages emerging in the 1970s.
Griswold first created SL5 (SNOBOL Language 5) as an intermediate step, but found the result unsatisfying. In 1977, he returned to the drawing board with a fresh approach that became Icon. The name “Icon” is not an acronym - it was chosen partly because “iconoclastic” described the language’s unconventional approach to programming.
Development and Evolution
Icon was developed primarily at the University of Arizona by faculty, staff, and students, with contributions from volunteers worldwide. The language went through several major versions:
- Version 2-5 (late 1970s): Early development and refinement
- Version 6-7 (1980s): Stability and wider adoption
- Version 8 (1990): Major performance improvements
- Version 9 (1990s-present): Modern maintenance
After Griswold’s death in 1999, the language has been maintained by Gregg Townsend and a dedicated community.
Core Concepts
Goal-Directed Evaluation
Icon’s most distinctive feature is goal-directed evaluation. Unlike most languages where expressions simply compute values, Icon expressions can succeed (producing a value) or fail (producing no value). This success/failure mechanism drives control flow.
# This fails if x is negative, succeeds otherwise
x > 0
# In an if statement, the condition's success/failure determines the branch
if x > 0 then write("positive") else write("not positive")
Generators
Icon introduced the concept of generators - expressions that can produce multiple values. When a generator is used in a context that can accept multiple values, Icon automatically iterates through all possibilities.
# Generate integers 1 to 10
every write(1 to 10)
# Find all vowels in a string
every write(find("aeiou", s))
This influenced Python’s generators and iterator protocol, which were partially inspired by Icon.
String Scanning
Icon provides a powerful string scanning facility that makes text processing elegant and concise:
s := "Hello, World!"
s ? {
tab(find(",")) # Move to comma
move(2) # Skip ", "
write(tab(0)) # Write rest: "World!"
}
The ? operator enters scanning mode, where special functions like tab(), move(), and find() operate on the subject string.
Language Features
Data Types
Icon has a rich set of built-in types:
- Numeric: integers (arbitrary precision), real numbers
- String: character strings of any length
- Lists: ordered, mutable sequences
- Sets: unordered collections with unique elements
- Tables: associative arrays (hash tables)
- Records: user-defined structured types
- Co-expressions: encapsulated computations
Automatic Type Conversion
Icon automatically converts between types when needed:
x := "42"
y := x + 8 # y is 50 (string converted to integer)
s := "Value: " || y # s is "Value: 50" (integer converted to string)
Control Structures
Icon provides familiar control structures, but they work with success/failure:
# If-then-else
if expr then action1 else action2
# While loop - runs while expr succeeds
while expr do action
# Every - processes all values from a generator
every expr1 do action
# Repeat - infinite loop (use break to exit)
repeat action
The Every Expression
The every expression is particularly powerful, allowing you to iterate through all values of a generator:
# Print all elements of a list
every write(!L)
# Find all occurrences of a pattern
every i := find("the", text) do
write("Found at position ", i)
# Complex generation
every i := 1 to 10 & j := 1 to 10 do
write(i, " x ", j, " = ", i * j)
List Operations
Lists in Icon are versatile:
L := [1, 2, 3, 4, 5] # Create a list
push(L, 0) # Add to front: [0, 1, 2, 3, 4, 5]
put(L, 6) # Add to end: [0, 1, 2, 3, 4, 5, 6]
x := pop(L) # Remove from front: x = 0
y := pull(L) # Remove from end: y = 6
write(!L) # Write each element
Unique Features
Failure is Not an Error
In Icon, failure is a normal part of expression evaluation, not an error condition:
# This doesn't cause an error if "needle" isn't found
if find("needle", haystack) then
write("Found it!")
else
write("Not found")
Reversible Assignment
Icon supports reversible assignment for backtracking:
s := "test"
s ? if tab(match("test")) then write("matched") else write("no match")
Co-expressions
Co-expressions are first-class objects that encapsulate a computation:
counter := create (seq()) # Create infinite sequence generator
@counter # Activate: returns 1
@counter # Returns 2
@counter # Returns 3
Icon Program Library (IPL)
The IPL is an extensive collection of Icon programs and procedures covering:
- String and text processing
- Data structure manipulation
- Mathematical functions
- Graphics operations
- System interfaces
- And much more
The IPL demonstrates Icon’s expressiveness and provides reusable components for common tasks.
Icon vs Other Languages
Compared to Perl/Python for Text Processing
Icon’s string scanning is more declarative than regular expressions:
# Icon: Extract items from "key=value,key=value"
s ? while key := tab(find("=")) do {
move(1)
value := tab(find(",") | 0)
move(1)
write(key, ": ", value)
}
Compared to Prolog for Backtracking
Icon’s backtracking is more limited than Prolog’s (it’s depth-first within expressions), but it’s integrated more naturally into imperative code:
# Icon: Find first solution
if x := find_solution() then use(x)
# Icon: Find all solutions
every x := find_solution() do use(x)
Modern Status
Icon development has slowed but not stopped:
- Icon 9.5: The current stable version, maintained by Gregg Townsend
- Unicon: An object-oriented extension of Icon with additional modern features
- Debian/Ubuntu: Icon is packaged in major Linux distributions
The source code is available on GitHub, and the language continues to have a small but dedicated community.
The Griswold Legacy
Ralph Griswold’s work on SNOBOL and Icon influenced programming language design in ways that continue today:
- Pattern Matching: Icon’s approach influenced pattern matching in modern languages
- Generators: Python’s generators were inspired by Icon
- Goal-Directed Evaluation: Influenced constraint programming and logic programming integration
- High-Level String Processing: Set the standard for text manipulation in high-level languages
Icon represents a road less traveled in language design - where failure is a first-class concept and expressions can naturally produce multiple values. While it never achieved mainstream popularity, its ideas have quietly influenced many modern language features.
Learning Resources
Online
- Icon Homepage - https://www2.cs.arizona.edu/icon/
- Icon on GitHub - https://github.com/gtownsend/icon
- Unicon Project - http://unicon.org/
Books
- The Icon Programming Language by Griswold and Griswold (Third Edition, 1996)
- Graphics Programming in Icon by Griswold, Jeffery, and Townsend
Why Learn Icon?
Even if you never use Icon in production:
- Different Perspective: Goal-directed evaluation will change how you think about control flow
- Generator Understanding: Icon’s generators predate Python’s and help understand the concept
- Elegant Text Processing: String scanning offers an alternative to regex that some find more readable
- Historical Appreciation: Understanding Icon helps appreciate features in modern languages
Icon is a window into an alternative history of programming - one where backtracking and multiple-valued expressions are natural parts of the language rather than special libraries.
Timeline
Notable Uses & Legacy
Text Processing
Icon's powerful string scanning and pattern matching made it popular for natural language processing and text analysis.
Rapid Prototyping
The combination of high-level abstractions and goal-directed evaluation made Icon excellent for quickly developing complex algorithms.
Education
Used in computer science education to teach programming concepts like generators and backtracking.
Compiler Research
Icon was used extensively in compiler and language research due to its unique evaluation model.
Document Processing
The Icon Program Library (IPL) includes extensive tools for document formatting and analysis.
Language Influence
Influenced By
Influenced
Running Today
Run examples using the official Docker image:
docker pull codearchaeology/icon:latestExample usage:
docker run --rm -v $(pwd):/app -w /app codearchaeology/icon:latest sh -c "icont hello.icn && ./hello"