Previous Table of Contents Next


These characters include the symbols most commonly used in algebraic notation for numeric expressions. This is not a coincidence. Binary selectors are most commonly used for messages that perform arithmetic operations or comparisons between the receiver and the argument. The use of binary selectors results in message expressions that appear similar to conventional algebraic expressions. Consider the following expressions, for example:

  123 + 456          “addition”
          579
  9 >= 10            “greater than or equal to”
          false
  true & false       “boolean and”
          false
  ‘abc’ , ‘xyz’      “string   concatenation”
          ’abcxyz’

When multiple binary messages are used to compose a compound message expression, the individual binary messages are evaluated strictly left to right. All binary selectors have the same precedence. Fortran-style operator precedence rules are not used. Consider the following example:

  1 + 2 * 3
          9    “Fortran or C would yield 7”

Parentheses can be used to alter the strict left-to-right evaluation order, as in this example:

  1 + (2 * 3)
          7

Even though binary selectors look like and are used as arithmetic operators, they are in fact regular message sends. The meaning of a selector, such as +, is dependent on the message receiver. Programmers can define new types of objects in which + or any other binary selector has meanings other than arithmetic addition.

Compound message expressions can also be formed from combinations of unary and binary message expressions. Unary selectors have higher precedence than binary selectors. Consider this line, for example:

  x squared + y squared

This code computes the sum of squares. Parentheses can also be used in such expressions:

  (x squared + y squared) sqrt

If this expression had not included parentheses, the receiver of the sqrt (square root) message would have been the result of squaring y, not the result of the addition of the squares.

4.2.3. Keyword Messages

The third syntactic form for message expressions is a keyword message expression. A keyword message expression has one or more arguments. Each argument is preceded by a keyword, which is an identifier immediately followed by a colon. The selector of a keyword message is formed by concatenating the keywords from left to right. Here are some examples of keyword message expressions:

  2 raisedTo: 16
          65536
  ‘abcdef’ copyFrom: 3 to: 4
          ’cd’
  #(12 13 14 15) copyReplaceFrom: 1 to: 3 with: #($a $b)
          #($a $b 15)

The first example has only one keyword and argument. Its selector is raisedTo:. The second example is a message with two arguments; its selector is formed by combining the keywords into copyFrom:to:. The last example’s selector is copyReplaceFrom:to:with:.

The order of the keywords is important because changing the order of keywords produces a different selector. Similarly, removing a keyword produces a different selector. A particular object could be a valid receiver for each of the following messages:

  anObject from: 1.
  anObject from: 1 to: 5.
  anObject to: 5 from: 1.
  anObject to: 5.

However, each of these messages has a distinct selector and would invoke a separate and distinct operation on the receiver.

Keyword messages can be combined with unary messages and binary messages to form a compound message expression. A simple, nonparenthesized expression can contain only a single keyword message. The keyword message has lowest precedence. The expressions defining the arguments are evaluated from left to right, and the keyword message itself is evaluated last. Here is an example of such a complex statement:

  aString copyFrom: aString size // 2 + 1 to: aString size

If a keyword message had been used in the subexpression for one of the arguments, parentheses would have been required:aString copyFrom: (aString size quo:2) + 1 to: aString size

Occasionally, the need arises to direct a series of individual messages to the same receiver. Smalltalk provides a syntactic construct called a cascade that facilitates this. If a message expression is immediately followed by a semicolon, then a message expression without an explicit receiver must immediately follow the semicolon. The receiver of the message to the left of the semicolon is also used as the receiver of the message expression to the right of the semicolon. For example, this code:

  anArray last
          start;
          continue;
          stop.

has the same meaning as this code:

  temp := anArray last.
  temp start.
  temp continue.
  temp stop.

An object’s behavior is defined by a set of methods. A method is essentially a function that consists of a sequence of Smalltalk message expressions. Each method also has an associated method selector. When a message expression is evaluated, its selector is used to find the method with a matching selector from the behavior of the object that is the receiver of the message. That method is then evaluated, and its result is used as the value of the original message expression.

4.2.4. Polymorphism with Identical Messages

Different Smalltalk objects can respond to identical messages in differing ways. This is called polymorphism. Polymorphism is possible because different objects can have different methods that match a particular message selector. The determination of which method is executed depends on the actual object that is the receiver of the message when the message is evaluated. Repeated evaluations of a particular message expression in the text of a Smalltalk program can result in the execution of different methods if each evaluation uses a different object as the receiver of the message.


Previous Table of Contents Next