For those of us that have always been fascinated with Smalltalk (but never managed to actually try it), Ralph Johnson has a great one-pager on Smalltalk’s syntax on the c2 wki.

Everything in Smalltalk is an object, and all computation is performed by sending messages to objects. Each object is an instance of a class. All instances of a class share the same methods and structure. Every class is a subclass of either another class or “nil” (a special object denoting “no value”). Each class “inherits” the methods and structure of its superclass. So, the key piece of Smalltalk syntax is the message.

There are three forms to the message send. Unary messages are named with a plain word, such as “beep” in (anyObject beep). Binary messages are made of one or two symbols, such as “+” in (17 + 5) or “>=” in (2 >= someVar). Keyword messages can take any number of arguments, with one colon (”:”) in the name for each argument. For example, the message at:put: takes two arguments, as in (myArray at: 3 put: ‘third’).

The expression (Rectangle new x: 13 y: 0) has two messages. The first is #new, which is a unary message. The second is x:y:, which is a keyword message with two arguments. Note that x: and y: are not separate messages; it is a single message with two arguments. If x: and y: were separate messages then we’d have to write something like ((Rectangle new x: 13) y: 0) to keep them separate.

The first line of a method defines the name of the method and the name of its arguments.

max: aNumber
^self < aNumber ifTrue: [aNumber] ifFalse: [self]

This is the max: method, which has one argument. The method sends the binary message < and also the keyword message ifTrue:ifFalse: It also has a return statement, which is what the ^ means. It also has blocks, which are represented by square brackets.