I'm currently working at Ta Mère SCRL a small development shop in Belgium.
We mainly do mobile apps (iOS, Android) for clients. We also have a strong interest in Pharo Smalltalk and Rust.
After my previous post about the Pharo ecosystem, some people asked me more about a comparison of Smalltalk and Ruby. And how a Rubyist could leverage his knowledge when learning Smalltalk.
The two languages are class based, dynamic and their supporters like their clean and easy syntax. Actually, Smalltalk is sometimes considered as one of the father of Ruby. They share quite a lot and most of the patterns used in one can be easily expressed in the other.
This post does not cover the basic syntax of Smalltalk. If you want to learn it (15 minutes max), wikipedia should be enough.
Ruby comes in different flavors: MRI, YARV, Rubinius, JRuby, Maglev, etc. So does Smalltalk. The principal difference is that they are no “official” distribution. Every dialect has its own ecosystem and tools. Some are open source, some are proprietary.
Choosing an implementation can be a quite challenging task. If you want to go the open source way:
Gemstone is not only a Smalltalk implementation but also an extremly scalable object-database. Actually Maglev is a Gemstone based products. If you’re serious about Ruby, you should definitely give Maglev a look.
My favorite implementation is Pharo. I like the energy in the community and its direction. It is for me the best bet for the future. It very similar to squeak but this screenshot of the main menu is enough to convince me.
You can follow this thread on stackoverflow to get the opinions of others.
Here comes the biggest problem when learning Smalltalk. That’s where people usually get lost. Smalltalk code does not lie on a plain text file. There are literally no “code time”, it’s always runtime. It would be like coding in an IRB session. You manipulate objects all the time. Consequences ?
5? Change its value to see what happens.
Actually some tools are starting to appear in Ruby. Pry is pretty damn cool Ruby tool. Once you’ll get used to Smalltalk environments you’ll want more.
When you load a library in your image, it lies next to your code. You can then read it, inspect it, put breakpoint in it and do whatever you want with it.
An image contains your code and all the libraries you want. It acts as a container and is completely independent from other images.
Okay, that one is tricky. What do you expect from meta-programming?
method_missing in Ruby,
doesNotUnderstand must be used carefully. The usual advice applies in Smalltalk.
Actually defining a class in Smalltalk is just sending a message (“calling a method” in Smalltalk jargon) to the class
Object. Adding a method is also a matter of sending a message to define it. The only difference is that you use tools to do it. Remember, it’s runtime and your environment is the running your code. That living environment comes with great responsibilities. If you try something along
Object := nil I guess you’re a footing yourself in the foot.
If you want to learn more about the Smalltalk object system, I warmly recommend the chapter 13 of the Pharo By Example free book. If you don’t know that much about Ruby’s object system, I recommend the Dave Thomas presentation at Scotland on Rails 2009.
Methods need explicit returns (with
^). If omitted, the method will return self.
You get implicit returns for blocks: the value of the last instruction is the the value returned by the block. If you return (with
^) inside a block, it is a return value for the method.
Methods name and variables are spelled in CamelCase. Abbreviations are usually avoided. Smalltalk uses keyword based method name (as in Objective-C). Many Ruby libraries/framework mimic this by passing an hash as argument.
The tabs vs. spaces does not exist in the Smalltalk community. In every tool, press
Tab to indent and you’re done.
As usual, just keep the global syntax style of the project you’re working on.
Be careful when using cascades, a common is mistake is the following:
programmingLanguages := OrderedCollection new add: 'Ruby'; add: 'Java'; add: 'Haskell'.
In the end of the execution, programmingLanguages will be the String
Haskell. That’s because the method
add: returns its argument, not
self. To prevent this, send
yourself at the end of the cascade:
programmingLanguages := OrderedCollection new add: 'Ruby'; add: 'Java'; add: 'Haskell'; yourself.
Another trick of the the language is the evaluation order:
3 + 4 * 5 #=> 35 and not 23
Evaluation is done from left to right. Mathematical order is not preserved. Indeed,
* are simple methods. Smalltalk does not even know (and does not care) that it is executing mathematical instructions. You must use parenthesis to express precedence:
3 + ( 4 * 5 ) #=> 23
My previous post will explain you how to version Smalltalk code. Do not expect
Subversion (although they can be used as backends for Monticello).