I Won!

Posted by Rick DeNatale Mon, 06 Jul 2009 16:44:00 GMT

I just got an email this morning informing me that my e-mail entry won a contest on boingboing gadgetsto win an original copy of each of the original Xerox Parc Smalltalk-72 and Alto manuals.

I'm looking forward to adding these to my collection of tech mementos.

The winning entry pointed to two articles I'd written here about Alan Kay

And I also threw in this scan of one of my current treasured mementos. This is an autograph page from the supplemental programming manual for Digitalk Smalltalk/V PM which was presented to me at Digitalk's developers conference. I'd been working closely with Digitalk on the release in my capacity as their liaison with IBM, and I gave a talk there.

Alan was also a speaker there. Alan had been instrumental in getting Digitalk to change the name of their product from Methods (which they'd picked to avoid issues with Xerox) to Smalltalk/V. I'm pretty sure that I'd already met Alan at one or two IBM internal OOP conferences. So Alan signed too, and I've highlighted his personalized autograph.

If you want you can click on the picture for a larger view.



Singleton Methods in Smalltalk and Ruby

Posted by Rick DeNatale Sat, 30 May 2009 21:29:00 GMT

Yesterday, Travis Griggs posted an interesting article on his blog about a couple of tricks he used to write a test which needed to ensure that a race condition actually happened during the test.

And Randal Schartz just discovered it too. These two posts point out some interesting similarities and differences between Ruby and Smalltalk.

Singleton methods

A lot of folks point to Smalltalk as a source for the kind of metaprogramming techniques that we Ruby programmers take for granted. Smalltalk does allow a lot of metaprogramming, but things like instance-specific behavior aren't part of the standard repertoire of most Smalltalkers. That's why Randal, who is no slouch at Smalltalk, expressed a certain amount of amazement at how Travis did this. Here's his (Travis') example Smalltalk code:

p := 4 @ 3.
p changeClassTo: (p class copy superclass: p class).
p class methodDictionary at: #negated put: (p class methodDictionary at: #transpose).
p negated

For those unfamiliar with Smalltalk, the expression 4 @ 3 creates an instance of Point, which is a 2-d point object with x=4 and y=3.

Let's write a Point class in Ruby which works like a subset of Smalltalk's Point

class Point
  attr_accessor :x, :y
  def initialize(x, y)
    @x, @y = x, y
  end
  
  def negated
    self.class.new(-x, -y)
  end
  
  def transpose
    self.class.new(y, x)
  end
  
  def inspect
    "#{@x} @ #{@y}"
  end
end

p = Point.new(4,3) # => 4 @ 3

p.negated
p.negated          # => -4 @ -3
p.transpose        # => 3 @ 4

Now , the above code might look something like this:

p = Point.new(4,3)
def p.negated
  transpose
end

p.negated # => 3 @ 4

Most Rubyists of any experience will recognize that what I've done is define a singleton method for that sole instance of point which overrides the negate method by calling transpose instead.

Another way to do this which might be a little bit more like what Travis shows in Smalltalk might be:

p = Point.new(4,3)
class <<p
  alias_method :negated, :transpose
end

Let's look at Travis' example and how he creates a 'singleton' class in Smalltalk. Here are the relevant lines:

p changeClassTo: (p class copy superclass: p class).
p class methodDictionary at: #negated put: (p class methodDictionary at: #transpose).

He gets p's class (which is Point up to now), copies it, and sets it's super class to p's class, effectively interposing the copied class object. Next he gets the transpose instance method from the copied class's method dictionary and replaces the negated method. Effectively what Ruby's alias_method does.

Now, I should point out here that Travis's example is probably specific to the Cincom VisualWorks Smalltalk dialect. The changeClassTo: method doesn't seem to be available in Squeak, although there might be a similar method, and I don't recall a similar method in the Smalltalks I've used in the past. Also changeClassTo: isn't entirely guaranteed to work, besides the cases where Ruby can't create a singleton class (for example immediate objects like FixNums), changeClassTo: requires that the 'shape' of the instance conform to the instance variable template defined in the new class, simplifying things a bit, that means that it needs to have either exactly the number of instance variables expected by the class, or at least the number of fixed instance variables expected by the class. Smalltalk classes can have a variable set of indexed instance variables which are placed after all the fixed (named) instance variables.

