QotD    "To be or not to be" – Shakespeare
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
expression or: aBlock
Last updated at 6:49 pm UTC on 11 September 2017
Ralph Johnson
Sun, Sep 10, 2017 at 3:50 PM
Reply-To: "A friendly place to get answers to even the most basic questions about Squeak."
To: "A friendly place to get answers to even the most basic questionsabout Squeak."

Yes, when the compiler sees

    exp or: [ ... ] 

then it assumes that "exp" is a boolean-valued expression and generates code that fails if it isn't. Not all Smalltalk compilers perform this optimization, but it is very common. There are a bunch of methods treated like this, ifTrue:ifFalse: is another.

is an interesting slightly different case. The compiler usually optimizes whileTrue: only when both receiver and the argument are blocks.

So, you can define whileTrue: in other classes without any problem.

Ralph Johnson

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

jump if false to 1
push true
jump to 2
1: b
2: ...

As you can see, the closure is gone completely.

  • Bert -​