Io podcast

Thursday, July 27th, 2006

Rodney Ramdas, from pinupgeek, recorded the first episode of the Io podcast. His guests are Steve Dekorte, Io’s creator, and Jonathan Wright (aka quag) who does the night shift. It can’t get any better in the Io world!

Good luck Rodney for the podcast!

technorati tags:,


Build Io on Ubuntu Dapper

Thursday, July 27th, 2006

The Io language has a brand new build system. Gone is the static linking, Io is now dynamically linked. I believe the build system is far better than its predecessor.

It will need a couple of iterations to iron out a couple of problems. The detection of the dependencies for the bindings needs a small revision: it only checks for the libraries, not the header files. This is problematic on debian based system where, traditionally, a library X is in a package named libX and the header files in libX-dev.

If you want to experience Io on Dapper, you will have to do the following:

> sudo apt-get install build-essential
  libsqlite0-dev
  libpcre3-dev
  libfreetype6-dev
  freeglut3-dev
  libgmp3-dev
  libncurses5-dev
  libpng12-dev
  libtiff4-dev
  libevent-dev
[...]
> sudo ldconfig

To get the SGML binding working, you will have to get your hands dirty with libsgml. Here is how:

> wget http://www.hick.org/code/skape/libsgml/libsgml-1.1.4.tar.gz
[...]
> tar xfz libsgml-1.1.4.tar.gz
[...]
> cd libsgml-1.1.4
> ./configure
[...]
> make
[...]

Before going any further, you need to edit the Makefile and change the first line of the install target from:

install -m 644 -o root -g root --directory /usr/local/include/sgml

into this:

install -o root -g root --directory /usr/local/include/sgml
install -m 644 -o root -g root include/Variant.h \
    /usr/local/include/sgml/Variant.h

Don’t ask… Finally, to install libsgml in a relatively clean way, I suggest using checkinstall like this:

> sudo apt-get install checkinstall
> sudo checkinstall

The stage is ready for Io:

> sudo apt-get install darcs
[...]
> darcs get http://www.iolanguage.com/darcs/Io
[...]
> cd Io
> make

May the cloning begin!

technorati tags:,

Updated on 05/09/06: fixed typo, thanks to Jesse’s comment.


IE without Windows

Wednesday, June 14th, 2006

Stuck in windows because you need to use IE to verify your CSS magic? I’ve got great news for you, my friend, because IE now runs in Linux, FreeBSD, Solaris, Mac OS X…

It can’t get easier than IEs 4 Linux. See for yourself, here is the Ubuntu/Debian version:

sudo apt-get install cabextract wine
wget http://www.tatanka.com.br/ies4linux/downloads/ies4linux-2.0beta6.tar.gz
tar xfz ies4linux-2.0beta6.tar.gz
cd ies4linux-2.0beta6
./ies4linux

Bingo! You’ve got IE on your favourite OS. From now on, ~/bin/ie6 will allow you to enjoy Redmond’s quirky browser.

technorati tags:,


Producing and maintaining high-quality code

Wednesday, April 26th, 2006

So much bad and ugly code is being spewed out every day all over this planet that entire websites are dedicated to the preservation of the worst specimens. In this post, I will show you simple ways to produce and maintain high-quality code because, firstly, this is one way of achieving Internet stardom that you probably want to avoid and secondly and more importantly, you know how painful it is to have to maintain bad code.

I will start by a disclaimer, using Douglas Adams words:

The problem with designing something completely foolproof is to underestimate the ingenuity of a complete fool.

You can follow all the tips in this post and still end up with bad code, but you would have to be a very crafty fool!

1. Understand the problem

If this sounds like a duh-ism, that is because it is one. If you do not understand what the code is supposed to do, you will not get it right. Before you start coding, whether you face a blank sheet or whether you are maintaining code, sit down and think: what problem am I trying to solve here.

2. Write unit-tests

I could almost have numbered it 1bis. Unit tests show and validate how the code is supposed to be used. Write the tests first if possible — unless you can get your hands on a time-machine, this is not an option when doing some maintenance. The quality of your interfaces will improve dramatically because you will design them from their user’s point of view.