So let's end this exploration of comparative instance specific method creation between Ruby and Smalltalk before I move on to another interesting difference which Travis' article exposes:

  1. Smalltalk provides dialect-specific mechanisms for monkeying with the class of an object and manipulating methods.
  2. Ruby has some nice syntactic sugar for doing this in a way which is part of the language definition.

As a result, these techniques are far more commonly used in Ruby than in Smalltalk.

Now for the second difference, one where Smalltalk leaves Ruby a bit behind.

Turtles All the Way Down

One of the really interesting things about Smalltalk is just how much of the runtime system is exposed as 'normal' Smalltalk objects. In Ruby certain things are hidden away (sometimes not so securely) from the Ruby programmer, there's a "Wizard of Oz" behind the curtain which separates to the Ruby program from the VM (or interpreter if you prefer).

Almost everything the VM deals with in Smalltalk pokes up as one or more Smalltalk objects. In Smalltalk everything really is an object, it's turtles all the way down, at least it looks that way.

Travis' motivating problem was to force a race condition to occur on demand. Anyone who has done concurrent programming has learned that race conditions have probabilistic minds of their own.

The lever that Travis pulled was the fact that Smalltalk threads (which Smalltalk calls Processes for historic reasons) are implemented as Smalltalk objects which can be manipulated directly from Smalltalk. The Smalltalk IDE makes use of this. For example the Smalltalk debugger is really just a specialized inspector which inspects a Process object, including showing it's state (the stack frames) and manipulate it (breaking, stepping, and responding when class definitions change).

So Travis could grab the instance of a single process and change its instance-specific behavior to modify the way it handled termination in order to simulate the condition he needed.

This aspect of Smalltalk is something which many maybe too many Smalltalk programmers are familiar with. The second part of that old article link I just snuck in talks about the distributed version of Smalltalk I did at IBM many years ago which added a new kind of Process proxy which tied execution threads which crossed machine boundaries together allowing distributed debugging, exception handling etc.

Can Ruby get along without this? Sure. But it is one thing I miss from Smalltalk


Crash!

Posted by Rick DeNatale Thu, 05 Mar 2009 17:00:00 GMT

Recently posted on Ruby Talk, under the title ‘This System Must have been Written in Ruby’

At 1950 feet (around 700 meters) the airplane’s left altimeter suddenly and mistakenly registered an altitude of 8 feet (about 2 meters) below sea level and passed the reading on to the automatic control system, Van Vollenhoven said.

But the autopilot reduced gas to the engines and the plane lost speed, decelerating until, at a height of 450 feet (150 meters) it was about to stall. Warning systems alerted the pilots.

It appears that then the pilots immediately gave gas, full gas, however it was too late to recover,’’ ...The plane fell into a freshly plowed field, striking the ground tail first and breaking into three pieces.

I assume the poster’s position is that this is the kind of thing that happens when non-statically typed languages are used to implement mission critical functions.

I use to hear the same argument about C++ vs Smalltalk, from no less a luminary than Bjarne Stroustrup, who was wont to say that he would hate to fly in an airplane whose autopilot might throw a doesNotUnderstand: exception because of a type violation.

Okay, I admit it, the static type zealots are correct. Static typing absolves the programmer from worrying about:

  • Conceptual errors in the domain model.
  • The fact that a floating point number is a poor approximation of a real number.
  • Incorrect mathematical formulae, either due to misunderstanding, or typos.
  • User errors.
  • Off by one errors
  • Buffer overflows
  • Bad input data
  • Adding instead of subtracting, or vice-versa
  • Hardware failures
  • Errors in concurrency control
  • Your favorite bug here
  • The need to properly test the system.

If you believe that, or any significant portion of it, let me tell you about this bridge between Brooklyn and Manhattan which I have to sell you!

And if you believe that and rely on that faith to implement mission critical systems, please feature it in your advertisements, and let us know what mission critical systems were built that way, so that the rest of us can avoid them whenever possible.

