Dwemthy’s Array Sidebar 1

Hmm. VisualWorks has namespaces, which Smalltalk-80 does not, and they seem to have changed the way subclasses are defined. According to my copy of the purple book, a subclass is created by sending a class the message ‘subclass:’. It should be possible to implement a version of subclass in the Creature class that adds the extra code.

However, VisualWorks wants me to send ‘defineClass:’ to a namespace. Problem with that is I want to change the way subclasses of a particular class are defined. If I change the code in the NameSpace class that will affect every class that is ever created thereafter.

I hope VisualWorks hasn’t sacrificed this flexibility. I think that the original implementation was the correct one (classes create their children), and that it should have been possible to introduce namespaces without changing it, or at least get the method in NameSpace to delegate to the original code. Currently both mechanisms exist, although the original one appears to have been left there just for backwards compatibility.

Hopefully James or someone who knows more about VisualWorks than I do will read this and set me straight.


Added later: James happily responded. How many other product managers would personally respond to some random blogger’s idle meanderings?

Exploring Dwemthy’s Array (Part 1)

Dwemthy’s Array is a great example of the metaprogramming capabilities of Ruby.

At the heart of Dwemthy’s Array is the Creature class, and at its heart is the following code:

def Creature.traits( *arr )
return @traits if arr.empty?
attr_accessor *arr
arr.each do |a|
class_eval %{
class << self
def #{a}( val )
@traits ||= {}
@traits[#{a.inspect}] = val
end
end
}
end

This code declares a static (class) method that, when called with a list of symbols, creates a class method for each symbol that, when called, lazily instantiates a class variable, with the symbol’s string as a key and the method’s argument as the value.

The next chunk looks like this:

class_eval %{
def initialize
self.class.traits.each do |k,v|
instance_variable_set( "@" + k.id2name, v )
end
end
}
end

This section defines an instance method called initialize that will iterate through the list of traits (stored as a class variable) and create instance variables for each entry, named after the key, assigning them to each value. The initialize method is called by default when an object is instantiated.

In a nutshell, each subclass of Creature provides a prototype template that allows multiple instances to be instantiated with copies of the same data. The Creature class also allows for easy addition of new traits. Calling the traits method more than once will append the new values to the collection.

There’s a line in Creature like so:

traits :life, :strength, :charisma, :weapon

Creature and all its subclasses share the above common traits.

One of the subclasses, Rabbit, starts like this:

class Rabbit < Creature
traits :bombs
life 10
strength 2
charisma 44
weapon 4
bombs 3

It adds an additional trait called ‘bombs’. and sets the initial trait values for its instances by calling the class methods defined by the meta code in Creature.

One important point to note is that the ‘traits’ class variable is defined per-subclass, so each subclass (subclass, not object instance) gets its own local collection of traits.

Okay. Now I think I understand how it works. So can it be done in Smalltalk? I don’t know yet.

That’s Part 2.

The wheel: version 2.0

Sometimes it seems that the world can never have too many:

  • Bug tracking tools
  • Email readers
  • Wiki engines
  • Message boards
  • Blog engines
  • RSS readers

I don’t mean ‘instances of”, rather the number of different software implementations. I’ve lost count of the number of times I’ve heard or read (and thought or said), ‘I tried out foo the other day but it didn’t work exactly how I wanted so I thought I’d have a go at writing my own….’.

I take some heart from the fact that the majority of the above list (which was developed by the highly scientific method of me thinking about it for about 30 seconds) consists of communication tools. Forming connections with other people is clearly a basic human drive.

Every method is an interface

Another way of thinking about the difference between dynamic and static languages is how they express interfaces. For example, Java interfaces define a group of method signatures that a class must implement. There is no way of enforcing that different subclass implementations do roughly the same thing – its down to convention and good style.

A dynamic language such as Ruby or Smalltalk doesn’t have the concept of interfaces. Instead, each method signature could be considered as implicitly defining its own interface – an interface containing just that one method. When calling a method on an object, the object’s type is essentially irrelevant. All that matters is that it has a method whose signature matches the one you’re trying to call.

Great things I’ve never done

I regularly have ideas that are impossible, or forget within hours, have no clue how to implement, or no time, or all of the above. I really should make a list.

  • A squeak wrapper around the Gecko HTML rendering engine.
  • A simple, high quality probabilistic gossip based P2P framework (I actually started a Java version but got bored).
  • A tuple space implementation on top of the aforementioned simple P2P framework.
  • A mobile-code mechanism for the tuple-space, so arbitrary tasks can be submitted. The Jini model uses jars downloaded from a webserver, which isn’t really ‘grid’ enough somehow.

Programming as Literacy

In what’s typically called ‘the western world’, before literacy became essentially ubiquitous it was limited to a select few. Monks originally, then scribes. These individuals possessed a truly remarkable skill. They could make marks on paper that could remember things. They could capture information and retrieve it later. Associated with this skill was the ability to make marks that could perform complex computations and produce an answer. People with these skills were hired by nobles and merchants to increase business value.

You know what I’m going to say next of course.

Programming appears to have many parallels with literacy in medieval times. It is a somewhat arcane skill known to a select few, who typically put that skill to use for others in return for remuneration. There are very few scribes left nowadays, although I’m sure at the time they felt that as there would always be a need to write things down, that there would always be scribes.

It’s not technical

A counterpoint to this post from my colleague Sam.

It’s not technical. Languages don’t succeed for technical reasons. If this were true we’d all be programming in Lisp and Smalltalk. Java became popular by riding the internet (specifically the web) wave. .Net became popular because Microsoft have billions of dollars to spend on marketing. Both of these platforms have something in common – they are aggressively marketed by a big industry name.

Write once, run anywhere. Sun coined the term, and successfully won the mindshare. Developers working in Lisp & Smalltalk wondered what was so special about that.

Garbage collection. Most work in garbage collection was done in the 70’s and 80’s (possibly even earlier – Lisp has been around since the 60’s). Again marketed heavily by Sun, while the aforementioned Lisp and Smalltalk programmers looked on nonplussed.

Lisp didn’t take over the world because (to my knowledge) there was no big name vendor marketing it, and everyone outside the Lisp community thought it was just for AI.

Smalltalk didn’t take over the world because of infighting between vendors, and a failure to see the threat of Java. They were too busy competing with each other to notice that Java was about to swamp all of them.

Having said that, there are places where Smalltalk and Lisp are thriving, and those companies are more than happy for everyone else to remain distracted by Java and .Net while they consistently outperform them in time-to-market of new features.

Can your Rails do this?

Don’t get me wrong, I love Rails. Its great to see something that isn’t .Net or Java gaining traction. ThoughtWorks has an internal mailing list about it and the traffic has been impressive so far.

Its just that now more than 25 people have heard about it, well, it feels like its gone all mainstream.

So I’m splitting my cool-new-dynamic-language-based-web-application-framework bandwidth between Rails and Seaside.

Today I saw something in Seaside that gave me one of those ‘Dude, that so totally rocks‘ moments.

There’s an innocent toolbar option in Seaside called ‘Toggle Halos’ that switches on a visual representation of the components on a page, with some icons for each one. One of the icons looks like a spanner (wrench), and when clicked on, shows you the code for the component in your browser, and lets you edit it!

Oh yes. Welcome to really rapid application development.