Icon Introduction

by "Blag" - Senior Developer Evangelist

Return to Geeky Thursday

What is Icon?


Very high-level programming language featuring goal-directed execution.


Released on 1977.


Related to Snobol and SL5.


Syntax similar to Pascal.


How to install Icon


Download from here


and follow the instructions

Who uses Icon?


  • University of Arizona (They invented it)
  • Some enthusiastic people...

Starting out...


Best to my knowledge..Icon doesn't have a REPL :(

Anyways...simply type "icon"

Comments


Comments are very simple

				
# This is a comment
				

Variables


There's no data type declaration...


The data type changes based on its value


Although you need to specify "local" for most variabes

				
procedure main()

    local myVar
   
    myVar := "Blag"
    
    write(myVar)
    
    myVar := 42
    
    write(myVar)
    
end
				

Success and Failure


In Icon an operation can success or fail.

If something fails, nothing happens.

				
procedure main()

    local myVar
    
    myVar := 5
    
    if myVar > 10 then
    
        write("Biggger")
        
end
				

This is important, because the program will not crash

Simply...it will do nothing...

Loops

Icon provides a couple of different loop constructions

				
procedure main()

    local i
    
    every i := 1 to 5 do
    
        write(i)
		
		
    while i < 10 do {
		
        write(i)
        
        i +:= 1
        
    }
	
	
    repeat{
		
        write(i)
        
        i +:= 1
        
        if(i > 15) then break
        
    }
    
end
				

Functions


Function are very important...that's true for every programming language...

				
procedure sum(a, b)

    return a + b 
    
end


procedure main()

    write(sum(2, 30))
    
end
				

Arrays


There's no arrays...but Lists, Records and Tables...

				
procedure main()

    local myList, i
    
    
    myList := ["Blag", 42, "Icon"]
    
	
    myList |||:= ["AFI"]
	
	
    every i := 1 to *myList do
    
        write(myList[i])	
        
end
				

Lists can have different variable types.

We use "*" to the size of a variable or list.

Tables


Tables allow us to define our own indices

				
procedure main()

    local tab
    
    tab := table()
    
    tab["a"] := 1
    
    tab["b"] := 1    
    
    tab["a"] +:= 1
    
    write(tab["a"])	
    
end
				

We create a table and assign two indices with values.

We add the value on one of the indices.

We print the value.

Records


Records allow us to define members

				
record person(name, age, band)

	
procedure main()

    local people
    
    people := person("Blag", 42, "AFI")
    
    write(people.name)    
    
end
				

We create a table and assign two indices with values.

We add the value on one of the indices.

We print the value.

Strings


We have some nice functions for string manipulation.

				
procedure main()

    write("This is " || "Icon")
    
    write(repl("Blag",3))
    
    write(map("Blag","a","A"))
    
    write(reverse("Blag"))
    
    write(center("Blag", 10, "*"))
    
end 
				

Concatenation, repetition, replacement, reverse and fill...

Co-Expressions


Captures an expression so that it can be resumed at anytime and place.

				
procedure main()

    local bands
    
    bands := create("AFI"|"Sex Pistols"|"DHC")
    

    while write(@bands)
    
end
				

Every time @bands is called, a new band will be displayed

Fibonacci list sequence


Finally...we're going to make our first application...


Name your file "Fibonacci.sno"


we can run it by calling icon nameoffile.icn


				
procedure fib(num, a, b)

    local result
    
    result := ""
    
    if a > 0 & num > 1 then
    
        result := result || " " || (a + b) || 
        
                  fib(num - 1, a + b, a)
        
    else if a = 0 then
    
        result := a || " " || b || " " || 
        
                  (a + b) || fib(num - 1, a + b, b)
        
    return result
    
end
				
				
procedure main()

    local num
    
    write("Enter a number: ")
    
    num := read()
    
    write(" ")
    
    write(fib(num, 0, 1))
end 
				

When we run it we're going to see...


Making an LCD Number App


This is my favorite application of all time...