Get Real!


Ward Cunningham on the Debt Metaphor

Posted by Rick DeNatale Mon, 02 Mar 2009 16:57:00 GMT

I just discovered that my old friend, Ward Cunningham has started putting some short interviews, and “video essays” up on YouTube

In the embedded video above, Ward relates how he came up with the metaphor of debt to explain the need for refactoring in interative development. The key insight is that you can proceed faster with an incomplete knowledge of the problem you are solving, and learn as you go. In many cases this is essential because for many problems the problem itself changes as implementation proceeds, because of effects like new feedback from users once they see the system starting to emerge. Ward compares implementation with incomplete knowledge to working with borrowed money. As the system implementation proceeds, the assumptions made on incomplete or out of date knowledge, which drove the design, or “architecture” if you prefer, of the system, start to make implementation of the more complete or evolved requirements progressively harder. In the debt metaphor, this increased cost of making progress corresponds to paying interest on the loan. Refactoring is a process of redesigning the software to reflect this new problem knowledge, without breaking it, thus “re-financing” the system.

Before I’d heard Ward express this metaphor, I’d come up with another for the same idea. One of my hobbies is metalworking. I saw an evolving system as a piece of metal which starts out as flexible and malleable. But like metal, as you start to form it by hammering, and bending, and other operations, it starts to “work-harden.” This means that the metal becomes more and more resistant to further shaping, because of local changes to it’s crystal structure. Eventually it resists all further efforts, often by failing with a stress fracture. This is why you can take a piece of, say copper, and bend it back and forth several times until it finally breaks at the bend.

In metalworking, you can use a process called annealing which returns the metal to a ductile, maleable state. Of course the analogy here is to refactoring.

I still like both metaphors, I tend to use my work hardening/annealing metaphor when talking to programmers, and Ward’s debt metaphor when talking to business people (the “gold donors.”)


Stout Man Talking

Posted by Rick DeNatale Thu, 26 Feb 2009 16:54:00 GMT

Better late than never

A few weeks back Jared Richardson interviewed me about the talk I gave at the inaugural RubyRX No Fluff, Just Stuff’s first foray into a Ruby oriented conference.

Although this was supposed to be published before the conference, it’s just now made it to the DZone web site. I hope you enjoy it.


Inject Some Thoughtful Craftsmanship Into Your Approach To Ruby Coding

Posted by Rick DeNatale Wed, 18 Feb 2009 16:52:00 GMT

For some reason, some people who hang out on ruby-talk seem to have a compulsion to periodically opine that “inject() is always the inefficient solution possible.”

I think that this statement, even if it were true, which I’m pretty sure it isn’t, being a claim for universality, isn’t particularly good advice.

My buddy Kent Beck has generated quite a few memes in the software development community. One of the more well known is “Make it run. Make it right, Make it fast.” Although the roots of this advice can be traced back to Butler Lampson. This is advice that anyone who wants to be a software craftsman needs to take to heart.

The order is important. First you make sure that the code runs, then you need to make it right. Making it right doesn’t mean that it does the right thing, that’s a large part of making it run, it mean’s making the code clear and maintainable, either by a future you, or by someone else. Only then you should make it fast, without unnecessarily affecting your success in keeping it right. And the best way to make it fast is to slavishly follow the 3 rules of optimization

While there are some who just seem to hate inject, it can, as you point out, be much more intention revealing, which helps in making the code right. In Ruby 1.9, the inject method also has the alias reduce, which is even clearer in the cases where there’s no initial value to inject into the enumeration. More languages use reduce for this case, and don’t provide an argument for the initial value at all. Ruby got the name inject from Smalltalk’s inject: aValue into: aBlock collection method where Smalltalk’s keyword message selector syntax does a better job of revealing the meaning of the parameters.

Now, that’s not to say that inject/reduce should be overused, the key tension is whether or not it is actually intention revealing, or overly clever, or even stupid. I confessed here some time ago, that I can be just as guilty as anyone of being cleverly stupid. But I don’t recommend it.

This is just one of those things, like when and when not to use optional parentheses in Ruby, which really need a bit of thoughtful reflection, rather than blind adherence to convention.


