Rant on retail

Supermarkets in the UK are posting record profits. 1 out of every 8 pounds spent in UK shops is spent in Tescos.

Independent retailers are understandably concerned about the threat to their business. Although apparently not enough to do much about it. I, like many people, leave for work before 9, and return after 5.30. From my perspective small retailers are actively avoiding my business. They wait to open until after I have left in the morning, and they make sure they’re closed before I return. Is it any surprise that I go to the large supermarket on my way home from work? It’s the only shop still open! Local retailers seem to be stuck in an era when we all lived in villages and the wife stayed home and did the shopping.

Advertisements

Alan Kay on software

From The Early History of Smalltalk:

I think the enormous commercialization of personal computering has smothered much of the kind of work that used to go on in universities and research labs, by sucking the talented kids towards practical applications. With companies so risk-adverse towards doing their own hardware, and the hardware companies betraying no real understanding of software, the result has been a great step backwards in most respects.

A twentieth century problem is that technology has become too “easy”. When it was hard to do anything whether good or bad, enough time was taken so that the result was usually good. Now we can make things almost trivially, especially in software, but most of the designs are trivial as well. This is inverse vandalism: the making of things because you can. Couple this to even less sophisticated buyers and you have generated an exploitation marketplace similar to that set up for teenagers. A counter to this is to generate enormous disatisfaction with one’s designs using the entire history of human art as a standard and goal. Then the trick is to decouple the disatisfaction from self worth–otherwise it is either too depressing or one stops too soon with trivial results.

I will leave the story of early Smalltalk in 1981 when an extensive series of articles on Smalltalk-80 was published in Byte magazine, [Byte 1981] followed by Adele’s and Dave Robsons books [Goldberg 1983] and the official release of the system in 1983. Now programmers could easily implement the virtual machine without having to reinvent it, and, in several cases, groups were able to roll their own image of basic classes. In spite of having to run almost everywhere on moribund HW architectures, Smalltalk has proliferated amazingly well (in part because of tremendous optimization efforts on these machines) [Deutsch 83]. As far as I can tell, it still seems to be the most widely used system that claims to be object-oriented. It is incredible to me that no one since has come up with a qualitatively better idea that is as simple, elegant, easy to program, practical, and comprehensive. (It’s a pity that we didn’t know about PROLOG then or vice versa, the combinations of the two languages done subsequently are quite intriguing).

While justly applauding Dan, Adele and the others that made Smalltalk possible, we must wonder at the same time: where are the Dans and the Adeles of the ’80s and ’90s that will take us to the next stage?

Getting meta

Okay, so the investigations continue. As mentioned previously I’m attempting to reimplement Dwemthy’s Array in Smalltalk. There are a couple of ways to port code from one language to another.

One approach is to attempt a ‘direct translation’, changing as little as possible outside the syntax. This has the benefit of making it easier to mentally flip back and forth as the code is ported. The difficulty depends on how similar the features of the 2 languages are. For example, transliterating idiomatic Lisp code to, well frankly, any non-Lisp based language would be exceedingly challenging. There is also the risk of being sucked into having to reimplement a bunch of the standard libraries of the source language in the target language.

The other approach is to establish a high level picture of the intent of the original code, and reimplement that in terms of the target language. The benefit here is being able to take full advantage of the idioms of the target platform. The disadvantage is obviously that subtleties of the original behaviour may be lost in the conversion.

Imagine a conversation conducted using a translator. A word for word translation might be more accurate but probably makes less sense in the target language, while a translator who digests an entire sentence and reiterates it in the colloquial form of the target language might well make more sense to the listener, but there is an increased need for the translator to understand the subject under discussion.

For the purposes of my journey I’m taking the direct translation approach. As Dwemthy’s Array uses some pretty exotic features of Ruby this is probably the more challenging of the two approaches, but that just makes it more interesting.

First off, I think I need to be able to extend the subclassing functionality of VisualWorks. The standard system creates subclasses by sending a message to a NameSpace object. This is a problem as I want to intercept the call for a specific class (Creature) and do some extra stuff. The current VisualWorks code looks like this:

defineClass: className superclass: superID indexedType: typeName private: isPrivate
instanceVariableNames: iVars classInstanceVariableNames: ciVars
imports: pools category: category attributes: attributes

| superclass approved class cbr mbr |
superID == nil
ifTrue: [superclass := nil]
ifFalse: [superID binding isForClass
ifTrue: [superclass := superID value]
ifFalse:[self error: (#SuperclassMustBeAClass <>
'The superclass of a class must also be a class')]].
Behavior checkLegalBehaviorType: typeName.
approved := SystemUtils
validateClassName: className
for: nil.
approved == nil ifTrue: [^nil].
cbr := (BehaviorBuilderRecord forName: approved in: self)
superclass: superclass;
instVarString: iVars;
category: category;
attributes: attributes;
behaviorType: typeName;
importString: pools;
private: isPrivate.
(mbr := MetaclassBuilderRecord new)
forInstance: cbr;
instVarString: ciVars.
class := ClassBuilder new
addRecord: cbr;
addRecord: mbr;
reviseSystem.
^class

What I actually want is for most of this code to live in the Class er, class so I can hook it from a subclass. The first chunk is all about making sure the superclass of the class under construction exists, so I don’t need that. I think I can take all the code from the line that starts ‘Behaviour’ and drop it into the Class um, class more or less verbatim, flipping around the references to ‘self’ and ‘superclass’ and adding ‘aNameSpace’ parameter:

subclass: className nameSpace: aNameSpace indexedType: typeName private: isPrivate
instanceVariableNames: iVars classInstanceVariableNames: ciVars
imports: pools category: category attributes: attributes

| approved class cbr mbr |
Behavior checkLegalBehaviorType: typeName.
approved := SystemUtils validateClassName: className for: nil.
approved == nil ifTrue: [^nil].
cbr := (BehaviorBuilderRecord forName: approved in: aNameSpace)
superclass: self;
instVarString: iVars;
category: category;
attributes: attributes;
behaviorType: typeName;
importString: pools;
private: isPrivate.
(mbr := MetaclassBuilderRecord new)
forInstance: cbr;
instVarString: ciVars.
class := (ClassBuilder new)
addRecord: cbr;
addRecord: mbr;
reviseSystem.
^class

The code in NameSpace then changes to:

defineClass: className superclass: superID indexedType: typeName private:
isPrivate instanceVariableNames: iVars classInstanceVariableNames: ciVars
imports: pools category: category attributes: attributes

| superclass |
superID == nil
ifTrue: [superclass := nil]
ifFalse:
[superID binding isForClass
ifTrue: [superclass := superID value]
ifFalse:
[self error: #SuperclassMustBeAClass <> 'The superclass of a class must also be a class']].
^superclass
subclass: className
nameSpace: self
indexedType: typeName
private: isPrivate
instanceVariableNames: iVars
classInstanceVariableNames: ciVars
imports: pools
category: category
attributes: attributes

Important thing I learned: an instance method of class Class is inherited as a class method of normal classes.

Minor aside: here I am changing the way classes are defined. I’d have been up to my armpits in the guts of the VM by now if this was Java.

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.