Name your file "LED_Numbers.icn"


				
procedure main()

    local leds, num, line1, line2, line3
    
    local i, j
    
    i := 1
    
    j := 2
    
    line1 := ""
    
    line2 := ""
    
    line3 := ""
    
    leds := table()
    
    leds["0"] := " _  ,| | ,|_| "
    
    leds["1"] := "    ,|   ,|   "
    
    leds["2"] := " _  , _| ,|_  "
    
    leds["3"] := " _  , _| , _| " 
    
    leds["4"] := "    ,|_| ,  | "
    
				
				
    leds["5"] := " _  ,|_  , _| "
    
    leds["6"] := " _  ,|_  ,|_| "
    
    leds["7"] := " _  ,  | ,  | "
    
    leds["8"] := " _  ,|_| ,|_| "
    
    leds["9"] := " _  ,|_| , _| "
	
    write("Enter a number: ")
    
    num := read()
    
	
    while i <= *num do{
		
        line1 ||:= leds[num[i:j]][1:4]
        
        line2 ||:= leds[num[i:j]][6:9]
        
        line3 ||:= leds[num[i:j]][11:14]
        
        i +:= 1
        
        j +:= 1
       
    }				
				
				        
    write(line1)
    
    write(line2)
    
    write(line3)
    
end	
				

When we run it we're going to see...

Decimal to Romans


This App will create a Roman Numeral based on a decimal number


This will include some nice commands...


Name your file "Decimal_to_Roman.icn"


				
procedure main()

    local roman, x, num, result, sort_roman
    
    result := ""
    
    roman := table()
    
    sort_roman := []
    
    roman[1000] := "M"
    
    roman[900] := "CM"
    
    roman[500] := "D"
    
    roman[400] := "CD"
    
    roman[100] := "C"
    
    roman[90] := "XC"
    
    roman[50] := "L"
    
    roman[40] := "XL"
				
				 
    roman[10] := "X"
    
    roman[9] := "IX"
    
    roman[5] := "V"
    
    roman[1] := "I"


    every x := key(roman) do
    
        sort_roman |||:= [x]
			
			
    sort_roman := sort(sort_roman)


    write("Enter a number: ")
    
    num := read()
				
				
    while num > 0 do{
		
        x := *sort_roman
        
        while x > 0 do{
			
            if num >= sort_roman[x] then{
				
                result ||:= roman[sort_roman[x]]
                
                num -:= sort_roman[x]
                
                break
                
            }
            
            x -:= 1
            
        }
        
    }
	
	
    write(" ")
    
    write(result)
    
end 
				

When we run it we're going to see...

Random Names


This App will generate 100,000 random names using two 16 elements arrays


We will measure the runtime.


Name your file "Random_Names.icn"


				
link random


procedure main()

    local names, last_names, full_names, i
    
    randomize()
    
    names := ["Anne","Gigi","Blag","Juergen","Marek",
    
              "Ingo","Lars","Julia", "Danielle",
              
              "Rocky","Julien","Uwe","Myles","Mike",
              
              "Steven","Fanny"]
              
    last_names := ["Hardy","Read","Tejada","Schmerder",
    
                   "Kowalkiewicz","Sauerzapf","Karg",
                   
                   "Satsuta","Keene","Ongkowidjojo",
                   
                   "Vayssiere","Kylau","Fenlon",
                   
                   "Flynn","Taylor","Tan"]
				
				
    full_names := []
 
    
    every i := 1 to 100000 do
    
        full_names := full_names ||| [names[?16] 
        
                      || " " || last_names[?16]]

	
    write("Time taken: ", &time, " milliseconds")
    
end
				

When we run it we're going to see...


Ok...that's more than a minute and a half...

Icon is not about speed after all -:(

Counting Letters


In this example we're going to read a file and count how many time a letter appears...


Call your file "countletters.icn".


Create a file called "readme.txt" with the following text...


"This is a text file that we're going to read using Icon"


				
procedure main()

    local intext, outtext, letters, x, i , j, letter
    
    letters := table()
    
    letter := ""
    
    i := 1
    
    j := 2
    
    intext := open("readme.txt") | 
    
              stop("Cannot open file")
    
    outtext := read(intext)
				
				
    every x := 1 to *outtext do{
		
        letter := outtext[i:j]
        
        i +:= 1
        
        j +:= 1
        
        if \letters[letter] then letters[letter] +:= 1
        
        else insert(letters,letter,1)
        
    }
	
	
    every x := key(letters) do
    
        write(x," : ",letters[x])
        
end
				

When we run it we're going to see...


That's it for now...


Despite the fact that is not so fast


Icon is a pretty cool language, that allows fast programming


Not sure why it didn't went mainstream...


Contact Information


Blag --> blag@blagarts.com

@Blag on Twitter

Go back home...