dideler
12/15/2013 - 1:17 PM

The example problems have gone missing from the Io language website, so here’s a backup.

The example problems have gone missing from the Io language website, so here’s a backup.

#Sample code

#Hello world

"Hello world!" print

#Factorial

factorial := method(n, if(n == 1, 1, n * factorial(n - 1)))
99 bottles of beer

bottle := method(i,
     if(i == 0, return "no more bottles")
     if(i == 1, return "1 bottle")
     return "" .. i .. " bottles"
)

for(i, 99, 1,
     writeln(current, " of beer on the wall, ", current, " of beer,\n",
          "take one down, pass it around,\n",
          bottle(i - 1), " of beer on the wall.\n")
)

#Create a simple object and show how to use it

Account := Object clone
Account balance := 0
Account deposit  := method(v, balance = balance + v)
Account withdraw := method(v, balance = balance - v)
Account show := method(
  writeln("Account balance: $", balance)
)

myAccount := Account clone
myAccount show
"Depositing $10\n" print
myAccount deposit(10)
myAccount show

#Concurrency example - the following will print "112233"

o1 := Object clone
o1 test := method(for(n, 1, 3, n print; yield))
o2 := o1 clone

// @ means send an asynchronous message
o1 @test; o2 @test 

// wait for the messages to get processed
while(Scheduler activeActorCount > 1, yield) 

#Look up a class/prototype given its name as a string

Lobby getSlot("PrototypeName")

#Execute a method given its name as a string

anObject perform("SomeMethodName", arg1, arg2)

#Find out if a method with a given name (again a string) exists

anObject hasSlot("SomeMethodName")

#Given an arbitrary reference to a class/prototype, instantiate it

newInstance := objectRef clone

#Add a method to a primitive

Number double := method(self * 2)
1 double
==> 2

#Subclass a primitive

MyList := List clone // Same as creating an instance

#Iterate through an inheritance hierarchy

Object printAllSlots := method(  
  self slotNames foreach(i, slotName, 
    writeln(slotName)
    if(self hasSlot("proto"), self proto printAllSlots
  )
)
Object printAllSlots

#Implement a generic proxy

Proxy = Object clone
Proxy forward := method(
  methodName := thisMessage name
  args := thisMessage argsEvaluatedIn(sender)

  // When an unrecognized message is received,
  // this method will be invoked.
  // Do what you like with the message here -
  // such as send it over a network, etc.
)

#Implement a singleton

Foo := Object clone
Foo clone := Foo

#Print the source code of a method

myMethod := method(return testing(1+2+3))
getSlot("myMethod") code print
==> "return(testing(1+(2)+(3)))"

#Add an operator method to an object

MyObject := Object clone
MyObject setSlot("+",  method(n, write("adding ", n, "\n")))
MyObject + 123
==> "adding 123"

#Mixins and Aspects

a := Object clone

Mix := Object clone
Mix logData := Buffer clone
Mix init := method(logData = logData clone)
Mix log := method(s, logData append(s))

a parent := Mix clone // Now a also inherits the state and behavior of Mix

b := Object clone
b parent := Mix clone // Now multiple objects use it so it's an "aspect"

#An auto source file importer

Object searchPaths = List clone add(launchPath)

Object forward := method(
  methodName := thisMessage name
  if (methodName characterAt(0) isUpperCase,
    searchPaths foreach(i, searchPath,
      fileName := searchPath appendPath(methodName .. ".io")
      sourceFile := File clone setPath(fileName)
      if (sourceFile exists) then (
        Lobby doFile(path)
        return Lobby getSlot(methodName)
      )
    )
  )
  raiseException("Importer", "Could not find slot for " .. methodName)
)

#A simple whois client

whois := method(host,
  socket := Socket clone setHostName("rs.internic.net") setPort(43) 
  socket connect write(host, "\n")
  while(socket readNextChunk, nil) // socket read auto yields to other coroutines
  return socket readBuffer
)

#An echo server

Echo := Object clone
Echo handleSocket := method(socket,
  while(socket isOpen, 
    if(socket read, socket write(socket readBuffer))
    socket readBuffer empty
  )
)

EchoServer := Server clone setPort(8456) 
EchoServer handleSocket := method(socket,
  Echo clone @handleSocket(socket) 
  // async message so it's handled in separate coroutine
)
EchoServer start