ObjectIcon

From Bauman National Library
This page was last modified on 21 May 2016, at 23:27.
ObjectIcon
Paradigm object-oriented
Website ObjectIcon

Object Icon is an object-oriented programming language, based on the classic Icon programming language. As its name implies, it adds object-oriented features, which are intended to make it much easier to write large programs and libraries. Some of the other significant features are :-

  • Very cheap co-expressions, with dynamically sized stacks. Co-expressions also form true closures over local variables.
  • A utf-8 based unicode string type.
  • Package/namespace system

Co-expressions and local variables

In contrast to conventional Icon, Object Icon implements co-expressions in such a way that they share the local variables of the procedure in which they were created (in Icon each co-expression gets a copy of the local variables).

For example, the following program

import io

procedure main()
   local i, e
   i := 1
   e := create i := 2
   write(i)
   @e
   write(i)
end

outputs

1
2

whereas in Icon the result would be

1
1

Refreshing a co-expression creates a new co-expression, which also shares the same local variables. Thus the program

import io

procedure main()
   local i, e
   i := 1
   e := create i +:= 1
   write(i)
   @e
   write(i)
   e := ^e
   @e
   write(i)
end

outputs

1
2
3

The ! operator

Object Icon lets the unary ! operator be applied to co-expressions. The effect is to generate the sequence of results from a refreshed copy of the given co-expression. In other words, the result sequence of !e is the same as for p(e), if p were defined as the following procedure :

procedure p(e)
   e := ^e
   suspend |@e
end

Note that evaluating !e does not affect e, nor generate any results from it.

Classes and objects

Class syntax

The syntax for a class definition is

class ClassName(Super1, Super2, ...)
   ... Field definitions...
end

Declaring a class causes a global variable having the name of the class to be included in the program. The initial value of the variable is a value of type class, representing the class itself. The value of the variable can be changed using assignment, since it is just a normal global variable. This sounds complicated, but it works in the same way that conventional Icon treats procedures and built-in functions. Classes cannot be created or changed dynamically; they are hardwired into the icode file.

The lang.Class class contains many static methods which allow the inner structure of a class to be examined at runtime.

Fields

The field definitions are either variables or methods. Each definition starts with the access modifiers, which specify who may access the field, and how it may be accessed. Typical variable declarations are :

private x, y                    # Private instance variables
public static const PI          # A constant, accessible anywhere
private readable z              # A private variable, but accessible read-only from outside

A method definition looks like :

# A public instance method
public set_loc(x, y)
   self.x := x
   self.y := y
end

# A static method accessible without an instance
public static origin()
   return Point(0,0)
end

To bring these things together, here is a simple class definition to represent an x,y point :

import util(Math)

class Point()
   public const x, y
   public static const ORIGIN

   private static init()
      ORIGIN := Point(0, 0)
   end

   # Radius of a circle on which this point lies
   public radius()
      return Math.sqrt(x * x + y * y)
   end

   # Distance between two points
   public static distance(p1, p2)
      return Math.sqrt((p1.x - p2.x) ^ 2 + (p1.y - p2.y) ^ 2)
   end

   public new(x, y)
      self.x := x
      self.y := y
      return
   end
end

The static init() method is used to initialize any static variables. It is called automatically the first time the class is referenced. The new() method is similar, but is used to initialize instances - it is called automatically every time a new object is created. Some examples of using the class :

p1 := Point(-2, -3)
p2 := Point(4, 3)
write(Point.distance(p1, p2))
write(p2.radius())
write(Point.distance(p2, Point.ORIGIN))

One thing to note about the Point class is that it is immutable. That means that its state does not change once it has been created. This is achieved by declaring its two instance variables as const.

External links

  1. Field
  2. ObjectIcon
  3. API