3. Talk to your cardboard friend

How many times were you stuck on a problem, decided to seek help from a nearby colleague, explain the situation and bingo! the solution became obvious. Your colleague hasn’t even had time to pronounce one word, he probably didn’t even understand the question. Articulating the problem solved it. My nearby colleague calls this the “cardboard friend” because people drawn on cardboard tend to have the property of listening without interrupting.

4. Enforce a coding standard

I previously wrote about this but just in case you missed it: you need a coding standard to make your code homogeneous because reading code is hard enough, you do not need the distraction of multiple coding styles. Once you have a coding standard, use tools to enforce it. In Java, checkstyle rocks and if you use eclipse, be sure to check out this plugin. There are similar tools in most languages, use them! At first configure them to be a complete and utter pain and then relax the rules you believe are damaging.

5. Use code analysis tools

Use any tool you can find to study and analyze your code. If the language you are using is compiled, turn on all warnings on the compiler: use -Wall when you use gcc, open the preferences in Eclipse and activate most warnings for the Java compiler (be pragmatic). Use any lint-clone you can put your hands on for your language. Here are the tools I recommend for Java: JDepend to measure the quality of my abstractions and to avoid cyclical dependencies, PMD to identify potential bugs and potential optimizations, FindBugs to (coincidentally) find bugs. I should mention Checkstyle again since it can also detect bug patterns. The situation is simple: the more code analysis tools you run on your code the more you will be able to fix problems before they bite you.

6. Use a continuous integration system

I will unleash my secret finishing move on the next guy who tells me: “but it works on my machine”. A continuous integration system is a referee. If the ref says the build fails because it is broken or because some test fails, it’s because it is. So, go fix it. The ref is always right even when “it works on my machine”. How does it do that? At regular intervals, it tries to build the latest version of your code and if anything goes wrong, it fires notifications — generally emails — to whoever is concerned. Receiving these notifications is not such a bad news: you have identified a problem in your code. Use your continuous integration system to run the code analysis tools and fail the build if these tools report problems. You can use CruiseControl, AntHill, DamageControl or write your own with cron+make+sendmail, but please use a continuous integration system.

7. Write less code

Aspire at writing code like a Zen master writes a Koan:

Monk: Does a dog have Buddha nature or not?
Zhaozhou: Wú.

There are two principles to assist you in your quest for minimalist code: KISS and DRY. “Keep It Simple Stupid”: do what is required and no more. Focus on a clean and simple implementation. “Don’t Repeat Yourself”: avoid duplicating code. Refactor mercilessly. This will decrease the size of your code-base, which is a Good-Thing™ because the less code you write, the less bugs you write.

8. Performance is overrated

I will probably have a contract on my head after this point, that’s what blogging is about, no? Writing fast code is a two step process:

  1. get the code to work,
  2. stop.

In case this was unclear: do not optimize the code. In the vast majority of cases, the code you are about to optimize is not a bottleneck. Use a profiler on a system running realistic data and identify the bottlenecks. Only then can you start working out how to eliminate them. Very often you will not have to change a single interface, only the implementation will require changes.

9. Read, read, read

Read books about software development. You must read the GoF book about Design Patterns and put it to good use. You must pick up Martin Fowler’s Refactoring, Code Complete by Steve McConnell. There are countless others. One of the first book to really open my eyes on developing good code was Writing Solid Code by Steve Maguire.
Read books about other programming languages too, you will frequently discover programming concepts that you might be able to port to your environment.

10. Use common sense

Common sense is your best friend to beat bad code and it’s free! Common sense is what dictates the previous nine points.

I hope you found these tips interesting and entertaining too! I am looking forward to your comments. I leave you with Zhaozhou to conclude this post: Wú!.

technorati tags:, ,


Behaviour Driven Development with RSpec

Monday, April 24th, 2006

Back in February, I told you about Behaviour Driven Development using RSpec. Things have moved in very interesting directions since then.

First, and this is probably the most important, BDD is getting quite some attention, most notably at Canada on Rails. You should check out the Ruby on Rails podcast episode from the 17th of April, where Dave Astels makes an appearance alongside Tim Bray.