Alan Kay, Super Hero

Posted by Rick DeNatale Fri, 21 Nov 2008 05:03:00 GMT

Via Boing-Boing, Business week has just put a comic strip on their web site, which tells the story of how Alan Kay, inspired by a visit to Seymour Papert seeded the idea of portable computers.

Long term readers of this blog no doubt know that I hold Alan Kay in high regard. I got to meet him several times, first I think at an internal IBM conference on Object Oriented Programming in the mid 1980s, Another time was at a Digitalk developers conference, where I obtained a prize possession. At the time I was the IBM technical liaison with Digitalk. They released a new version of Smalltalk/V PM at this particular conference, and I was presented a copy of the supplemental manual for the release signed by all of the Digitalk developers, and also by Alan Kay, who wrote something like “to the most non-IBM like IBMer I’ve ever met.”

Reading the business week strip, I was reminded of an even earlier personal connection with Kay and Smalltalk. A year or so before I really got into Objects, I was working on IBM Mainframe software in Poughkeepsie, NY. One summer the project got an intern, named Radia Perlman, who was in graduate school at M.I.T. And is now known as the “mother of the internet” for her invention of spanning-tree protocol. It was only later that I learned that she was one of Papert’s students working on Logo and seeing how kids learned programming with Logo, and if I recall correctly she also visited Xerox PARC, and was involved in porting the concept of the Logo turtle model of graphics to Smalltalk, where it became the Pen object.

What a long strange trip it is!


The Pros and Cons of 64-Bit Architectures

Posted by Rick DeNatale Sat, 01 Nov 2008 13:17:00 GMT

My former OTI colleague Andrew “Roo” Low just wrote an interesting article about the trade-offs involved in designing a VM (and software in general) to exploit 64-bit machine architectures. Although, Roo discusses JVM implementation, he also grounds it with his experiences developing the IBM/OTI Smalltalk VM, and the lessons would be equally applicable to, say, a Ruby implementation.


Will It Go Round in Circles?

Posted by Rick DeNatale Wed, 15 Oct 2008 19:24:00 GMT

I really like seeing the resurgence of interest in my second most favorite programming language

One of the comments to the referenced Gartner Group blog post had a link to an IBM Developer Works article about using using Eclipse as a Smalltalk IDE.

It seems like a strange loop, since Eclipse is the descendant of IBMs old VisualAge. Now I happen to know a bit about this since I was involved at the beginning. I guess that enough time has passed that nothing I say here will affect anyone’s business.

IBM, Smalltalk, and VisualAge

VisualAge started out as a demonstration prototype I wrote using Digitalk Smalltalk/V. The idea was to make something like the NeXT interface builder in Smalltalk as an adjunct to the Smalltalk IDE. For those who are not hip to such things, the Interface Builder, originally a Lisp program before Steve Jobs hired the author, lives on as part of Apple’s XCode tool suite for OS/X for the Mac and the iPhone.

The demo got some key IBM executives excited, and so the VisualAge development organization was born. Development proceeded using Smalltalk/V, along with Object Technology International’s (OTI) Envy/Developer, which was the state of the art version and configuration management for Smalltalk team programming.

As the project progressed, IBM and Digitalk had a falling out over conflicting views of who should be doing what. I’d shown the prototype to them in my position as liaison between the two companies, and they launched their Look and Feel kit which was seen by IBM management as competition from a supplier. So since we already had a relationship with OTI because of Envy/Developer, and OTI was in the business of building Smalltalk VMs, including the VM used by Digitalk’s Smalltalk/V for the Macintosh, IBM switched horses and contracted OTI to build “IBM” Smalltalk. This eventually led to the acquisition of OTI by IBM Canada.

This was about the time we founded the ANSI X3J20 committee to forge a standard across the existing and emerging Smalltalk implementations. I served as the secretary of X3J20. Some of the other members included Peter Deutsch and Glenn Krasner of ParcPlace, which Xerox had spun-off from their Palo Alto Research Center to commercialize Smalltalk-80; George Bosworth of Digitalk; Allen Wirfs-Brock of Instantiations one of the more successful Smalltalk consulting companies in the Portland Oregon suburbs; David Simmons who was the brains behind the iconoclastic Smalltalk/Agents; and Bruce Schuchardt who worked for Servio-Logic or Gemstone, I can’t recall which name they were going under at the time. I’m sure that I’m forgetting some of the players, but I’ll plead senility.

