Monday, December 5, 2011

Some nice words for Smalltalk

As part of a comment on an earlier post, Bob Calco writes some nice things about Smalltalk...
Now I'm getting into Smalltalk 'for real' and finding that the OO-ness of it is not even the main thing I find compelling: it's the live-ness of it. It's just easier to think about the abstractions 'in the present' as it were. 
I think Smalltalk takes the idea of live objects to such a level of sophistication that most people can't quite grok the Platonic Forms of domain modelling that swirl around the mind of an accomplished Smalltalk developer. 
and also
But folks who have come to think OO is more buzzword than reality could not possibly have tried Smalltalk, not 'for real,' let alone tried to get good at it. It's not just a language or even a platform but a way of thinking about reduction of a problem to its essence, as this article makes clear. 
I did leave out the bit in the middle where he has some thoughts for improvements like pattern matching, but they're at the bottom of the article. For myself I've never quite seen pattern matching as an especially valuable feature. To my mind the biggest gain is that it's a terse way of extracting out elements of a list -either a variable size list of arguments, or if you're in a language where linked lists are the primary data structure, being passed a list and automatically having it expressed as two variables represent first and rest. Other than that it just seems like syntactic sugar for a case statement. But maybe I'm missing something.


  1. Pattern matching is just syntactic sugar for case statements, but in this case it's a ├╝ber powered version of the case statement, one we can use to go deep inside a data structure without caring for the paths. In a sense pattern matching is the antithesis of OO, you must know about the object's structure and it's components' structures deeply in order to use them, but when used in functional programming they provide very clean ways to slice and dice a value.

  2. Thanks. A nice explanation. And yes, it does seem rather difficult to reconcile with having opaque objects.

  3. It's only difficult to reconcile with opaque objects until you realise that an opaque object may freely represent itself any way it likes.

    OMeta, for instance, allows one to pattern match against objects, and objects permit themselves to be pattern matched against by exposing a stream-like interface.

    Another name for pattern matching is destructuring. When a language supports it - like in Clojure - it permits lucid and terse code; code rather more lucid than case statements or visitors.

    What puzzles me is why noone just skips pattern matching in favour of unification (which is a _bidirectional_ pattern match). It's not much work to implement, and you get pattern matching for free!

  4. Hmm. I really need to bump up the priority on the to-do list item of looking at OMeta more seriously. Alex Warth's talk on it at Smalltalk Solutions a few years back was extremely good, but I've never gotten around to following up.

  5. Pattern matching in functional programming is a really powerful and expressive language feature, which I came to fully appreciate only when coding in Erlang and Haskell. You become dissatisfied with most languages that have case statements after playing with pattern matching for, say, five minutes. The code is so much easier to understand once you grok what's going on both syntactically and, more importantly, semantically, it's outrageous.

    Similarly, you become dissatisfied with most languages' syntax for method calling when you grasp Smalltalk's message-passing syntax and semantics. Suddenly, Objective-C makes sense. I never thought that could happen. ;)

    My ideal language would bring the best ideas from Erlang and Smalltalk together. Erlang's weakness -- data abstraction -- is Smalltalk's strength, and vice versa. Smalltalk lacks Erlang's process-oriented philosophy of fault-tolerance (and supervision), concurrency and parallelism. I suppose strictly speaking pattern matching in Smalltalk is unnecessary, as there are better idioms in Smalltalk for dealing with complex choices than case statements.

    But the idea I was trying to convey is that there must be some ideal way to blend functional and object-oriented paradigms that preserves elegance and comprehension in the code. To my delight, Smalltalk blocks have much in common with the lambda calculus functional programming really taught me to appreciate. But I wish I could count on it on multi-core machines or distributed environments like I can count on Erlang.

    F# and Scala are going in that 'hybrid' direction, but IMHO retaining to many of the bad features of both mainstream variants of those syntaxes. Mozart-Oz is an intriguing if obscure language that attempts to do this not just with OO and functional programming, but more ambitiously with several additional paradigms to boot. Unfortunately its syntax reminds me of Tcl, which always makes me want to take a shower for some reason. But I learned a lot studying it and owe my 'multi-paradigm' perspective to it.

    What I guess I was trying to convey in retrospect was simply that pattern matching opened my mind to better syntax than I had previously known for doing what I was normally doing in procedural and quasi-OO code in C++/Delphi/et al. Similarly, Smalltalk's syntax has been liberating my mind to think differently about how I solve problems in software design in-the-large. I'm embarrassed (just a little) to admit that I hardly knew what OO was about using the 'other' OO languages. Hence, I have experienced with Smalltalk a similarly positive association that I had with pattern matching when I first got the concept.

    I love the 'Aha' moments I've had so far, anyway. :)