Sunday, November 28, 2010

Lowering the barrier to metaprogramming


I've been trying to finish the Io chapter of Seven Languages in Seven Weeks, and I just added indentation to the LispML implementation. At the end of the Io chapter Bruce says
Io’s syntax is remarkably compact. You can learn Io very quickly. Once you understand the core syntax, everything else is learning the library structures. I found that I could work my way into metaprogramming quite quickly, within my first month of using the language. In Ruby, getting to the same point took a little longer. In Java, it took many months to get to the point where I could make any sense of metapro- gramming at all.


He is right on the money! But edit "within my first month" to "within my first week". Also, since there isn't special syntax for metaprogramming you aren't likely to forget how to do it. All you need to understand is how a method call in Io works, and you are ready to metaprogram.

Friday, November 26, 2010

Io Language: the init method


I'm slowly working through Bruce Tate's book "7 Languages in 7 Weeks". It is ambitious and lots of fun. In the Io chapter I struggled and I think it was because Bruce forgot to mention Io's init method. The init method is automatically called anytime a prototype is cloned and it is important becuase if you can't setup each clone, you can't have full fledged instance level behavior. Here is some code I wrote after reading Bruce's intro to Io.

Closet := Object clone do(
closet := list()
stash := method(item,
self closet append(item)
)
peek := method(
self closet foreach(item, item println)
)
)

myCloset := Closet clone
yourCloset := Closet clone
myCloset stash("rollerskates")
yourCloset stash("bowling ball")
"My closet looks like:" println
myCloset peek

"Your closet looks like:" println
yourCloset peek

If you run that code you will see it print out the following:

My closet looks like:
rollerskates
bowling ball
Your closet looks like:
rollerskates
bowling ball

Whoops. My closets aren't behaving like separate instances! What is going on? Well, in prototype if an object receives a message and no slot exists to receive that message, it forwards that message up to its prototype. In this case, the closet slot is on the Closet prototype, so closet is like a class variable. It sounds simple, but it took me awhile to understand what was happening. I had been assuming that a "clone" was an object identical to its prototype, but it isn't identical at all. In fact, initially the closet clones have no state or behavior of their own. It felt like something was missing...

Of course! These clones need to be able to initialize themselves. With an init method each of the clones can have their own closet slot. No more shared state.

Closet := Object clone do(
init := method(
self closet := list()
)

stash := method(item,
self closet append(item)
)

peek := method(
self closet foreach(item, item println)
)
)

Run that the same way we did previously and you get:

My closet looks like:
rollerskates
Your closet looks like:
bowling ball

Which is what I meant originally.

They say learning 1 new language a year will make you a better programmer. Bruce's book can help keep you well ahead of that curve.