On the usage front, RSpec’s DSL has seen some tremendous progress. It reads like plain English. I have not decided yet whether I find it too wordy or simply astonishing! What do you think of this example.

Finally, RSpec now has a good-looking content-packed website complete with documentation, tutorial, examples and all.

There is simply no barrier to its adoption, it just needs traction within the development community. This is where you and me come into the picture. Let’s make RSpec a success, let’s all give it a go: gem install rspec.

You will be amazed at how much RSpec will impact the quality of your code because it changes your perspective on unit testing.

Comments are welcomed and encouraged! That’s all folks, see you next time!


Quantum Computing and “Singes Dactylographes”

Thursday, April 20th, 2006

As a popular science anorak, I listen to several scientific podcasts geared towards enthusiasts. This morning, while catching up on the Science Friday Podcast, I had the great pleasure to listen to Ira Flatow interview Seth Loyd on Quantum computing. The dialogue is witty, thought provoking and easily accessible. Seth Loyd, who jokingly describes himself as a quantum mechanic, excels at popularizing this complex and fascinating topic. I hope not to betray his ideas in what follows.

In man made quantum computers, we coax atoms and elementary particles to perform specific computations. Seth Loyd’s argument is that the universe is a quantum computer. Indeed, every atom and elementary particle carries bits of information that can flip following collisions. In effect, the universe is already computing. This reminded me of an excellent book by David Deutsch: “The Fabric of Reality”. If my memory serves me well, he too considers the universe — or should I say multiverse — to be a quantum computer. What made me think of this book is Loyd’s reference to Borel’s “singes dactylographes” towards the end of the interview.

In 1913, Emile Borel, a french physicist, illustrated how unlikely the occurrence of a particular event is — to be precise: how unlikely it is to observe a noticeable difference from what is the most likely outcome of statistical mechanics — by comparing it with the likelihood that a million monkeys using a million typewriters ten hours a day for a year would produce the exact copy of each and every book in the world’s most famous libraries. I should point out that this quote is also attributed to Aldous Huxley, the English biologist (he would have been only 19 in 1913, so I tend to favour Borel as the originator). Check out the Parable of the Monkeys for a rather long list of related quotes.

Seth Loyd points out that if the monkeys were to use a quantum computer the result is far more likely:

if you take a computer, we have a computer because the universe is computing and it’s a quantum computer, and if you take a bunch of monkeys, here the monkeys are these little tiny quantum fluctuations that tell the universe to do this or that. […] These little accidents program the universe and it’s this process of programming the universe with quantum fluctuations that gives rise to the computation we see around us which produces all sorts of complexity, and structure, and beautiful things, and horrible things, and most of all amazing things.

While listening to this, I could not stop thinking we have already run the monkey experiment. It turns out that monkeys do write the collected works of Shakespeare rather quickly. What takes a lot of time is waiting for the monkeys to self assemble. Indeed, it took roughly 14,000 million years for the quantum computer we are part of to come up with a proto-monkey. It took a further 5 million years for this proto-monkey to evolve into William Shakespeare and approximately 36 years for Shakespeare to write Hamlet. Typewriters turn out to be the hardest thing to get as they only appeared 300 years later.

Rounding up, 100% of the time is spent waiting for the monkey, 0% waiting for the books to be written.


The Panda Principle

Wednesday, April 5th, 2006

A few years back, I read “The Collapse of Chaos: Discovering Simplicity in a Complex World” by Jack Cohen and Ian Stewart. As a popular science addict, I thoroughly enjoyed this book. I particularly remember it for introducing me to Stephen Jay Gould’s Panda principle. All of us have seen the Panda’s principle in action, yet few of us know of it. The following lines will, I hope, shed some light on this principle. I will start by exposing how it came to be discovered. Then I will look at a couple of typical examples to show that it reaches beyond biology. Finally I will explain why the Panda principle is relevant in the context of this blog — because for a couple of paragraphs, you will wonder.

The Panda’s Thumb: Survival of the Fit-ish

In “The Origin of the Species“, Charles Darwin popularized the concept of natural selection. Here it is, summed up by the man himself:

