And last thing there's an absolutely cheap way to remove optimization: don't provide a block argument. For example provide a message send instead:

[true or: [false] yourself] bench.
 '39,900,000 per second. 25 nanoseconds per run.'

[true or: [false]] bench.
'177,000,000 per second. 5.63 nanoseconds per run.'

If you like syntactic sugar, implement BlockClosure>>unoptimized as ^self and write:

    true or: [false] unoptimized.

And last, here is a draft that I wrote in 2015 in the pharo thread about mustBeBoolean workaround
(but I never sent that draft, I didn't want to sound too negative) :

[Pharo-dev] can or: be redefined?

...snip...
> That's the way to go. I think some people like Camille are already working on it. Basically, you need abstraction over what is happening which is implemented in the image instead of the VM for simplicity and maintenance, and what the programmer wants to see which is relevant for him.

> For optimized selectors, one could mark the methods with pragmas as 'Do not show in debugger' and in addition rewire the bytecode to source code mapping from the method compiled on-the-fly executed in ExecuteUnoptimizedIn: to the regular method.

> But as I stated for Slots, it is more complicated. The debugger cannot detect if the stack is currently in a slot access, as it has access only to the bottom 20 frames. Having the debugger access the full stack is a bad idea as it would slow it considerably, making the debugger unusable on devices such as the raspberry pie, and hard to use to debug recursive code. Maybe a solution could be that if the compiled bytecode for a slot has an interrupt point (branch, back jump, send), then it could change a state in the process, probably encoded in the process instance variables, and as the debugger has access to the process it is showing it would know.
 

It sounds like inserting an elephant in the stack and keep prretending it's turtle all the way down ;)
Isn't the cheat too visible?

Some essential Smalltalk principles/properties shall better not be lost:
- there's a well defined virtual machine which acts as boundary between Smalltalk code and non Smalltalk (primitive) code.
- everyone should be in a position to understand every single bit of Smalltalk code and the debugger is the ultimate introspective tool to do so.

There are times when you want to debug slot implementation itself, think of it...
And there will be times when you want to introspect how the machinery works, maybe because you want to understand time spent in a method or come with a similar trick.
I hope it does not imply debugging at bytecode level, this would be a great loss.

To me, the whole #or: story sounds like you came with a complex workaround for hiding an optimization.
And now you're trying to hide the workaround with an even more complex machinery which endanger first principles:

Just admitting and learning that there are a very few exceptions to the rules sounds very cheap in regard.
I wish you success, but it's scary!

2017-09-18 19:22 GMT+02:00 Levente Uzonyi <leves@caesar.elte.hu>:

On Sun, 17 Sep 2017, Sean P. DeNigris wrote:


On the "Squeak Beginners" ML, a new Smalltalker wrote:
I don't understand why Smalltalk doesn't allow me to have an or:
method that takes a block argument (except on Boolean).

The answer apparently was that the compiler replaces the code with an
optimization that is usually what one wants, and the actual message never
gets sent:
   Ralph Johnson wrote
   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.

I remember the pain of tripping over these little "everything is a message
send to an object*" sins as a new Smalltalker. I wonder now, with the
incredible speed of Cog, Spur, Sista, etc., if these devil's bargains from
prior decades are still necessary. It would be psychologically satisfying
(and nice for newbies) to remove the asterisk from the principle above.

p.s. IIRC e.g. Opal has flags to modify this behavior, but could the actual
messages be sent by default, and the flag be set to inline when that
performance boost is actually required?

You can turn off all those optimizations in your image except for potentially infinite loops.

The performance drop will be larger than you may think, because Cog has its own native implementation for most if not all those methods. So it'll skip both primitives and special bytecodes when possible and inline them into the jitted code (This can result in nasty debug situations when the jitter code's behavior differs from what the image side code suggests).

Also, most of those methods are not newbie-safe. Changing any of them will probably freeze your image.

Finally, these changes can only be done on the image side, so this question probably belongs to another list.

Levente




-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Squeak-VM-f104410.html