On 05.10.2011, at 00:24, nicolas cellier wrote:
Bert Freudenberg <bert <at> freudenbergs.de> writes: On 04.10.2011, at 19:16, Erlis Vidal wrote:
Thanks Bert!
The byte code has the answer, I thought that the byte code will map the
source code but I see that's not the
case, probably to ensure some optimizations.. or to do that "jump" I don't
know how to do that in smalltalk
For ifTrue: it is purely an optimization, yes. It would work fine by actually
sending that message. It would
just be slower.
In the case of whileTrue:, however, it's not just an optimization. The only
way to do loops otherwise would
be by recursion. But the Squeak VM does not do tail-call elimination, so it
would run out of space pretty
soon. Generating the loop as a byte code back jump is essential for the system
to work.
- Bert -
Oh no, we could as well reduce stack depth to (numberOfIteration log: 2) with silly recursive code like this:
Block>>tryTwiceThen: aBlock self value ifFalse: [^aBlock value]. self value ifFalse: [^aBlock value]. ^ [self value ifFalse: [^aBlock value]. self value ifFalse: [^aBlock value]. true] tryTwiceThen: [^aBlock value]
Block>>log2WhileTrue ^self tryTwiceThen: [^nil]
| i maxDepth sender | i := maxDepth := 0. [i := i+1. depth := 0. sender := thisContext. [(sender := sender sender) isNil] whileFalse: [depth := depth+1]. maxDepth := maxDepth max: depth. i<10000] log2WhileTrue. ^maxDepth
Yes, but log(n) is still not good enough for loops that run forever. Like the Morphic main loop. Or the idle process.
I don't think it's possible to emulate whileTrue without reaching for the meta hammer. Interesting discussion though. Maybe a bit over the head of the average newbie ;)
- Bert -