I have called this principle, by which each slight variation, if useful, is preserved, by the term of Natural Selection.

Contrary to popular belief, Darwin did not coin the phrase “Survival of the Fittest”, Herbert Spencer did when he applied Darwin’s theory to human societies. This phrase suggests that only the cream of the cream thrives, the rest being condemned to extinction.

Enter the panda.

Check out this thumb! How could such a poorly formed appendage be the result of millions of years of natural selection. Should it not be the best possible thumb to manipulate bamboo shoots? Stephen Jay Gould answers this question by observing that pandas might have evolved better thumbs but their current thumb is good enough — and sufficiently widespread among the panda population — to prevent improved thumbs from being a selective advantage. He named this the Panda Principle. As Cohen and Stewart put it:

Evolution leads to the occupation of niches by locally optimal creatures, not by globally optimal ones.

In effect, once locally optimal creatures get a foothold they prevent globally optimal ones from occupying the same niche.

The Panda Principle in action

The Panda Principle manifests itself in a wide range of domains. Stephen Jay Gould uses the example of keyboard layouts. Christopher Sholes, an early typewriter inventor, realized that his original design suffered from one problem: fast typists would frequently jam the type-bars. He had to slow them down. He came up with the QWERTY layout by trial and error in 1873. It is fair to say that QWERTY is a slow-ptimized layout! That hardly makes it the most efficient design for today’s usage where RSI sufferers’ fingers are the only thing that can actually jam.

In the 1930s, Dr. August Dvorak found that virtually any random layout leads to faster typing speed than the QWERTY layout — Sholes had worked hard to reach this (global) minimum. Dvorak invented the Dvorak layout — I am sure the amazing and unlikely coincidence is not lost on you. Throughout his life Dvorak fought unsuccessfully to get his layout adopted. He died a bitter man in 1975. Sadly, the man had a point: in every single comparative study, the Dvorak layout proved faster, more comfortable and less error-prone. There is still a community of Dvorak layout users, most of them programmers who have decided to use the fittest layout. But by all account, the QWERTY specimen is here to stay. It might well be the least fit specimen in the keyboard-layout-space but it will not be replaced any day soon. A perfect example of the Panda Principle in action.

At first, I thought the Betamax v. VHS war was another manifestation of the principle. I had it all typed and it looked promising: “despite Betamax being superior to VHS in technical terms — and being the Simpsons’ favourite videotape format — it lost the war”. Then I discovered that the original Betamax tapes were only one hour long, whereas VHS would stretch up to 3 hours long. In hindsight, this is a huge argument against Betamax’s fitness. As it turned out, in the videotape space, fitness is strongly correlated with the record-ability of hollywood movies. Hardly a good example to illustrate the Panda Principle.

Panda sighting #1: Smalltalk

Now, you must be wondering where I am going to with this principle and what is the link with this blog. Well, I have recently stumbled upon two manifestations, or so I believe, of the Panda Principle in the realm of software development.

The first one was a couple of weeks ago when I decided to pick up a Smalltalk book from Stéphane Ducasse’s collection and learn the language. Smalltalk is a fascinating and beautiful language. It was destined to be the next best thing. Then came Java. We all know what happened next.
The more I read about or play with Smalltalk, the more I wonder how Java won the match. It seems to me that Smalltalk had everything Java does and much more — yes, I am once again talking about metaprogramming, but there are so many other aspects. The two most common arguments to Java’s dominance are:

  • Java was an incremental step from C++. Whereas Smalltalk was influenced by the far less popular Simula and Sketchpad. It was therefore easier for Java to gather momentum as it appealled to a larger audience
  • Sun made the JDK available for free. Smalltalk development kits where expensive and more often than not incompatible.

Both arguments seem to forget that at the beginning, Sun envisaged Applets as being Java’s spearhead. Ironically, Java only really took off when people started using it on the server side.

What surprises me is the impressive list of contributions the Smalltalk community made to the Java community. Take Eclipse, arguably one of the most successful open-source Java project. Eclipse was originally derived from IBM’s VisualAge Micro Edition. VisualAge, up to the Micro Edition release, was Smalltalk based. As Joe Winchester puts it

