Icon Programming
A Wikibookian believes this page should be split into smaller pages with a narrower subtopic. You can help by splitting this big page into smaller ones. Please make sure to follow the naming policy. Dividing books into smaller sections can provide more focus and allow each one to do one thing well, which benefits everyone. |
Introduction
editIcon - What is this?
editIcon is a modern high-level programming language. It provides many useful features for managing data, generators and much more. It is not object-oriented, but the UN-icon variant, UNICON, is object-oriented as is ObjectIcon (code.google.com/p/objecticon)
Hello world
editHere is a tiny but complete Icon program.
procedure main() write("Hello world!") end
As you see, the code is very simple. Lines procedure main() and end enclose the body of the program. The second line is responsible for printing Hello world! on your standard output (usually screen). Naturally, procedure write prints the string which is given as a parameter. There is a similar procedure read which reads a line from standard input (usually keyboard).
Compiling and running
editSave the program from the previous section to file helloworld.icn. Type
icont helloworld.icn
in linux shell. The executable file named helloworld will be generated. You can run it now.
Basic syntax
editThe program consists of procedures. Every procedure begins with procedure reserved word followed by the name of the procedure and list of arguments (it can be empty). The procedure ends with end. All the instructions are separated by newline or semicolon.
There must be a main procedure which is called automatically when user runs the program.
procedure p1(arg1, arg2, arg3) instr1 instr2 end procedure p2() instr1; instr2 end procedure main(arg) instr1 instr2 instr3 end
If you want to put a comment into your code, use # character. All the text in the line after that character is discarded by the compiler.
Variables
editAbout variables in Icon
editVariables in Icon have no type and can contain value of any data type. That means you can for example assign a number to one of your variables and assign a string to it few instructions later.
There is no need to declare variables (except global ones), they are created when they are used for the first time. There is no need to destroy them too, because there is a garbage collector doing it automatically.
Assigning value to variable
editTo assign value to variable use Pascal-like := operator:
procedure main() x := 1 # assigns 1 to variable x y := 3 # assigns 3 to variable y x := x + y # assigns 4 (1+3) to variable x y := "example string" # assigns string "example string" to variable y end
Global variables
editNumbers
editStrings
editIntroduction to strings in Icon
editA string is a sequence of characters. You can easily put string constants into your code, enclosing them with pair of " characters. For example:
str := "abcdefgh"
will create a string constant containing 8 characters and assign this string to str variable.
Accessing characters and substrings
editCharacters in strings are indexed in a very convenient way. As in Pascal, 1 points to the place before the first character, 2 to the place between the first and the second etc. Unlike many other languages, strings are indexed from the end too. 0 points to the place after the last character, -1 to the place before the last character, etc.
To access the part of the string you want, use the brackets [ ] operator:
- variablename[from:to]
- variablename[index]
The first method returns a substring placed between points pointed by from and to. If you place only one number in the brackets, it is equivalent to variablename[index:index+1].
str := "sample string" str[1:7] := "SAMPLE" # str := "SAMPLE string" str[3] := "m" # str := "SAmPLE string" write(str[8:0]) # write("string")
Special characters
editOperators
edit- *str - produces the length of str
- ?str - produces the random one-character substring of str
- !str - generates the sequence of one-character substrings of str
- str1 || str2 - concatenates two strings:
str := "Hello" || " " || "world" # str := "Hello world" str ||:= "!" # str := "Hello world!"
- strings case-sensitively comparison:
- str1 == str2 - produces str2 if those strings are equal, fails otherwise
- str1 ~== str2 - produces str2 if those strings are not equal, fails otherwise
- str1 << str2 - produces str2 if it is greater than str1, fails otherwise
- str1 <<= str2 - produces str2 if it is greater or equal than str1, fails otherwise
- str1 >> str2 - produces str2 if it is less than str1, fails otherwise
- str1 >>= str2 - produces str2 if it is less or equal than str1, fails otherwise
- str ? expr - sets str as &subject for expr expression
String scanning
editLists
editOverview of lists
editLists are similar to strings, although they are able to contain much more various data. Like strings, lists are indexed from the beginning and from the end (read the Accessing characters and substrings section related to strings).
List creation
editYou can create list constants enclosing its elements with brackets and separating them with , character. For example:
lst := [1, "hello", 44]
creates three-element list constant and assigns it to the lst variable. To create empty list do not put anything between brackets:
lst := [] # lst value is now an empty list
There is a special function for creating lists of desired length:
- list (i,x)
i-element list is created and all its elements are initialized with x value. By default i is 0 and x is &null.
list(5, 7) # [7, 7, 7, 7, 7] list(3, "text") # ["text", "text", "text"] list(6) # [&null, &null, &null, &null, &null, &null] list() # []
Operators
editArrays
editThere are no arrays in Icon. Use lists instead. If you need multi-dimensional arrays, use lists of lists.
matrix := list(3) # makes a list of 3 rows every !matrix := list(5, 0) # each a different list of 5 zeroes matrix[2][4] +:= 5 # adds 5 to the element # in 2nd row and 4th column every write(!!matrix) # writes all the elements
Stack and queue
editVery useful functions are given to manage stacks and queues as lists.
- push(list, elem) - adds elem to the list list at its beginning.
- pop(list) - produces the first element of list and removes it from list or fails if list is empty.
- put(list, elem) - adds elem to the end of list.
- get(list) - produces the first element of list and removes it from list or fails if list is empty, it is identical to pop.
- pull(list) - produces the last element of list and removes it from list or fails if list is empty.
queue := [] # creates an empty queue put(queue, 1) # puts 1 into the queue put(queue, "it is a string") # puts "it is a string" into the queue write(get(queue)) # writes 1 write(get(queue)) # writes "it is a string" # queue is now empty stack := [] # creates an empty stack put(stack, 1) # puts 1 into the stack put(stack, "it is a string") # puts "it is a string" into the stack write(get(stack)) # writes "it is a string" write(get(stack)) # writes 1 # stack is now empty write(*queue) # writes length of the queue
Characters sets
editTables
editRecord types
editRecord type declaration
editTo declare record type use record reserved word, for example:
record person(firstname, lastname, age)
Construction of the record variable
editWhen you declare a record, a constructor for it is defined automatically. A constructor is a procedure, which arguments are initial values for record fields and returns the created record. The constructor 's name is the same as record's.
record person(firstname, lastname, age) # declaration of person record jd := person("John", "Doe", 47) # create and assign record value
Operators
edit- rec.fieldname - produces a value of the fieldname field of the rec record
- *rec - produces a number of fields of the rec record
- ?rec - produces a value of a random field of the rec record
- !rec - generates values of all fields of the rec record
Procedures
editA procedure which forms part of the Icon language is conventionally referred to as a "function". A function which is added by the user as part of a program are referred to as a "procedure". A procedure may have a return value by preceding an identifier with the reserved word "return".
#example of the use of the reserved word return
procedure ex-ret(var1, _Var2)
b := "a_proc succeeded"
if a_proc(var1) then return b else c_proc(_Var2)
end
Generators
editGenerators, which are so fundamental to newer languages such as Ruby and Python, were first used in ICON shortly after CLU.
Goal-directed execution
editMany ICON expressions are called "conditional expressions" and their evaluation results in success or failure. Three important examples are
read(res) find( Str_target, Str_source) match( Str_target, Str_source)
Comparison operators form expressions which succeed or fail such as
write(count > 0)
If count is not greater than zero then the comparison in the conditional expression fails; without an expression, the enclosing expression which is a call to the function write(), is never evaluated and in that sense, inherits the failure of the conditional expression. By way of comparison
b := "paused" if count > 0 then b := "running" write(b) # will write "paused"
Goal-directed execution is not the very basis of Icon as it is in , say, Prolog. Icon is rather more like Oz, where backtracking is an option. In Icon, backtracking is available, but within the limits of a particular context. ICON also has the concept of "data backtracking"