One of the great joys of working in Smalltalk during it’s first “glory days” was the opportunity to work with and exchange ideas with such brilliant people in IBM, OTI, and other companies.

VisualAge grew to become an entire family of development environments for several of the IBMSAA” programming languages. There was even a VisualAge for Cobol! All of the various flavors featured an IDE written in IBM Smalltalk.

Enter Java

When Java “reared it’s head.” IBM, of course came out with VisualAge for Java. Again, the IDE was written in Smalltalk, although, in order to accomodate Java execution, OTI developed what was called the UVM (or Universal Virtual Machine) whcih could execute both Smalltalk and Java byte-codes, and used Smalltalk to implement the Java primitive functions which were implemented in C in the Sun JVM.

IBM eventually switched its focus from Smalltalk to Java. After considerable thought about this, and conversations with those who were in a position to know, I’m now convinced that this had nothing to do with the relative technical merits, and everything to do with a combined IBM/Sun platform play against Microsoft.

VisualAge for Java did eventually move away from the UVM for Java execution, primarily because the Java language had evolved to provide a standard C api for extensions. OTI began implementation of a new JVM, which was dubbed J9, which was built from the ground up to be usable in embedded systems.

OTI had a reputation of fostering the use of Smalltalk in embedded systems. When I first became aware of them in the early OOPSLA days, they were showing off products like an HP Network Analyser, and a TekTronix Digital Oscilloscope which used Smalltalk to implement their user interfaces. They were also involved with a large semiconductor company in Texas which was planning to use Smalltalk in controllers in an automated IC fabrication facility.

Around the time of the birth of J9, IBM was becoming quite interested in embedded software, under an initiative called Pervasive Computing (PVC). Because of this, OTI now an IBM Subsidiary, started working on VisualAge Micro Edition, which bundled J9 with an cross-platform IDE written, this time, in Java. About this time, I moved from IBM to OTI, and ended up working on the VAME IDE.

The Emergence of Eclipse

Work on VAME was distributed between various OTI labs. The lab in Phoenix acted as the liaison with the IBM PVC folks, the J9 VM work was done in Ottawa, Raleigh did some applications work, and some UI work, but the bulk of the VAME UI framework was done by Erich Gamma’s team at OTI Zurich. The IDE used Swing, as most Java desktop apps did in those days, and apparently that was a bit of a struggle. OTI used to have an annual all-hands internal developer conference in sunny early February Quebec, and I’ll never forget Erich, who is quite the Alpine skier, talking about the UI while showing a slide he took at some ski report showing a sign with a precariously oscillating chair-lift and a skier about to fall, with the text “Don’t Swing!”

This led to the desire to develop a new UI framework and what is now known as the standard widget set or SWT.

And the overall IDE/UI framework which replaced VAME was, of course Eclipse.

And now it seems we’ve gone from a Smalltalk IDE hosting Java development to the reverse!

Where Are They Now

Digitalk eventually merged with ParcPlace to form ParcPlace-Digitalk. For a while, both Smalltalk/V and VisualWorks/Objectworks (the ParcPlace Smalltalk-80 products) were carried, but eventually VisualWorks survived. It’s now shepherded by Cincom, which bought the rights.

Similarly, IBM eventually sold the rights to market and develop VisualAge Smalltalk (a.k.a. VAST) to Instantiations. My old friend and colleague from IBM John O’Keefe “retired” from IBM to lead the development team.

Several of the X3J20 guys went to or through Microsoft. George Bosworth worked for several years on a precursor to today’s Microsoft DLR. Davd Simmons and Allen Wirfs-Brock both work on Javascript for Microsoft.

And, of interest to the Ruby community, Gemstone is now working on Maglev, a Ruby implementation with persistent objects based on their mature Smalltalk product.


What Would You Miss If You Had To Stop Using Ruby and Go Back to Smalltalk?

