Understanding Smalltalk Method Invocation with Multiple Colons

94 Views Asked by At

I'm currently learning Smalltalk, and I've encountered a behavior that I find puzzling regarding method invocation with multiple colons. I understand that colons play a crucial role in specifying method names and their arguments in Smalltalk, but I'm having difficulty grasping why the following two cases lead to different outcomes:

Example 1:

100 max: 50 max: 102

Example 2:

6 gcd: 3 factorial: 5

In Example 1, Smalltalk attempts to find a method named 'max:max:' with three arguments, while in Example 2, it correctly interprets the colons as separate messages, resulting in 'gcd: 3' and 'factorial: 5'.

I would appreciate clarification on the specific syntax and structural aspects that lead to these different interpretations by the Smalltalk interpreter. Additionally, any insights into how Smalltalk processes colons in method invocations would be helpful.

Thank you for your assistance!

3

There are 3 best solutions below

0
On BEST ANSWER

In Smalltalk, there are three types of message selectors: unary selectors (e.g., 2 negated), binary selectors (e.g., 2 + 3), and keyword selectors (e.g., 2 max: 3, 2 min: 20 max: 10). There are no operator precedences but messages get evaluated from the left to the right and you can use brackets to control the evaluation order.

In Example 1, Smalltalk attempts to find a method named 'max:max:' with three arguments, while in Example 2, it correctly interprets the colons as separate messages, resulting in 'gcd: 3' and 'factorial: 5'.

For any Smalltalk dialect I am aware of, this is wrong. There is no such thing as "automatic combination of selectors". If your implementation of 2 responds to the message max:max:, i.e., SmallInteger or one of its superclasses defines a method for this selector, this method will be executed. Otherwise, doesNotUnderstand: will be sent to the object which usually raises MessageNotUnderstood error. Analogously, 6 gcd: 3 factorial: 5 will trigger a DNU because there is no such method.

By the way, I am not aware of any factorial method that takes an argument (mathematical factorial n! is a unary function and implemented in Smalltalk as Number>>factorial, e.g., 3 factorial), so for the sake of the argument I will use raisedTo: instead, which computes the exponentiation of the receiver to the argument.

If you want to make explicit that you want to send gcd: first, use brackets:

(6 gcd: 3) raisedTo: 5

To compute the exponentiation first, use other brackets:

6 gcd: (3 raisedTo: 5)

HTH?

0
On

Unless you use parenthesis, keyword message sends look for a method that has all keywords. So, yes, the first looks for a single method named #'max:max:' and the second example looks for a single method named #'gcd:factorial:'. If you don't have a method in the receiver's class with the expected name, then the system will report an error.

So, if the second expression succeeds, then you have a method in your image for #'gcd:factorial' (which seems somewhat surprising). What dialect and version of Smalltalk are you using?

0
On

The Smalltalk code written like this

100 max: 50 max: 102.

is sending a #max:max: message  (which is one keyword message,
                                 composed of two 'keyword' parts
                                 'max:' and 'max:', and so expects
                                 two arguments)
to the receiver, which in this case is the integer 100.

Essentially equivalent to calling a C-like function written as

answer = selfMaxMax(100, 50, 102);

which might be described as a function with three arguments. I say 'essentially equivalent' because one could look at things this way, translating back and forth, while learning. But don't actually do it like this.

You want to learn to see and think of code as "a receiver, a message, and some parameters".
Because you can then compose these things, recursively. since each parameter is just some more code, with "a receiver, a message, and some parameters". For example, the #max:max: message above has two parameters, one of the parameters is "receiver 50 with no message and no parameters" and the other parameter is "receiver 102 with no message and no parameters". When you begin to see the code this way, a light goes on, and everything suddenly makes sense. Can take a few minutes to happen, for some people, or a few days, for others, but not very long. Once it happens, you're a Smalltalker).