Squeak Smalltak, Does +, -, *, / have more precedence over power?

Viewed 159

I understand in Smalltalk numerical calculation, if without round brackets, everything starts being calculated from left to right. Nothing follows the rule of multiplication and division having more precedence over addition and subtraction.

Like the following codes

3 + 3 * 2

The print output is 12 while in mathematics we get 9


But when I started to try power calculation, like

91 raisedTo: 3 + 1. 

I thought the answer should be 753572

What I actual get is 68574964

Why's that?

Is it because that +, -, *, / have more precedence over power ?

2 Answers

Yes, +, -, *, / have more precedence than raisedTo:, and the interesting aspect of this is the reason why this happens.

In Smalltalk there are three types of messages: unary, binary and keyword. In our case, +, -, * and / are examples of binary messages, while raisedTo: is a keyword one. You can tell this because binary messages are made from characters that are not letters or numbers, unlike unary or keywords, which start with a letter or underscore and follow with numbers or letters or underscores. Also, you can tell when a selector is unary because they do not end with a colon. Thus, raisedTo: is a keyword message because it ends with colon (and is not made of non-letter or numeric symbols).

So, the expression 91 raisedTo: 3 + 1 includes two selectors, one binary (+) and one keyword (raisedTo:) and the precedence rule says:

first evaluate unary messages, then binary ones and finally those with keywords

This is why 3 + 1 gets evaluated first. Of course, you can always change the precedence using parenthesis. For example:

(91 raisedTo: 3) + 1

will evaluate first raisedTo: and then +. Note that you could write

91 raisedTo: (3 + 1)

too. But this is usually not done because Smalltalk precedence rules are so easy to remember that you don't need to emphasize them.


Commonly used binary selectors

@ the Point creation message for x @ y

>= greater or equal, etc.

-> the Association message for key -> value

==> production tranformation used by PetitParser

= equal

== identical (very same object)

~= not equal

~~ not identical

\\ remainder

// quotient

and a lot more. Of course, you are always entitled to create your own.

Smalltalk does not have operators with precedence. Instead, there are three different kinds of messages. Each kind has its own precedence.

They are:

  • unary messages that consist of a single identifier and do not have parameters as squared or asString in 3 squared or order asString;
  • binary messages that have a selector composed of !%&*+,/<=>?@\~- symbols and have one parameter as + and -> in 3 + 4 or key -> value;
  • keyword messages that have one or more parameters and a selector with colons before each parameter as raisedTo: and to:by:do: in 4 risedTo: 3 and 1 to: 10 by: 3 do: [ … ].

Unary messages have precedence over binary and both of them have precedence over keyword messages. In other words:

unary > binary > keyword

So for example

5 raisedTo: 7 - 2 squared = 125

Because first unary 2 squared is evaluated resulting in 4, then binary 7 - 4 is evaluated resulting in 3 and finally keyword 5 risedTo: 3 evaluates to 125.

Of course, parentheses have the highest precedence of everything.

To simplify the understanding of this concept don't think about numbers and math all the numbers are objects and all the operators are messages. The reason for this is that a + b * c does not mean that a, b, and c are numbers. They can be humans, cars, online store articles. And they can define their own + and * methods, but this does not mean that * (which is not a "multiplication", it's just a "star message") should happen before +.

Related