I just started learning Smalltalk at uni.
I would like to know the difference between the messages &
and and:
(just like |
and or:
)
I just started learning Smalltalk at uni.
I would like to know the difference between the messages &
and and:
(just like |
and or:
)
Welcome to Smalltalk! You are asking a good question that points out some subtle differences in expressions that are outside or inside blocks.
The '&' message is a "binary" message so takes only one argument. In this case the argument is expected to be a Boolean or an expression that evaluates to a Boolean. Most importantly for our purposes in this comparison, the expression will always be evaluated.
The 'and:' message is a "keyword" message and also takes only one argument. But in this case the argument is expected to be a Block that if later sent the 'value' message would return a Boolean. So, for our purposes in this comparison, the Block will not always be evaluated. (The difference between the binary and keyword messages does not matter for this question.)
The option to not evaluate the argument allows Short-circuit evaluation in which knowing the left-hand side often allows us to avoid a (possibly expensive) calculation of the right-hand side. So, if the left ("receiver") is false, there is nothing to be gained by evaluating the right-hand side.
So, consider the following:
self cheapFalse & self expensiveTrue. "an expensive way to get false"
self cheapFalse and: [self expensiveTrue]. "a cheap way to get false"
One obvious difference is that and:
is a keyword message thus you can write something like
a > b and: [b < c]
while with &
you would need parentheses in this expression:
a > b & (b < c)
because all the binary messages (+
, -
, >
, <
, &
, |
) have the same precedence.
More importantly, and:
and or:
expect blocks while &
and |
expect values. This means that you can write
this shouldRedraw and: [ obj stateChanged ]
where obj stateChanged
will be executed only if this shouldRedraw
is true. This is useful if you want to optimize your code and avoid computing something which is not needed at the moment.
© 2022 - 2024 — McMap. All rights reserved.
shouldCompute
should be changed toshouldRedraw
. – Schnozzle