I don't understand why Smalltalk doesn't allow me to have an or: method that takes a block argument (except on Boolean). For example:
Set or: 1. ==> MNU as expected.
Set or: [1]. ==> NonBooleanReceiver exception.
Set or: [:x | x] ==> Argument has too many arguments
Is it because the compiler specializes this to boolean when it sees the or: [ ... ] syntax? Is this a tradeoff made for performance?
greetings, Lorenz
On Sun, Sep 10, 2017 at 01:33:15PM +0200, Lorenz K??hl wrote:
I don't understand why Smalltalk doesn't allow me to have an or: method that takes a block argument (except on Boolean). For example:
Set or: 1. ==> MNU as expected.
Set or: [1]. ==> NonBooleanReceiver exception.
Set or: [:x | x] ==> Argument has too many arguments
Is it because the compiler specializes this to boolean when it sees the or: [ ... ] syntax? Is this a tradeoff made for performance?
Hi Lorenz,
If you are looking for set operations, check these methods:
Collection>>union: Collection>>intersection: Collection>>difference:
I am not sure what you are trying to do with your examples. Can you explain the intent?
Dave
Hi, there.
I think the issue is that you cannot implement the message #or: for any domain object because the compiler treats it in a special way.
Consider a class Foo with the method #or:
Foo >> #or: block ^ block value
You cannot use it as expected:
x := Foo new. y := x or: [42].
There is an optimisation that interferes with the general concepts of objects and messaging.
Best, Marcel Am 10.09.2017 14:45:31 schrieb David T. Lewis lewis@mail.msen.com: On Sun, Sep 10, 2017 at 01:33:15PM +0200, Lorenz K??hl wrote:
I don't understand why Smalltalk doesn't allow me to have an or: method that takes a block argument (except on Boolean). For example:
Set or: 1. ==> MNU as expected.
Set or: [1]. ==> NonBooleanReceiver exception.
Set or: [:x | x] ==> Argument has too many arguments
Is it because the compiler specializes this to boolean when it sees the or: [ ... ] syntax? Is this a tradeoff made for performance?
Hi Lorenz,
If you are looking for set operations, check these methods:
Collection>>union: Collection>>intersection: Collection>>difference:
I am not sure what you are trying to do with your examples. Can you explain the intent?
Dave
_______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
I am not sure what you are trying to do with your examples. Can you explain the intent?
Set was just an example object that's quick to test the behaviour. My intent is to understand this behaviour, bc. Smalltalk usually goes to great length to keep the messaging system consistent. But in VisualWorks the behaviour is the same, so I presume (and Marcel confirms) that without this the performance of the whole system suffers.
greetings, Lorenz
On Sun, Sep 10, 2017 at 3:06 PM, Lorenz Köhl rainbowtwigs@gmail.com wrote:
I am not sure what you are trying to do with your examples. Can you
explain the intent?
Set was just an example object that's quick to test the behaviour. My intent is to understand this behaviour, bc. Smalltalk usually goes to great length to keep the messaging system consistent. But in VisualWorks the behaviour is the same, so I presume (and Marcel confirms) that without this the performance of the whole system suffers.
It avoids a message send and the allocation of a block. These used to be very costly with the interpreter, but even now with a JIT compiler having these get transformed to simple jumps behind the scenes is advantageous.
You can see how it works in class MessageNode, which is used by the Compiler.
In MessageNode class>>initialize all the macro transformations are registered. E.g. for "or:" we have "transformOr:" as a transformer and "emitCodeForIf:encoder:value:" as an emitter. The first transforms the "or:" message into an "ifTrue:ifFalse:" message, and the second emits the proper branch byte code to conditionally skip the blocks:
a or: [b]
gets transformed to
a ifTrue: [true] ifFalse: [b]
and then byte code is emitted like
a jump if false to 1 push true jump to 2 1: b 2: ...
As you can see, the closure is gone completely.
- Bert -
beginners@lists.squeakfoundation.org