Posted by Rick DeNatale Wed, 21 May 2008 20:58:00 GMT

Last night, James Robertson from Cincom, presented Smalltalk and Seaside to the Raleigh Ruby Brigade.

It was an interesting deja-vu experience, since in my younger days, part of my job with IBM was evangelizing Smalltalk, much as James does today. It was interesting to see what has and hasn’t changed. For the most part the things about Smalltalk which were blessings and curses (or many times both) haven’t changed. The IDE is still powerful. It gets much of it’s power from Smalltalk’s model of how source code and run-time implementation objects like compiled-methods, classes and metaclasses interact, but the consequence is that there aren’t really Smalltalk source files to use with popular editors like VIM or EMACS or Textmate. The question came up about whether the Smalltalk IDE supported the notion of giving the code to an external editor, and the answer was that the size of a typical Smalltalk method, which is the unit of editing, was so small (10 lines is a long Smalltalk method) as to make it ‘moot.’ I used to get the same kind of questions and give pretty much the same answers.

One area where Smalltalk really does excel is in it’s debugging and inspection tools. The same implementation object model which enables browser features, like finding all senders or implementers of a message using structural rather than textual searching, also allows live debugging, where you can not only inspect the run-time state at a breakpoint, or when an exception occurs, but actually make changes to the running code, and compile those changes, at which point the VM prunes the invocation stack down to the point of the change and allows you to restart from that point. Protestations from TDD/BDD adherents that you don’t need no steenking debugger if you follow TDD practice, the Smalltalk debugger was tool much favored by the very people, like Kent Beck, who invented TDD. Many Rubyists who were around for more than a year or two had an anti-debugger attitude, generated more, I suspect, by the lack of a decent Ruby debugger than any real hatred of debuggers.

Now that ruby-debug has been around for almost two years, the situation is much better. Ruby has a fairly competent debugger which allows stepping through code. It’s still hampered by Ruby’s rather simple run-time meta information, being forced to work on a line-by-line mode, rather than being able to step through individual expressions as can the Smalltalk debugger. And we’re still a long way from the live surgery capabilities I described. Perhaps as Ruby VM implementations mature we might see some of these advanced features emerge, perhaps this is something which the Rubinius implementers might also take as an inspiration from Smalltalk. This is one of the main things I miss from my Smalltalk days.

On the other hand, at this point in time, I’m really much happier working in Ruby than I think I would be were I somehow forced to work in Smalltalk again instead. Much as I love it, Smalltalk is now my second favorite language.

At one point last night, Brian Adkins asked me the question which is the title of this article. I think it’s a fair question, and I’m not sure I know exactly, but let me try to answer it.

What I’d miss from Ruby

I’ve said this before, but one of the things I like about Ruby is that it is more dynamic than Smalltalk in ways which I like, and cuts back on other aspects of Smalltalk which I don’t think are really that important.

One of the things I like about Ruby is the elimination of variable declarations. A good example of this was that during the Seaside demo last night, James showed how interfacing to the database requires attribute instance variables in model objects to be declared. Now the IDE provides tools for helping with this, you get prompted with a list of column names and can add them one by one just by clicking buttons. Contrast this with ActiveRecord where model objects just acquire instance variables dynamically at run-time. Now I know that some prefer more explicit mappings, but personally I feel that the dynamic mapping provides much more capability for much less ceremony.

The ways in which Ruby is more dynamic than Smalltalk seem to me to provide better facilities for building low-ceremony architectures and artifacts like Rails, Rake, etc. There are more dynamic languages than Ruby to be sure, such as Self, and from what I can sense JavaScript, but Ruby seems to strike a very nice balance.

Much has been made of the legacy of Smalltalk in pioneering metaprogramming, although some Lisp guys might quibble with that, and in truth, most Smalltalk metaprogramming was only used to support the IDE and never put to use by application programmers. Alan Kay used to say that he was disappointed that no one seemed to make new classes of Behavior (which is the superclass of both Class and Metaclass in Smalltalk). I know he said this to some of us at an IBM internal conference, which at least led to Dave Smith and Jerry Archbald developing a “behavior of behavior” tutorial which ran for several years at OOPSLA. But Rubyists have taken metaprogramming much further than I recall from my Smalltalk days.