From a technology point of view Eclipse has a lot of Smalltalk DNA in it.

Take the JUnit framework, written by Erich Gamma and Kent Beck. It has inspired countless testing frameworks in virtually any programming language. Well, JUnit actually had a precursor: SUnit, also written by Kent Beck.

Martin Fowler’s classic “Refactoring: Improving the Design of Existing Code“, although not a pure Java book, is on the bookshelf of most Java programmers (go buy it if is not!). The foundations of this book lie in Smalltalk as Fowler acknowledges in the preface.

It is hard to conceive that a language so ahead of its time and yet so simple failed to overcome the challenge of what seems a less evolved language. Moreover, Smalltalk had been preparing since 1971 for the advent of OOP‘s widespread acceptance. Java’s inception, on the other hand, only dates from 1990. When C++’s dominance came to pass, how did the fittest lose to the slightly fitter? Is this another manifestation of the Panda Principle?

Panda sighting #2: Mac/OS X

I have always been curious about Operating Systems and more particularly OSes for personal computers. I still remember my Pentium-75 triple-booting OS/2 WARP, Windows 95 and Linux. For quite a few years I have been a proponent of Linux and FreeBSD. I rarely use Windows, I get rashes and spots when exposed to it for more than a couple of minutes.

But lately, through the Ruby and Io community, I have been frequenting a bad bunch: Mac users. I heard so much about the Mac that I decided to have a closer look. I looked a bit too close. Here I am proud owner of a brand new iMac. I have been using it for less than a week and I have no doubt: this is the best machine I have ever had the pleasure to work with. My wife used to complain about my excessive usage of computers. Now, we are almost fighting about whose turn it is to use the Mac. I thought it would take me a while to get use to the Mac idiosyncrasies. After only a couple of hours, I feel pretty comfortable with the interface. Not only is it gorgeous, it is also far more comfortable and consistent than most systems I have used in the past.

A typical example of consistency is the key bindings. No matter what application I use I know command-F will let me search whatever this application manipulates. Compare that with Windows, ctrl-F is used by most applications but not all: see for yourself, try it in IE. It actually opens a side panel to let you search the web. If you look in the main menu, you will discover that ctrl-F is indeed the binding for searching into the current page… and sometimes it does — let me know if there is a cartesian explanation for this infuriating behaviour. The problem also exists in Gnome and KDE. It tends to be related to non-native applications like X-based ones.

But let’s go back to the Panda Principle, nobody can dispute Windows dominance in terms of marketshare. It is however hard to fathom how Windows could be considered the fittest OS for personal computers. I am talking fitness in the market space, not fitness in my own little OS fanatic space. Since I work in computers, I tend to get called by other people to fix their computers. I am pretty sure this resonates with your own experience. Are these people masochistic? How much pain can they endure? That repeatedly? Microsoft is losing the trust of its own customers. This has been going on for quite a few years, and yet only few people switch to alternatives. And there are many viable alternatives! I think this is a typical manifestation of the Panda Principle. Windows might not be the fittest but the shear number of users virtually guarantees that it will keep its place.

That is fine by me. I am quite happy with my very own globally optimum machine!


A bit of help to spread the word on Digg or Reddit would be very much appreciated!


Little manual of cloning for Io programmers

Monday, March 20th, 2006

Today, we will continue the little stroll around the Io language landscape that we started in Blame it on Io! A slow-paced introduction to the Io language. We will delve deeper into the central principle of prototype-based languages: cloning.

Cloning crash course

For the mad scientists and other evil dictators who landed here after googling “manual of cloning”, here is a crash course in object creation, à-la Io:

Movie := Object clone

original := Movie clone
original title := "Island of Lost Souls"
original year := 1933
original scenario := "Mad scientist off-shores
    development of mutant race"

remake := original clone
remake title = "The Island of Dr Moreau"
remake year = 1977

remakeOfRemake := remake clone
remakeOfRemake year = 1996

Object creation in Io, like Polka, is a two step dance: 1. you clone, 2. you specialize.

Differential inheritance

As we have just seen, cloning an object is done by sending it the clone message. This allows for a very elegant implementation of the Singleton pattern:

