Icon is a
very high-level programming language
A very high-level programming language (VHLL) is a programming language with a very high level of abstraction, used primarily as a professional programmer productivity tool.
VHLLs are usually domain-specific languages, limited to a very specific ...
based on the concept of "goal-directed execution" in which an
expression in code returns "success" along with a result, or a "failure", indicating that there is no valid result. The success and failure of a given expression is used to direct further processing, whereas conventional languages would typically use
Boolean logic
In mathematics and mathematical logic, Boolean algebra is a branch of algebra. It differs from elementary algebra in two ways. First, the values of the variable (mathematics), variables are the truth values ''true'' and ''false'', usually denot ...
written by the programmer to achieve the same ends. Because the logic for basic control structures is often implicit in Icon, common tasks can be completed with less explicit code.
Icon was designed by
Ralph Griswold
Ralph E. Griswold (May 19, 1934, Modesto, CA – October 4, 2006, Tucson, AZ) was a computer scientist known for his research into high-level programming languages and symbolic computation. His language credits include the string processing la ...
after leaving
Bell Labs
Nokia Bell Labs, commonly referred to as ''Bell Labs'', is an American industrial research and development company owned by Finnish technology company Nokia. With headquarters located in Murray Hill, New Jersey, Murray Hill, New Jersey, the compa ...
where he was a major contributor to the
SNOBOL
SNOBOL ("StriNg Oriented and symBOlic Language") is a series of programming languages developed between 1962 and 1967 at AT&T Bell Laboratories by David J. Farber, Ralph Griswold and Ivan P. Polonsky, culminating in SNOBOL4. It was one of a ...
language. SNOBOL was a string-processing language with what would be considered dated syntax by the standards of the early 1970s. After moving to the
University of Arizona
The University of Arizona (Arizona, U of A, UArizona, or UA) is a Public university, public Land-grant university, land-grant research university in Tucson, Arizona, United States. Founded in 1885 by the 13th Arizona Territorial Legislature, it ...
, he further developed the underlying SNOBOL concepts in SL5, but considered the result to be a failure. This led to the significantly updated Icon, which blends the short but conceptually dense code of SNOBOL-like languages with the more familiar syntax of
ALGOL
ALGOL (; short for "Algorithmic Language") is a family of imperative computer programming languages originally developed in 1958. ALGOL heavily influenced many other languages and was the standard method for algorithm description used by the ...
-inspired languages like
C or
Pascal.
Like the languages that inspired it, the primary area of use of Icon is managing
strings
String or strings may refer to:
*String (structure), a long flexible structure made from threads twisted together, which is used to tie, bind, or hang other objects
Arts, entertainment, and media Films
* ''Strings'' (1991 film), a Canadian anim ...
and textual patterns. String operations often fail, for instance, finding "the" in "world". In most languages, this requires testing and branching to avoid using a non-valid result. In Icon most of these sorts of tests are simply unneeded, reducing the amount of code that must be written. Complex pattern handling can be done in a few lines of terse code, similar to more dedicated languages like
Perl
Perl is a high-level, general-purpose, interpreted, dynamic programming language. Though Perl is not officially an acronym, there are various backronyms in use, including "Practical Extraction and Reporting Language".
Perl was developed ...
but retaining a more function-oriented syntax familiar to users of other ALGOL-like languages.
Icon is not
object-oriented
Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impleme ...
, but an object-oriented extension named Idol was developed in 1996 which eventually became
Unicon
Unicon, previously known as UNICON, is the World unicycle, Unicycling Convention and Championships sanctioned by the International Unicycling Federation (IUF).
The IUF sanctions a biennial world unicycling convention and competition, the major e ...
. It also inspired other languages, with its simple generators being especially influential; Icon's generators were a major inspiration for the
Python
Python may refer to:
Snakes
* Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia
** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia
* Python (mythology), a mythical serpent
Computing
* Python (prog ...
language.
History
SNOBOL
The original
SNOBOL
SNOBOL ("StriNg Oriented and symBOlic Language") is a series of programming languages developed between 1962 and 1967 at AT&T Bell Laboratories by David J. Farber, Ralph Griswold and Ivan P. Polonsky, culminating in SNOBOL4. It was one of a ...
effort, retroactively known as SNOBOL1, launched in the fall of 1962 at the
Bell Labs
Nokia Bell Labs, commonly referred to as ''Bell Labs'', is an American industrial research and development company owned by Finnish technology company Nokia. With headquarters located in Murray Hill, New Jersey, Murray Hill, New Jersey, the compa ...
Programming Research Studies Department. The effort was a reaction to the frustrations of attempting to use the SCL language for polynomial formula manipulation, symbolic integration and studying
Markov chain
In probability theory and statistics, a Markov chain or Markov process is a stochastic process describing a sequence of possible events in which the probability of each event depends only on the state attained in the previous event. Informally ...
s. SCL, written by the department head Chester Lee, was both slow and had a low-level syntax that resulting in volumes of code for even simple projects. After briefly considering the COMIT language, Ivan Polonsky, Ralph Griswold and David Farber, all members of the six-person department, decided to write their own language to solve these problems.
The first versions were running on the
IBM 7090
The IBM 7090 is a second-generation Transistor computer, transistorized version of the earlier IBM 709 vacuum tube mainframe computer that was designed for "large-scale scientific and technological applications". The 7090 is the fourth member o ...
in early 1963, and by the summer had been built out and was being used across Bell. This led almost immediately to SNOBOL2, which added a number of built-in functions, and the ability to link to external
assembly language
In computing, assembly language (alternatively assembler language or symbolic machine code), often referred to simply as assembly and commonly abbreviated as ASM or asm, is any low-level programming language with a very strong correspondence bet ...
code. It was released in April 1964 and mostly used within Bell, but also saw some use at
Project MAC
Computer Science and Artificial Intelligence Laboratory (CSAIL) is a research institute at the Massachusetts Institute of Technology
The Massachusetts Institute of Technology (MIT) is a Private university, private research university in ...
. The introduction of system functions served mostly to indicate the need for user functions, which was the major feature of SNOBOL3, released in July 1964.
SNOBOL3's introduction corresponded with major changes within the Bell Labs computing department, including the addition of the new
GE 645
The GE 645 mainframe computer was a development of the GE 635 for use in the Multics project. This was the first computer that implemented a configurable hardware protected memory system. It was designed to satisfy the requirements of Project M ...
mainframe which would require a rewrite of SNOBOL. Instead, the team suggested writing a new version that would run on a
virtual machine
In computing, a virtual machine (VM) is the virtualization or emulator, emulation of a computer system. Virtual machines are based on computer architectures and provide the functionality of a physical computer. Their implementations may involve ...
, named SIL for SNOBOL Intermediate Language, allowing it to be easily ported to any sufficiently powerful platform. This proposal was accepted as SNOBOL4 in September 1965. By this time, plans for a significantly improved version of the language emerged in August 1966. Further work on the language continued throughout the rest of the 1960s, notably adding the
associative array
In computer science, an associative array, key-value store, map, symbol table, or dictionary is an abstract data type that stores a collection of (key, value) pairs, such that each possible key appears at most once in the collection. In math ...
type in later version, which they referred to as a table.
SL5 leads to Icon
Griswold left Bell Labs to become a professor at the
University of Arizona
The University of Arizona (Arizona, U of A, UArizona, or UA) is a Public university, public Land-grant university, land-grant research university in Tucson, Arizona, United States. Founded in 1885 by the 13th Arizona Territorial Legislature, it ...
in August 1971. He introduced SNOBOL4 as a research tool at that time. He received grants from the
National Science Foundation
The U.S. National Science Foundation (NSF) is an Independent agencies of the United States government#Examples of independent agencies, independent agency of the Federal government of the United States, United States federal government that su ...
to continue supporting and evolving SNOBOL.
As a language originally developed in the early 1960s, SNOBOL's syntax bears the marks of other early programming languages like
FORTRAN and
COBOL
COBOL (; an acronym for "common business-oriented language") is a compiled English-like computer programming language designed for business use. It is an imperative, procedural, and, since 2002, object-oriented language. COBOL is primarily ...
. In particular, the language is column-dependant, as many of these languages were entered on
punch card
A punched card (also punch card or punched-card) is a stiff paper-based medium used to store digital information via the presence or absence of holes in predefined positions. Developed over the 18th to 20th centuries, punched cards were wide ...
s where column layout is natural. Additionally, control structures were almost entirely based on branching around code rather than the use of
blocks, which were becoming a must-have feature after the introduction of
ALGOL 60
ALGOL 60 (short for ''Algorithmic Language 1960'') is a member of the ALGOL family of computer programming languages. It followed on from ALGOL 58 which had introduced code blocks and the begin and end pairs for delimiting them, representing a ...
. By the time he moved to Arizona, the syntax of SNOBOL4 was hopelessly outdated.
Griswold began the effort of implementing SNOBOL's underlying success/failure concept with traditional flow control structures like if/then. This became SL5, short for "SNOBOL Language 5", but the result was unsatisfying. In 1977, he returned to the language to consider a new version. He abandoned the very powerful function system introduced in SL5 with a simpler concept of suspend/resume and developed a new concept for the natural successor to SNOBOL4 with the following principles;
* SNOBOL4's philosophic and sematic basis
* SL5 syntactic basis
* SL5 features, excluding the generalized procedure mechanism
The new language was initially known as SNOBOL5, but as it was significantly different from SNOBOL in all but the underlying concept, a new name was ultimately desired. After considering "s" as a sort of homage to "C", but this was ultimately abandoned due to the problems with typesetting documents using that name. A series of new names were proposed and abandoned; Irving, bard, and "TL" for "The Language". It was at this time that
Xerox PARC
Future Concepts division (formerly Palo Alto Research Center, PARC and Xerox PARC) is a research and development company in Palo Alto, California. It was founded in 1969 by Jacob E. "Jack" Goldman, chief scientist of Xerox Corporation, as a div ...
began publishing about their work on
graphical user interface
A graphical user interface, or GUI, is a form of user interface that allows user (computing), users to human–computer interaction, interact with electronic devices through Graphics, graphical icon (computing), icons and visual indicators such ...
s and the term "icon" began to enter the computer lexicon. The decision was made to change the name initially to "icon" before finally choosing "Icon".
Language
Basic syntax
The Icon language is derived from the
ALGOL
ALGOL (; short for "Algorithmic Language") is a family of imperative computer programming languages originally developed in 1958. ALGOL heavily influenced many other languages and was the standard method for algorithm description used by the ...
-class of
structured programming Structured programming is a programming paradigm aimed at improving the clarity, quality, and development time of a computer program by making specific disciplined use of the structured control flow constructs of selection ( if/then/else) and repet ...
languages, and thus has syntax similar to
C or
Pascal. Icon is most similar to Pascal, using syntax for assignments, the keyword and similar syntax. On the other hand, Icon uses C-style braces for structuring execution groups, and programs start by running a procedure called .
In many ways Icon also shares features with most
scripting language
In computing, a script is a relatively short and simple set of instructions that typically automation, automate an otherwise manual process. The act of writing a script is called scripting. A scripting language or script language is a programming ...
s (as well as
SNOBOL
SNOBOL ("StriNg Oriented and symBOlic Language") is a series of programming languages developed between 1962 and 1967 at AT&T Bell Laboratories by David J. Farber, Ralph Griswold and Ivan P. Polonsky, culminating in SNOBOL4. It was one of a ...
and SL5, from which they were taken): variables do not have to be declared, types are cast automatically, and numbers can be converted to strings and back automatically. Another feature common to many scripting languages, but not all, is the lack of a line-ending character; in Icon, lines that do not end with a semicolon get ended by an implied semicolon if it makes sense.
Procedures are the basic building blocks of Icon programs. Although they use Pascal naming, they work more like C functions and can return values; there is no keyword in Icon.
procedure doSomething(aString)
write(aString)
end
Goal-directed execution
One of the key concepts in SNOBOL was that its functions returned the "success" or "failure" as primitives of the language rather than using
magic numbers or other techniques.
For example, a function that returns the position of a substring within another string is a common routine found in most language
runtime system
In computer programming, a runtime system or runtime environment is a sub-system that exists in the computer where a program is created, as well as in the computers where the program is intended to be run. The name comes from the compile time ...
s. In
JavaScript
JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.
Web browsers have ...
to find the position of the word "World" within a
"Hello, World!" program
A "Hello, World!" program is usually a simple computer program that emits (or displays) to the screen (often the Console application, console) a message similar to "Hello, World!". A small piece of code in most general-purpose programming languag ...
would be accomplished with , which would return 7 in the variable . If one instead asks for the the code will "fail", as the search term does not appear in the string. In JavaScript, as in most languages, this will be indicated by returning a magic number, in this case -1.
In SNOBOL a failure of this sort returns a special value, . SNOBOL's syntax operates directly on the success or failure of the operation, jumping to labelled sections of the code without having to write a separate test. For instance, the following code prints "Hello, world!" five times:
* SNOBOL program to print Hello World
I = 1
LOOP OUTPUT = "Hello, world!"
I = I + 1
LE(I, 5) : S(LOOP)
END
To perform the loop, the less-than-or-equal operator, , is called on the index variable I, and if it ucceeds, meaning I is less than 5, it branches to the named label and continues.
[
Icon retained the concept of flow control based on success or failure but developed the language further. One change was the replacement of the labelled -like branching with block-oriented structures in keeping with the ]structured programming Structured programming is a programming paradigm aimed at improving the clarity, quality, and development time of a computer program by making specific disciplined use of the structured control flow constructs of selection ( if/then/else) and repet ...
style that was sweeping the computer industry in the late 1960s. The second was to allow "failure" to be passed along the call chain so that entire blocks will succeed or fail as a whole. This is a key concept of the Icon language. Whereas in traditional languages one would have to include code to test the success or failure based on Boolean logic
In mathematics and mathematical logic, Boolean algebra is a branch of algebra. It differs from elementary algebra in two ways. First, the values of the variable (mathematics), variables are the truth values ''true'' and ''false'', usually denot ...
and then branch based on the outcome, such tests and branches are inherent to Icon code and do not have to be explicitly written.
For instance, consider this bit of code written in the Java programming language
Java is a high-level, general-purpose, memory-safe, object-oriented programming language. It is intended to let programmers ''write once, run anywhere'' ( WORA), meaning that compiled Java code can run on all platforms that support Jav ...
. It calls the function to read a character from a (previously opened) file, assigns the result to the variable , and then s the value of to another file. The result is to copy one file to another. will eventually run out of characters to read from the file, potentially on its very first call, which would leave in an undetermined state and potentially cause to cause a null pointer exception
In computing, a null pointer (sometimes shortened to nullptr or null) or null reference is a value saved for indicating that the pointer or reference does not refer to a valid object. Programs routinely use null pointers to represent conditions s ...
. To avoid this, returns the special value (end-of-file) in this situation, which requires an explicit test to avoid ing it:
while ((a = read()) != EOF)
In contrast, in Icon the function returns a line of text or . is not simply an analog of , as it is explicitly understood by the language to mean "stop processing" or "do the fail case" depending on the context. The equivalent code in Icon is:
while a := read() do write(a)
This means, "as long as read does not fail, call write, otherwise stop". There is no need to specify a test against the magic number as in the Java example, this is implicit, and the resulting code is simplified. Because success and failure are passed up through the call chain, one can embed function calls within others and they stop when the nested function call fails. For instance, the code above can be reduced to:
while write(read())
In this version, if the call fails, the call fails, and the stops. Icon's branching and looping constructs are all based on the success or failure of the code inside them, not on an arbitrary Boolean test provided by the programmer. performs the block if its "test" returns a value, and performs the block or moves to the next line if it returns . Likewise, continues calling its block until it receives a fail. Icon refers to this concept as goal-directed execution.
It is important to contrast the concept of success and failure with the concept of an exception; exceptions are unusual situations, not expected outcomes. Fails in Icon are expected outcomes; reaching the end of a file is an expected situation and not an exception. Icon does not have exception handling in the traditional sense, although fail is often used in exception-like situations. For instance, if the file being read does not exist, fails without a special situation being indicated. In traditional language, these "other conditions" have no natural way of being indicated; additional magic numbers may be used, but more typically exception handling is used to "throw" a value. For instance, to handle a missing file in the Java code, one might see:
try catch (Exception e)
This case needs two comparisons: one for EOF and another for all other errors. Since Java does not allow exceptions to be compared as logic elements, as under Icon, the lengthy syntax must be used instead. Try blocks also impose a performance penalty even if no exception is thrown, a distributed cost that Icon normally avoids.
Icon uses this same goal-directed mechanism to perform traditional Boolean tests, although with subtle differences. A simple comparison like does not mean, "if the conditional expression evaluation results in or returns a true value" as they would under most languages; instead, it means something more like, "if the conditional expression succeeds and does not fail". In this case, the operator succeeds if the comparison is true. The calls its clause if the expression succeeds, and either the (if present) or the next line if it fails. The result is similar to the traditional if/then seen in other languages, the performs if is less than . The subtlety is that the same comparison expression can be placed anywhere, for instance:
write(a < b)
Another difference is that the operator returns its second argument if it succeeds, which in this example will result in the value of being written if it is larger than , otherwise nothing is written. As this is not a test ''per se'', but an operator that returns a value, they can be strung together allowing things like , a common type of comparison that in most languages must be written as a conjunction of two inequalities like .
A key aspect of goal-directed execution is that the program may have to rewind to an earlier state if a procedure fails, a task known as ''backtracking''. For instance, consider code that sets a variable to a starting location and then performs operations that may change the value - this is common in string scanning operations for instance, which will advance a cursor through the string as it scans. If the procedure fails, it is important that any subsequent reads of that variable return the original state, not the state as it was being internally manipulated. For this task, Icon has the ''reversible assignment'' operator, , and the ''reversible exchange'', . For instance, consider some code that is attempting to find a pattern string within a larger string:
This code begins by moving to 10, the starting location for the search. However, if the fails, the block will fail as a whole, which results in the value of being left at 10 as an undesirable side effect
In medicine, a side effect is an effect of the use of a medicinal drug or other treatment, usually adverse but sometimes beneficial, that is unintended. Herbal and traditional medicines also have side effects.
A drug or procedure usually use ...
. Replacing with indicates that should be reset to its previous value if the block fails. This provides an analog of atomicity in the execution.
Generators
Expressions in Icon may return a single value, for instance, will evaluate and return x if the value of x is less than 5, otherwise it will fail and return no value. Icon also includes the concept of procedures that do not ''immediately'' return success or failure, and instead return new values every time they are called. These are known as ''generators'', and are a key part of the Icon language. Within the parlance of Icon, the evaluation of an expression or function produces a ''result sequence''. A result sequence contains all the possible values that can be generated by the expression or function. When the result sequence is exhausted, the expression or function fails.
Icon allows any procedure to return a single value or multiple values, controlled using the , and keywords. A procedure that lacks any of these keywords returns , which occurs whenever execution runs to the of a procedure. For instance:
procedure f(x)
if x > 0 then
end
Calling will return 1, but calling will return . This can lead to non-obvious behavior, for instance, will output nothing because fails and suspends operation of .
Converting a procedure to be a generator uses the keyword, which means "return this value, and when called again, start execution at this point". In this respect it is something like a combination of the concept in C and . For instance:
procedure ItoJ(i, j)
while i <= j do
fail
end
creates a generator that returns a series of numbers starting at and ending a , and then returns after that. The stops execution and returns the value of without reseting any of the state. When another call is made to the same function, execution picks up at that point with the previous values. In this case, that causes it to perform , loop back to the start of the while block, and then return the next value and suspend again. This continues until fails, at which point it exits the block and calls . This allows iterator
In computer programming, an iterator is an object that progressively provides access to each item of a collection, in order.
A collection may provide multiple iterators via its interface that provide items in different orders, such as forwards ...
s to be constructed with ease.
Another type of generator-builder is the ''alternator'', which looks and operates like the Boolean operator. For instance:
if y < (x , 5) then write("y=", y)
This appears to say "if y is smaller than x or 5 then...", but is actually a short-form for a generator that returns values until it falls off the end of the list. The values of the list are "injected" into the operations, in this case, . So in this example, the system first tests y < x, if x is indeed larger than y it returns the value of x, the test passes, and the value of y is written out in the clause. However, if x is not larger than y it fails, and the alternator continues, performing y < 5. If that test passes, y is written. If y is smaller than neither x or 5, the alternator runs out of tests and fails, the fails, and the is not performed. Thus, the value of y will appear on the console if it is smaller than x or 5, thereby fulfilling the purpose of a Boolean . Functions will not be called unless evaluating their parameters succeeds, so this example can be shortened to:
write("y=", (x , 5) > y)
Internally, the alternator is not simply an and one can also use it to construct arbitrary lists of values. This can be used to iterate over arbitrary values, like:
every i := (1, 3, 4, 5, 10, 11, 23) do write(i)
As lists of integers are commonly found in many programming contexts, Icon also includes the keyword to construct ''ad hoc'' integer generators:
every k := i to j do write(k)
which can be shortened:
every write(1 to 10)
Icon is not strongly typed, so the alternator lists can contain different types of items:
every i := (1 , "hello" , x < 5) do write(i)
This writes 1, "hello" and maybe 5 depending on the value of x.
Likewise the ''conjunction operator'', , is used in a fashion similar to a Boolean operator:
every x := ItoJ(0,10) & x % 2 0 do write(x)
This code calls and returns an initial value of 0 which is assigned to x. It then performs the right-hand side of the conjunction, and since does equal 0, it writes out the value. It then calls the generator again which assigns 1 to x, which fails the right-hand-side and prints nothing. The result is a list of every even integer from 0 to 10.
The concept of generators is particularly useful and powerful when used with string operations, and is a major underlying basis for Icon's overall design. Consider the operation found in many languages; this function looks for one string within another and returns an index of its location, or a magic number if it is not found. For instance:
s = "All the world's a stage. And all the men and women merely players";
i = indexOf("the", s);
write(i);
This will scan the string , find the first occurrence of "the", and return that index, in this case 4. The string, however, contains two instances of the string "the", so to return the second example an alternate syntax is used:
j = indexOf("the", s, i + 1);
write(j);
This tells it to scan starting at location 5, so it will not match the first instance we found previously. However, there may not be a second instance of "the" -there may not be a first one either- so the return value from has to be checked against the magic number -1 which is used to indicate no matches. A complete routine that prints out the location of every instance is:
s = "All the world's a stage. And all the men and women merely players";
i = indexOf("the", s);
while i != -1
In Icon, the equivalent is a generator, so the same results can be created with a single line:
s := "All the world's a stage. And all the men and women merely players"
every write(find("the", s))
Of course there are times where one does want to find a string after some point in input, for instance, if scanning a text file that contains a line number in the first four columns, a space, and then a line of text. Goal-directed execution can be used to skip over the line numbers:
every write(5 < find("the", s))
The position will only be returned if "the" appears after position 5; the comparison will fail otherwise, pass the fail to write, and the write will not occur.
The operator is similar to , looping through every item returned by a generator and exiting on failure:
every k := i to j do
write(someFunction(k))
There is a key difference between and ; re-evaluates the first result until it fails, whereas fetches the next value from a generator. actually injects values into the function in a fashion similar to blocks under Smalltalk
Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
. For instance, the above loop can be re-written this way:
every write(someFunction(i to j))
In this case, the values from i to j will be injected into and (potentially) write multiple lines of output.
Collections
Icon includes several collection types including lists
A list is a set of discrete items of information collected and set forth in some format for utility, entertainment, or other purposes. A list may be memorialized in any number of ways, including existing only in the mind of the list-maker, but ...
that can also be used as stacks and queues, tables (also known as maps or dictionaries in other languages), sets and others. Icon refers to these as ''structures''. Collections are inherent generators and can be easily called using the bang syntax. For instance:
lines := [] # create an empty list
while line := read() do
while line := pop(lines) do
Using the fail propagation as seen in earlier examples, we can combine the tests and the loops:
lines := [] # create an empty list
while push(lines, read()) # push until empty
while write(pop(lines)) # write until empty
Because the list collection is a generator, this can be further simplified with the bang syntax:
lines := []
every push(lines, !&input)
every write(!lines)
In this case, the bang in causes Icon to return a line of text one by one from the array and finally fail at the end. is a generator-based analog of that reads a line from standard input
In computer programming, standard streams are preconnected input and output communication channels between a computer program and its environment when it begins execution. The three input/output (I/O) connections are called standard input (stdin), ...
, so continues reading lines until the file ends.
As Icon is typeless, lists can contain any different types of values:
aCat := muffins", "tabby", 2002, 8/syntaxhighlight>
The items can included other structures. To build larger lists, Icon includes the generator; generates a list containing 10 copies of "word". Like arrays in other languages, Icon allows items to be looked up by position, e.g., . Array slicing
In computer programming, array slicing is an operation that extracts a subset of elements from an array and packages them as another array, possibly in a different dimension from the original.
Common examples of array slicing are extracting a ...
is included, allowing new lists to be created out of the elements of other lists, for instance, produces a new list called aCat that contains "tabby" and 2002.
Tables are essentially lists with arbitrary index keys rather than integers:
symbols := table(0)
symbols there":= 1
symbols here":= 2
This code creates a table that will use zero as the default value of any unknown key. It then adds two items into the table, with the keys "there" and "here", and values 1 and 2.
Sets are also similar to lists but contain only a single member of any given value. Icon includes the to produce the union of two sets, the intersection, and the difference. Icon includes a number of pre-defined "Cset"s, a set containing various characters. There are four standard Csets in Icon, , , , and . New Csets can be made by enclosing a string in single quotes, for instance, .
Strings
In Icon, strings are lists of characters. As a list, they are generators and can thus be iterated over using the bang syntax:
every write(!"Hello, world!")
Will print out each character of the string on a separate line.
Substrings can be extracted from a string by using a range specification within brackets. A range specification can return a point to a single character, or a slice of the string. Strings can be indexed from either the right or the left. Positions within a string are defined to be between the characters 1A2B3C4 and can be specified from the right −3A−2B−1C0
For example,
"Wikipedia" > "W"
"Wikipedia" > "k"
"Wikipedia" > "a"
"Wikipedia" :3 > "Wi"
"Wikipedia" 2:0 > "ia"
"Wikipedia" +:3 > "iki"
Where the last example shows using a length instead of an ending position
The subscripting specification can be used as a lvalue within an expression. This can be used to insert strings into another string or delete parts of a string. For example:
s := "abc"
s := "123"
s now has a value of "a123c"
s := "abcdefg"
s :5:= "ABCD"
s now has a value of "abABCDefg"
s := "abcdefg"
s :5:= ""
s now has a value of "abefg"
String scanning
A further simplification for handling strings is the ''scanning'' system, invoked with , which calls functions on a string:
s ? write(find("the"))
Icon refers to the left-hand-side of the as the ''subject'', and passes it into string functions. Recall the takes two parameters, the search text as parameter one and the string to search in parameter two. Using the second parameter is implicit and does not have to be specified by the programmer. In the common cases when multiple functions are being called on a single string in sequence, this style can significantly reduce the length of the resulting code and improve clarity. Icon function signatures identify the subject parameter in their definitions so the parameter can be hoisted in this fashion.
The is not simply a form of syntactic sugar, it also sets up a "string scanning environment" for any following string operations. This is based on two internal variables, and ; is simply a pointer to the original string, while is the current position within it, or cursor. Icon's various string manipulation procedures use these two variables so they do not have to be explicitly supplied by the programmer. For example:
s := "this is a string"
s ? write("subject= ,&subject," pos= ,&pos,")
would produce:
subject= his is a string pos=
Built-in and user-defined functions can be used to move around within the string being scanned. All of the built-in functions will default to and to allow the scanning syntax to be used. The following code will write all blank-delimited "words" in a string:
s := "this is a string"
s ?
There are a number of new functions introduced in this example. returns the current value of . It may not be immediately obvious why one would need this function and not simply use the value of directly; the reason is that is a variable and thus cannot take on the value , which the procedure can. Thus provides a lightweight wrapper on that allows Icon's goal-directed flow control to be easily used without having to provide hand-written Boolean tests against . In this case, the test is "is &pos zero", which, in the odd numbering of Icon's string locations, is the end of the line. If it is ''not'' zero, returns , which is inverted with the and the loop continues.
finds one or more examples of the provided Cset parameter starting at the current . In this case, it is looking for space characters, so the result of this function is the location of the first non-space character after . moves to that location, again with a potential in case, for instance, falls off the end of the string. is essentially the reverse of ; it returns the location immediately prior to its provided Cset, which the example then sets the to with another . Alternation is used to also stop at the end of a line.
This example can be made more robust through the use of a more appropriate "word breaking" Cset which might include periods, commas and other punctuation, as well as other whitespace characters like tab and non-breaking spaces. That Cset can then be used in and .
A more complex example demonstrates the integration of generators and string scanning within the language.
procedure main()
s := "Mon Dec 8"
s ? write(Mdate() , "not a valid date")
end
# Define a matching function that returns
# a string that matches a day month dayofmonth
procedure Mdate()
# Define some initial values
static dates
static days
initial
every suspend (retval <- tab(match(!days)) , , # Match a day
=" " , , # Followed by a blank
tab(match(!months)) , , # Followed by the month
=" " , , # Followed by a blank
matchdigits(2) # Followed by at least 2 digits
) &
(=" " , pos(0) ) & # Either a blank or the end of the string
retval # And finally return the string
end
# Matching function that returns a string of n digits
procedure matchdigits(n)
suspend (v := tab(many(&digits)) & *v <= n) & v
end
Criticisms
Laurence Tratt wrote a paper on Icon examining its real-world applications and pointing out a number of areas of concern. Among these were a number of practical decisions that derive from their origins in string processing but do not make as much sense in other areas. Among them:
The decision to fail by default at the end of procedures makes sense in the context of generators, but less so in the case of general procedures. Returning to the example noted above, will not output which may be expected. However:
x := 10
(additional lines)
x := f(-1)
write(x)
will result in 10 being printed. This sort of issue is not at all obvious as even in an interactive debugger all the code is invoked yet never picks up the expected value. This could be dismissed as one of those "gotchas" that programmers have to be aware of in any language, but Tratt examined a variety of Icon programs and found that the vast majority of procedures are not generators. This means that Icon's default behaviour is only used by a tiny minority of its constructs, yet represents a major source of potential errors in all the others.
Another issue is the lack of a Boolean data type and conventional Boolean logic. While the success/fail system works in most cases where the ultimate goal is to check a value, this can still lead to some odd behaviour in seemingly simple code:
procedure main()
if c then
end
This program will print "taken". The reason is that the test, , does return a value; that value is , the default value for all otherwise uninitiated variables. is a valid value, so succeeds. To test this, one needs to make the test explicit, . Tratt supposed that it detracts from the self-documenting code, having supposed erroneously that it is testing "is c zero" or "does c exist".
See also
*Coroutine
Coroutines are computer program components that allow execution to be suspended and resumed, generalizing subroutines for cooperative multitasking. Coroutines are well-suited for implementing familiar program components such as cooperative task ...
Notes
References
Citations
Bibliography
*
*
*
*
*
*
External links
*
*
Oral history interview with Stephen Wampler
Charles Babbage Institute
The IT History Society (ITHS) is an organization that supports the history and scholarship of information technology by encouraging, fostering, and facilitating archival and historical research. Formerly known as the Charles Babbage Foundation, ...
, University of Minnesota. Wampler discusses his work on the development Icon in the late 1970s.
Oral history interview with Robert Goldberg
Charles Babbage Institute
The IT History Society (ITHS) is an organization that supports the history and scholarship of information technology by encouraging, fostering, and facilitating archival and historical research. Formerly known as the Charles Babbage Foundation, ...
, University of Minnesota. Goldberg discusses his interaction with Griswold when working on Icon in the classroom at Illinois Institute of Technology
The Illinois Institute of Technology, commonly referred to as Illinois Tech and IIT, is a Private university, private research university in Chicago, Illinois, United States. Tracing its history to 1890, the present name was adopted upon the m ...
.
Oral history interview with Kenneth Walker
Charles Babbage Institute
The IT History Society (ITHS) is an organization that supports the history and scholarship of information technology by encouraging, fostering, and facilitating archival and historical research. Formerly known as the Charles Babbage Foundation, ...
, University of Minnesota. Walker describes the work environment of the Icon project, his interactions with Griswold, and his own work on an Icon compiler.
The Icon Programming Language page
on The Rosetta Code comparative programming tasks project site
{{Authority control
Dynamically typed programming languages
Icon programming language family
Pattern matching programming languages
Public-domain software
SNOBOL programming language family
Text-oriented programming languages
Programming languages created in 1977