Io> Ferris live
So week 2 brings me (a week late) to a language I’ve never heard of before. As Ruby was Mary Poppins, so Io is, apparently, Ferris Bueller. I have a poor familiarity with Ferris Beuller’s Day Off so here ends all references to Ferris for this week’s posts.
Io is an object based prototype language. Everything is an object that receives messages and how the object responds to the message is dictated by its prototype. If a given object cannot respond to a message based on its prototype then the its type’s prototype is consulted (and so on). This will become clearer in a moment. This is the analogy of inheritance in a prototype language.
Like Ruby, Io is an interpreted language. After installing the interpreter and supporting libraries, statements can be entered directly into the interpreter. To run programs from a file the interpreter can either be invoked on the command line or (if the host operating system supports this idiom) referenced at the start of the program file.
Running statements in the Io Interpreter
[dan@home ~]$ io Io 20090105 Io> "hello world" println hello world ==> hello world Io>
Running an Io Program by Invoking the Interpreter
[dan@home ~]$ vi testing.io [dan@home ~]$ io testing.io hello world
Running an Io Program by Specifying Interpreter in Source
[dan@home ~]$ echo '#!'$(which io) > testing2.io [dan@home ~]$ cat testing.io >> testing2.io [dan@home ~]$ chmod +x ./testing2.io [dan@home ~]$ ./testing2.io hello world
Grab the sources to Io from the Io Github repo and unzip them into a build directory. There are a number of libraries required in order to build Io and the packaged components. I’m running Fedora 15 and needed to install the following packages to get a build that issued no warnings.
Use the build.sh script in the extracted contents of the download to build and install Io:
[dan@home ~]$ ./build.sh [dan@home ~]$ sudo ./build.sh install [dan@home ~]$ sudo ./build.sh LinkInstall
Finally you will need to update the locations used for finding dynamically loaded libraries. On my Fedora system this requires adding a new file referencing /usr/local/lib into the /etc/ld.so.conf.d/ directory and re-running ldconfig:
[dan@home ~]$ sudo echo "/usr/local/lib" > /etc/ld.so.conf.d/usrlocal.conf [dan@home ~]$ sudo ldconfig
Given it’s youth, I found it surprising how much material is available on Io. A google for “io language” reveals quite a wealth of results.
Primary amongst these resources is Io’s home at http://www.iolanguage.com/. There are links from there to reference material and a useful wiki. From the wiki there are links to a useful page of samples and a style guide.
And as a sign that the language has surely “arrived”, Stackoverflow has an iolanguage question tag.
Io is a strong but dynamically typed language. By adding slots we can provide implementations of expected methods. We can see this with a simple example:
[dan@home ~]$ io Io 20090105 Io> 1 + 1 ==> 2 Io> 1 + "two" Exception: argument 0 to method '+' must be a Number, not a 'Sequence' --------- message '+' in 'Command Line' on line 1 Io> "one" + "two" Exception: Io Assertion 'operation not valid on non-number encodings' --------- message '+' in 'Command Line' on line 1 Io> "one" type ==> Sequence Io> Sequence + := method(next, self .. next) ==> method(next, self .. next ) Io> "one" + "two" ==> onetwo Io> "one" + 1 ==> one1 Io> 1 + "one" Exception: argument 0 to method '+' must be a Number, not a 'Sequence' --------- message '+' in 'Command Line' on line 1 Io>
Here we send the + message to two Number objects and we get the expected result. When we try this between a Number and Sequence we get an exception and ditto when we try it with two Sequences. Once we define a + against Sequence our tests work. Sort of. I included that final erroring case as it highlights that the message is going to a Sequence and not a Number. Adding a + to Number such that it would accept a Sequence proved a little beyond me at this stage.
Apart from nil and false it seems pretty much everything in Io evaluates to true.
Io> true and true ==> true Io> true and false ==> false Io> true and nil ==> false Io> true and 1 ==> true Io> true and 0 ==> true Io> true and "" ==> true Io> true and "true" ==> true Io> true and "false" ==> true Io> true not ==> false Io>
The slotNames message enables us to see what slots are available on a given object:
Io> Object slotNames ==> list(newSlot, ownsSlots, isError, foreachSlot, currentCoro, <, removeAllSlots, list, for, doString, uniqueHexId, clone, become, write, evalArgAndReturnNil, serializedSlots, isNil, method, block, pause, isActivatable, deprecatedWarning, isLaunchScript, coroWith, evalArg, uniqueId, ?, actorProcessQueue, do, in, setProto, super, writeln, setSlot, !=, inlineMethod, doRelativeFile, removeAllProtos, coroDo, asyncSend, continue, stopStatus, ancestorWithSlot, print, protos, evalArgAndReturnSelf, actorRun, not, type, and, return, break, slotSummary, >, message, ==, serialized, slotNames, ifNonNilEval, asSimpleString, hasLocalSlot, while, updateSlot, switch, perform, returnIfError, asString, hasSlot, try, returnIfNonNil, hasProto, prependProto, getSlot, wait, justSerialized, hasDirtySlot, thisContext, removeProto, appendProto, println, lazySlot, loop, slotDescriptionMap, launchFile, .., relativeDoFile, serializedSlotsWithNames, compare, , yield, setSlotWithType, init, resend, isTrue, lexicalDo, or, doFile, argIsActivationRecord, raiseIfError, ancestors, isIdenticalTo, ifNil, ifNilEval, performWithArgList, cloneWithoutInit, contextWithSlot, thisLocalContext, >=, if, isKindOf, memorySize, <=, ifNonNil, coroFor, thisMessage, apropos, @, getLocalSlot, ifError, markClean, coroDoLater, slotValues, -, doMessage, proto, setIsActivatable, futureSend, removeSlot, shallowCopy, handleActorException, @@, setProtos, argIsCall) Io> Person := Object clone ==> Person_0x82f9b60: type = "Person" Io> Person slotNames ==> list(type)
The proto will list all the slots available to an object via its prototype.
A Note on Assignment Operators
Io has 3 operators that play a similar role:
The first is assignment to an existing slot. An exception is raised if the slot is not present. This stackoverflow answer deals nicely with the difference between the second two.
Glad to see you’re still going well with the studying. Sorry you missed the call today.
Yeah, I’m slipping a bit though :) Going to try and get through Io this week but might give Prolog a miss and pick up again with Scala from next Monday.
Truly when someone doesn’t understand afterward its up to
other viewers that they will help, so here it happens.
I know this web page provides quality dependent articles
or reviews and extra data, is there any other website which gives these data in quality?
A fascinating discussion is worth comment. I do
believe that you should publish more about this issue, it might not be a taboo subject
but usually people do not discuss these subjects.
To the next! Cheers!!
Very great post. I just stumbled upon your weblog and wished to say
that I’ve truly enjoyed surfing around your
blog posts. In any case I’ll be subscribing for your feed and I hope you write again soon!