GeorgeClooney := FamousActor clone
GeorgeClooney clone = GeorgeClooney

Bad news for my wife… but I digress.

To really understand cloning, it is necessary to look at how an object is implemented. I will spare you the details of the struct definition (see vm/IoObject_struct.h if you really want to know) by remaining at a conceptual level. Io objects are made of two ingredients: slots and prototypes. Slots are stored in a hash table and represent both the data and the methods of the object. Prototypes are stored in a list and are the ancestors of the object — more on why this is a list in the next section.

How does this all fit together? Well, when a message is sent to an object, its name is used to query the slots hash table of the object. If no slot is found, the operation is repeated for each prototype in the prototypes list. When a matching slot is found, it is activated. If no slot is found, the forward slot is activated. If no forward slot is found, then you get an error. This will clarify:

JeanClaudeVanDamme := FamousActor clone
JeanClaudeVanDamme act

will raise: Exception: Importer Object does not respond to 'act', whereas:

KeanuReeves := FamousActor clone
KeanuReeves forward := method(
    writeln("I know ", call message name))
KeanuReeves kungfu

will even pretend that Keanu Reeves can act.

Now, back to our first question, what happens when an object is cloned? Very little actually: a new object is created with an empty slots hash table and a prototypes list containing the target of the clone message. By default, a clone delegates everything to its original. Once it is created, a clone is usually specialized by adding slots in its slots hash table. The clone only stores the difference with its original. This is called differential inheritance.

Clones sharing memories with their original, not only makes bad hollywood movies (The Island and Replicant), it is not always desirable:

Movie := Object clone
Movie cast := List clone

would lead to all movies sharing the same cast! You could fix the problem by initializing the cast slot to a freshly cloned list on every Movie clone, but this would be error-prone and very inelegant. This is where the init slot comes into play. It is activated, if it is present, just after the creation of the clone. Let’s rewrite the previous piece of code:

Movie := Object clone
Movie init := method(self cast := List clone)

Note that self is required, otherwise the cast slot will be local to the method.

Future directions

This is the current state of affair in Io. But things might change, Steve Dekorte, the mad scientist behind Io, identifies 5 different cloning strategies with regards to slots:

  1. nil: the slot is set to nil in the clone — init := method(self foo = nil)
  2. shared: the slot is not created in the clone — the current default behaviour
  3. shallow: the slot is created with the original’s value — init := method(self foo = foo)
  4. deep: the slot is created with a clone of the original’s value — init := method(self foo = foo clone)
  5. very deep: the slot is created with a deep clone of the original’s value — init := method(self foo = foo deepClone)

It is probable that support for each strategy will be added to Io at some point. For now, you have to use the init slot to implement these strategies.

Dynamic inheritance with Protos

Let’s come back to the prototypes list. From what I have explained so far, it seems objects can have only one parent, the original. A list looks superfluous. Great news for my mad-scientists readers: the answer does not follow the laws of biology. Io makes it possible to add and remove parents to an object, at runtime, using appendProto, prependProto, removeProto and other related methods. These methods simply manipulate the list of prototypes associated with an Io object.

LukeSkywalker := Person clone
LukeSkywalker appendProto(Orphan)
LukeSkywalker fightsWith(DarthVader)
DarthVader tellsSecretTo(LukeSkywalker)
LukeSkywalker removeProto(Orphan)
LukeSkywalker appendProto(DarthVader)

And this concludes today’s stroll! I hope you found it informative and entertaining. I would like to thank everyone on the #io channel for your patience in dealing with my questions. Most, if not all, of the information contained in this post comes from chats on IRC and from the Io documentation. I’ll only claim the silly examples!


Blame it on Io! A slow-paced introduction to the Io language

Wednesday, March 15th, 2006

No posts in a week, I have been silent too long. Blame it on Io!

You see, Io is a contagious disease. It affects programmers’ brains. The incubation period is extremely short, due to the simplicity of its syntax. But the damages are extensive, particularly for Algol-derivative programmers: you will end up messed up! Huh… I forgot to mention the vectors include reading posts about Io. I just hope your infection will not be as bad as mine. (If I do not get google hits from E.R. fans with this paragraph, what will it take?)

