'how to simplify smalltalk expression by using as less brackets as possible
im new to smalltalk. I and in my online course I got the exercise task to simplify an expreesion:
((7 + 5) + (31 * 8) - (51 * 2))
I tried different things out but to be honest I dont understand the syntax and everything else in Smalltalk. I could also not find good youtube tutorials. Can someone help me and explain me of to use as less brakets as possible? and if there are good pages/videos to learn Smalltalk please let me know.
Solution 1:[1]
Short answer:
7 + 5 + (31 * 8) - (51 * 2)
Background: Smalltalk has a uniform metaphor and syntax whose expressions are messages of the form receiver selector argument(s)
. Here uniform means, well, uniform. For example the sum 7 + 5
is a message with receiver 7
, selector +
and argument 5
. Similarly, in 31 * 8
the receiver is 31
, the selector *
and the argument 8
.
The idea is that, in Smalltalk, messages are the only computation and therefore all actions are message sends. This might sound strange at first glance, but is actually a very smart simplification: messages are the only concept you have to master.
Explanation: Let's now consider the first part of your expression
(7 + 5) + (31 * 8)
Since messages are the main construct, we can get rid of the first pair of parentheses: once we parse 7 + 5
, we already have a complete unit of computation. Now, mentally replace this message with its answer: 12
and advance to the next message. You get: 12 + (31 * 8)
, right? This means that this time the argument of +
is 31 * 8
.
Ok. So far we know that (7 + 5) + (31 * 8)
is the same as 7 + 5 + (31 * 8)
, which agrees with our knowledge of mathematics. The question is, can we get rid of the parentheses around 31 * 81
? The answer is no, we can't. Let's see why. Once we replace 7 + 5
with 12
, after removing the parentheses we would get 12 + 31 * 8
. If we now parse this expression we will stop right after reading 31
and will interpret that the message just read is 12 + 31
. Then we would replace this with 43
and look for the next message: 43 * 8
. The actual intend, however, was to have 31 * 8
as the argument of +
sent to 12
, i.e., 12 + (31 * 8)
.
In contrast, in the traditional notation, when we say 12 + 31 * 8
, we think of someone (or something) who would apply the precedence rules and sum 12
with 31 * 8
. Who incarnates such a role? The system? the computer? us? In Smalltalk that someone or something is always explicit: it is the receiver of the message. That's why you don't think of 7 + 5
as an instruction to someone to take care of the sum, you explicitly asks 7
to perform + 5
and provide the result. This is a subtle but important conceptual difference, not just a notational eccentricity.
The last part can be analyzed in a similar way.
Addendum
One of the comments mentions another answer, namely
7 + 5 + (31 * 8 - (51 * 2))
While this expression would give the same result, it is computationally different from
7 + 5 + (31 * 8) - (51 * 2)
Once again, understanding the difference is a good exercise, so let's do it!
Since the first part is the same in both expressions the issue reduces to compare
12 + (31 * 8) - (51 * 2)
with
12 + (31 * 8 - (51 * 2))
In the first expression the argument of 12 +
is 31 * 8
. In the second 31 * 8 - (51 * 2)
. So, these messages aren't the same: they differ in the argument.
Of course, one may be tempted to say: yes, but the result is the same. Sure it is. But what we are trying to do here is to get rid of unnecessary parentheses, and not to find a shorter expression that would give the same result. Had this last one be the problem, the correct answer would have been 158
.
Addendum 2
A question remains (see the comment below). Is the syntactic difference between both expressions relevant? Yes, it is and here is why.
To better analyze the issue, let's simplify and abstract it by considering the difference between
a + (b - c)
and
a + b - c
The latter expression first performs a + b
and then subtracts c
. Now, imagine that these quantities are floats. Consider the case where a = b
and c
is greater enough than b
so that b - c
evaluates to -c
but 2*b - c
doesn't (in other words, c
doesn't notice b
but does notice 2*b
). Then a + (b - c)
would first evaluate to a - c
and then to -c
while a + b - c
would evaluate to 2*b - c
, which is different.
Solution 2:[2]
As an answer to the question as asked:
The number of parentheses can be reduced by rearranging the terms to take advantage of the order in which expressions are evaluated when there are no parentheses.
Using the rules for Smalltalk, (as described in the answer above) we're allowed to simplify an expression like this:
((7 + 5) + (d * c) - (b * a))
by rearranging the terms like this:
c * d - (a * b) + e + f
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Jim Sawyer |