I'm attempting to solve AoC problem 12 part 2 in Smalltalk. The specific aren't super relevant, but here's the relevant portion of a single-dimensional version of the model I'm using for the problem:
Object subclass: Moon [
| X XX Xin |
init [
X := 0. XX := 0. Xin := 0.
]
Moon class >> new [ | moon | moon := super new. moon init. ^moon]
x: xx [
X := xx. XX := 0. Xin := xx.
]
kinetic [ ^ (XX abs) ]
initialState [ | killmeNow |
killmeNow := ((self kinetic) == 0).
killmeNow := killmeNow and: (Xin == X).
^killmeNow
]
]
moonA := Moon new.
moonA x: 1.
moonA initialState printNl.
As the variable names just might suggest, I'm failing at the highly complex task of checking if a number equals zero and a second number equals a third number. No amount of refactoring of this statement seems to change the ultimate outcome:
Object: true error: did not understand #value
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
True(Object)>>doesNotUnderstand: #value (SysExcept.st:1448)
True>>and: (True.st:116)
Moon>>initialState (omg.st:15)
UndefinedObject>>executeStatements (omg.st:22)
What is the #Value
that (self kin == 0)
is receiving, why is it not True
, and how do I fix this?
The argument of the and:
message must be a Block
(and you are passing a Boolean
). Just change your code like this
killmeNow := killmeNow and: [Xin == X]. "squared brackets rather that parentheses"
You could also have written the same more succinctly as
initialState [
^self kinetic = 0 and: [Xin = X]
]
but, of course, this is secondary. Note that I've used =
instead of ==
because both have a slightly different semantics and you don't need object identity in these tests (even though ==
will work as well in your case).
For the sake of completeness, let me mention that there is way to and Booleans: the binary message &
does that. So, you could have written
^(self kinetic = 0) & (Xin = X).
The precedence rules of the Smalltalk syntax allow you to remove the parentheses around self kinetic = 0
because here the main message is =
which is also binary. The parantheses aroung Xin = X
cannot be removed, otherwise &
would take precedence over the last occurrence of =
.