Yo Io!

First things first, let’s get the token “Hello World!” implementation out of the way:

"Yo Io!" print

Aside from my poor taste in greeting phrases, you probably noticed how concise and simple this statement is. At first sight, to most programmers, it appears to be written backward. Not so if you think that the "Yo Io!" object — which happens to be a string — is being sent the message print. Everything in Io is an object, and I really mean everything: lists, files, strings, numbers and even messages!

Attack of the clones

Well that is not fully accurate, to be pedantic, I should have written: everything in Io is a prototype. Indeed, Io is a prototype-based language. C++/Java/C# programmers, here comes surprise #1: Io knows nothing about classes. In class-based languages, classes describes the structure and behaviour of objects in term of methods whereas instances hold the objects’ data. Prototype-based languages do not make this distinction. A prototype is both a class and an instance. To get a new instance, you clone an existing prototype. To get a new class you add or alter the behaviour of an existing prototype. Sounds complex? Let your inner mad scientist free:

Sheep := Object clone

In English, Sheep is defined as a clone of Object — the parent of all Io prototypes.

Sheep legCount := 4

In brain-damaged English, the legCount property of a Sheep is defined as four. Non-programmers would have you believe this is equivalent to: a sheep has four legs.

MutantSheep := Sheep clone

A MutantSheep is defined as a clone of a Sheep. No surprise here, we all knew that!

MutantSheep legCount = 7

But their legCount property is set to seven! Most inner mad scientists tend to go for six legs, but my inner mad scientist is also nonconformist. I explain the difference between = and := in the next section. Just pretend they are the same for the moment.

dolly := MutantSheep clone

Here be dolly the mutant sheep! The convention is to use an upper-case character at the beginning of the name of prototypes acting as classes and a lower-case character for prototypes acting as instances.

Lots of slots

Once again, I have to confess that I have been inaccurate: I wrote legCount was a property of a Sheep whereas, in Io speak, it is actually a slot of Sheep. A slot associates a value to a name within the context of a prototype. Sheep holds one slot named legCount with the value 4. Here comes surprise #2: slots can contain variables and methods.

Sheep baa := method("bah!" print)

The baa slot on Sheep is defined as a method which prints “bah!”. Simple, no?
You noticed earlier that Io has two different assignment operators: := and =. Both of them are actually methods on Object. := is actually parsed as setSlot and = is parsed as updateSlot. From the method names you probably inferred the difference: := creates a new slot on a prototype from a name and a value whereas = updates an existing slot with a new value.
Io interprets the previous code sample like this:

Sheep setSlot("baa", method("bah!" print))

There is madness to Io’s methods

In case you were wondering, method is a method on Object that creates anonymous methods. The self-referential aspect of what I just wrote surely enlightened you, not. Rewind. Slow motion. The method method takes a list of parameters. All but the last one are arguments to the created method. The last argument is the body of the method. In this example, I define the growMoreLegs slot on MutantSheep to be a method with one parameter:

MutantSheep growMoreLegs := method(n,
    legCount = legCount + n)

Apart from the slightly surprising syntax, I hope this all sounds pretty familiar so far. Things are about to change big time! Surprise #3: a method can control when and if to evaluate an argument. This lets us define flow control constructs (if, unless, while, etc.) as methods. Most of them already exist on Object of course. One construct is missing though and we will implement it here. But first, we will botch the job:

Object unless := method(cond, then, else,
    if(cond, else, then))

The problem: cond, then and else are evaluated when unless is called. We do not want that. What we want is: unless cond is true, evaluate then, otherwise evaluate else. In Io this is done like this:

Object unless := method(
    if(call eval argAt(0),
        call eval argAt(2),
        call eval argAt(1)))

Update: see jer’s comment for a better implementation
What looks like a nice trick, is actually extremely powerful. Lisp programmers laugh in the background, they’ve used it successfully since 1958! I will not explore this vast topic any further in this post — I must save some ammunition for future posts!
By the way, I hope you appreciated the fact that Io is a dynamic language: we just added a method to the Object prototype!

