The basic rules for messages/methods in SmalltalkLanguage are:
Dictionary new. 12 factorial.
12 + 7. 'BIG' > 'little'
5 between: 1 and: 10. Transcript show: aString. 12 > 7 ifTrue: ['yes'] ifFalse: ['no'].
3 squared + 4 squared between: 1 and: 1000. Executes 3 squared then 4 squared then 9 + 16 then 25 between: 1 and: 1000.
#new, #factorial, #+, #>, #between:and:, #show:, #ifTrue:ifFalse:
Can anyone explain how the messaging notation works when combined with the ; cascading operator? I.e. I have something like:
7 + 3 squared; printOn: aStreamWhat's printed now? 3 or (7 + 3 squared)? -- StephanHouben (trying to write a YACC grammar of Smalltalk, just for the heck of it).
The meaning of semi-colon is, "Send the next message to the same object that received the previous message". A simpler example would be:
aStream nextPutAll: 'line 1'; cr; nextPutAll: 'line 2'.So in this case, cr is sent to the same object that received the first nextPutAll:, namely aStream. Same goes for the last nextPutAll:.
Your example is a bit trickier, though, because of the precedence rules:
7 + 3 squared; printOn: aStream 3 squared gets evaluated first. Then 7 + 9, then 7 printOn: aStream.Here's a couple more examples:
7 + 4 squared; factorial; yourself. 4 squared, then 7 + 16, then 7 factorial then 7 yourself -> 7. 7 + 2 squared factorial; yourself. 2 squared, then 4 factorial then 7 + 24, then 7 yourself -> 7.
I find it quite easier "parse" the above examples like this (it avoids english :)
7 + 4 squared; factorial; yourself. 7 + 2 squared factorial; yourself.-- EtoffiPerson?
Q: Can anyone explain how Smalltalk implements shortcut evaluation of logical operators? E.g. is this possible?
((x != 0) && ((n / x) > 10)) ifTrue: [ .... ].Apologies if the operators are not correct -- I'm interested in the semantics, rather than the precise syntax. -- anon
A: That is a form of deferred evaluation, which in Smalltalk is always done with blocks. The example becomes:
(x ~= 0 and: [n / x > 10]) ifTrue: [ .... ].The first part, x ~= 0, returns true or false which are normal objects. When true is sent #and:, it evaluates the second argument (the block [n / x > 10]) with #value and returns that. When false is sent #and:, it just returns false without evaluating the second argument.
Thus what is done in CeePlusPlus with special language magic is done in Smalltalk with the general mechanisms of blocks and polymorphism. One consequence is that you can write your own short-cut methods which behave like the built-in ones. In C++, you can overload operator&&() but you cannot duplicate the short-cut arguments.
Previous edit of this page was 2005 -- in 2012, C++ finally has deferred evaluation with lambdas, so you could write this as:
Iftrue(And(x != 0, [=]{ return (n / x) > 10 }), [=]{ ... })What? I didn't say the future was *pretty*