On the other end of the scale, Smalltalk as James pointed out, as I used to, has a very simple syntax, a few reserved words (self, super, nil, true, and false), three types of messages (unary, binary, and keyword), two operators (:= for assignment, and ^ for return), and a few more things for defining block literals.

Now when I was doing James’ job, this got mixed reactions. Some people took to syntax like:

topLeft = Point x: 3+2*5 y: 15

While others found it just a little too strange, something which we Smalltalkers just couldn’t get.

Another thing which put off newcomers to Smalltalk was that, because of the simplicity of the language, and the lack of any form of operator precedence (remember the only operators are := and ^), that subexpression 3+2*5 evaluates to 25 and not 13.

Ruby trades off a little simplicity and does provide precedence between messages which seem like they should act as operators.

I’m not saying that Ruby is without quirks, just that different people react to different quirks in different ways. If you don’t like what you perceive to be the quirks of any programming language, you won’t be convinced, even by the most ardent supporter of those quirks.

One of the interesting effects of the Smalltalk syntax was that, as we observed back in Smalltalk’s heyday in the Enterprise (late ’80s-early ’90s), it seemed that a lot of COBOL programmers seemed to take to Smalltalk. We used to think that Smalltalk might actually become the 21st century COBOL, until the “Enterprise” got wooed away by EJBs and the like. The same things which made Smalltalk approachable by COBOL programmers made it seem weird to those who looked down on those COBOL programmers as “trade-school” programmers.

Another much-touted feature of Smalltalk, is that everything is done by message sending, even control flow. In Smalltalk a if/then/else control flow is achieved by sending an ifTrue:ifFalse: message to a boolean object as in:

 ^(x = 0) ifTrue:[a] ifFalse:[b]

Smalltalk evaluates this as if the the expression (x = 0) is evaluated by sending the message with the selector = and argument 0, to the object referenced by x. The result of that message, an object of course, is then sent the message with the selector ifTrue:ifFalse: and the arguments [a] and [b], which are two blocks. What happens is up to that object. Typically that object is either true (the sole instance of the class True) whose ifTrue:ifFalse: method evaluates the first argument, or false (the sole instance of the class False) whose ifTrue:ifFalse: method evaluates the second argument. Very neat and conceptually clean. It allows you to define your own control flow methods.

Ruby on the other hand compiles if statements and their kind as tests and branches, much as a C compiler would. We trade off a little flexibility for performance.

But, in my experience, that flexibility rarely got used in Smalltalk. Not only that but, in my day at least, the Smalltalk compilers would also compile ifTrue:ifFalse: to a test of the result of the ‘receiver’ and a branch. In fact I just tried defining a FakeBoolean class with an ifTrue: method and when I try to use it I see this:

must_be_boolean

That NonBooleanReceiver exception is like seeing the Wizard of Oz behind the curtain, this notion of no control flow, just messages is actually a bit of an illusion.


Again, while Ruby doesn’t even pretend to implement all control flow by messaging, it provides most of what the underlying Smalltalk mechanisms are really used for in the form of blocks used to implement iterators.


There are other aspects of Smalltalk which are both blessings and curses. The fact that Smalltalk has a persistent run-time image, containing all the development tools, which can be saved along with its state of execution, and restarted is quite powerful, alien to many programmers, and can drastically change your approach to deployment. Back when I was doing Smalltalk we always struggled with issues like the footprint of the image, how to strip out the development tools before deployment, and start-up time. Some of these problems might seem to be less severe with today’s hardware, but they are still issues.


I feel that I might be coming across a little too harshly on my old friend Smalltalk. It still provides a great programming environment, and serves as a source of inspiration which shouldn’t be overlooked, and I hope to see some of the powerful development tool features from Smalltalk appear with help from support in some of the emerging Ruby implementations. I’m glad to see that it seems to be making somewhat of a resurgence, along with dynamic languages in general. But for me right now, while I wouldn’t be unhappy if I had to go back to Smalltalk, but I feel happier with Ruby.