Lobby for Io!

Before concluding, I would like to point out that Sheep and MutantSheep are defined like slots. But what is the underlying prototype? In Io, this is the Lobby. So what? Well, Lobby ultimately derives from the Object prototype, like all other prototypes. But where do you think we found the Object prototype? Bingo! It is a slot in the Protos slot of Lobby. I suggest you read this again. You are not dreaming: Object is both a slot of a slot in the Lobby and an ancestor of the same Lobby. How is that for another self-referential bit of self-reference?

Time to conclude, I hope this introduction will entice you to dwell deeper into this really amazing language. Believe me, we have only scratched the surface!
For a more complete, formal and accurate presentation of Io, check out The Io Programming Language.
Visit the official website or join the posse on irc.freenode.net#io.


Development best practices: coding standards and the “20 lines” rule

Wednesday, March 8th, 2006

Defining a coding standard

A coding standard is a set of conventions regulating how code must be written. These conventions usually cover formatting, naming and common idioms. Choosing them can be a painful process as it frequently leads to endless and passionate discussions between developers (how many hours have been lost arguing the positioning of curly-braces in Algol derived languages). Yes, us developers have an acute sense of aesthetics when it comes to our code — probably only rivalled in intensity by our legendary lack of aesthetics in the clothing department. In my experience, the best way to select a set of conventions is to have one experienced programmer act as a dictator. After all, no coding standards has ever pleased everyone.

Enforcing the standard

Coding standards are like speed limits: they are A Good Thing™ but they are useless unless they are respected. There are several ways to enforce the rules. Code reviews are probably the least efficient (don’t get me wrong: having code reviews is a very valuable practice, but not to enforce a coding standard). Using a code formatting tool when code is checked in the source control management system is more efficient. However, these tools rarely cover naming conventions and common idioms. Most IDEs can be configured to warn when the conventions are not followed and format the code on the fly. But the most efficient way is to use a dedicated tool and integrate it in the build system — particularly when using continuous integration. The best example I have come across is Checkstyle. Not only does it integrate easily in a build system but it can also be used as a plug-in in most Java IDEs. One stone, two birds and no more escaping the coding standard!

Benefits

At the very least, adhering to a coding standard allows a developer to read a piece of code written by another developer while focusing only on the content, because she is familiar with the form. If you think this is mildly important during the development phase of a project, think about the maintenance phase. Undoubtedly, enhanced readability leads to better maintainability. What is less obvious is that a coding standard can also improve the design of a piece of software. In my experience, no rule has a greater impact on design than what I call the “20 lines” rule.

The “20 lines” rule

It goes like this: No method body shall be longer than 20 lines. Period. Yes, that’s all: no big formula and no esoteric concept, just a simple little rule that absolutely anyone can understand. Its power lies in its simplicity.

You see, 20 lines of code is more than enough to express an idea concisely and it is also about the right amount of information the eye and the brain can scan and comprehend without having to do too much double-takes — not that I have data to back this up, but 20 lines happens to snugly fit in most screens/windows used while coding, thus reading the code does not require interrupting the train of thought by scrolling. If the only impact of this rule was enhanced readability, you would accuse me of false advertisement.

Most benefits from this rule actually cascades from the side effects of breaking down a large method in a set of smaller methods. The most dramatic effect is the reduction of the cyclomatic complexity of the code. Here comes the esoteric concept! Crudely, the cyclomatic complexity of a piece of code is a measure of the number of possible execution paths through it. Less execution paths means less execution paths to test. Bingo! We have just simplified our unit tests. The emergence of smaller methods improves abstraction and reusability. Indeed, very frequently these methods can be invoked in other parts of the code base, thus reducing redundant code.

I am certainly forgetting other effects but I hope you get my point: the “20 lines” rule is a really low hanging fruit. I frequently realize how far reaching its usage as had on the code I have written. Finally, the “20 lines” rule could have been Fight Club’s ninth rule: it does not accept exceptions, as exceptions to this rule are precisely when this rule should be applied.

Give it a go, you will be surprised by how quick you’ll start reaping the rewards!


Follow

Get every new post delivered to your Inbox.