io  →  about
faq
sample code

    Hello world

    "Hello world!" print
    

    Factorial

    Number factorial := method(n := 1; for(i, 1, self, n = n * i); n)
    

    Vectorized Factorial

    Numberfactorial := method((Vector clone setSize(self) rangeFill += 1) product)
    

    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, -1,
         writeln(bottle(i), " of beer on the wall, ", bottle(i), " of beer,")
         writeln("take one down, pass it around,")
         writeln(bottle(i - 1), " of beer on the wall.")
    )
    

    Create a simple object and show how to use it

    Account := Object clone do(
        balance := 0
        deposit  := method(v, balance = balance + v)
        withdraw := method(v, balance = balance - v)
        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 
    
    // here we pause the main coroutine
    //  the process will exit after async messages are processed and there
    // are no yielding coroutines to be switched to
    
    Coroutine currentCoroutine pause
    

    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(slotName, 
            writeln(slotName)
            if(self hasSlot("proto"), self proto printAllSlots)
        )
    )
    Object printAllSlots
    

    Implement a generic proxy

    Proxy = Object clone
    Proxy forward := method(
        methodName := call message name
        args := call message argsEvaluatedIn(call 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

    Mix := Object clone
    Mix logData := Buffer clone
    Mix init := method(logData = logData clone)
    Mix log := method(s, logData append(s))
    
    a := Object clone
    a appendProto(Mix clone) // Now a also inherits the state and behavior of Mix
    
    b := Object clone
    b appendProto(Mix clone) // Now multiple objects use it so it's an "aspect"
    

    An auto source file importer

    Object searchPaths = List clone append(launchPath)
    
    Object forward := method(
        methodName := call message name
        if (methodName characterAt(0) isUpperCase,
            searchPaths foreach(searchPath,
                fileName := Path with(searchPath, methodName .. ".io")
                sourceFile := File clone setPath(fileName)
                if (sourceFile exists) then(
                    Lobby doFile(path)
                    return Lobby getSlot(methodName)
                )
            )
        )
        Exception raise("Importer: Could not find slot for " .. methodName)
    )
    

    Fetch a URL and find the links in it

    aString := URL with("http://www.yahoo.com/") fetch
    links := aString asXML elementsWithName("a") map(attributes at("href"))
    

    A simple whois client

    whois := method(host,
    	socket := Socket clone setHostName("rs.internic.net") setPort(43) 
    	socket connect streamWrite(host, "\n")
    	while(socket streamReadNextChunk, nil) // sockets auto yield to other coros
    	return socket readBuffer
    )
    

    A minimal web server

    WebRequest := Object clone do(
    	handleSocket := method(aSocket,
    		aSocket streamReadNextChunk
    		request := aSocket readBuffer betweenSeq("GET ", " HTTP")
    		f := File with(request) 
    		if(f exists, f streamTo(aSocket), aSocket streamWrite("not found"))
    		aSocket close
    	)
    )
    
    WebServer := Server clone do(
    	setPort(8000)
    	handleSocket := method(aSocket, 
    		WebRequest clone @handleSocket(aSocket)
    	)
    )
    
    WebServer start
    

    OpenGL

    See the Io versions of the NeHe OpenGL tutorials.