6

I want to know how whileTrue: works. I searched the implementation that is in BlockClosure:

whileTrue: aBlock 
 ^ [self value] whileTrue: [aBlock value]

And another implementation with no parameter:

whileTrue
 ^ [self value] whileTrue: []

But I don't know how that works, that's a recursive method, but this led me to ask several questions:

  1. How does this recursive call terminate?
  2. If [self value] returns a Boolean object, why is whileTrue: not implemented in the Boolean type?
  3. Why is there another implementation named whileTrue that just do not receive any block and evaluates self?
SylvainD
3291 silver badge7 bronze badges
asked Oct 15, 2014 at 12:42

2 Answers 2

7

whileTrue: is inlined by the compiler, that's why you don't see the actual implementation. Here's the comment out of Pharo:

"Ordinarily compiled in-line, and therefore not overridable. This is in case the message is sent to other than a literal block. Evaluate the argument, aBlock, as long as the value of the receiver is true."

If you look at the byte code of #whileTrue: you'll see that the compiler simply uses a jump to make the loop:

17 <70> self
18 <C9> send: value
19 <9C> jumpFalse: 25
20 <10> pushTemp: 0
21 <C9> send: value
22 <87> pop
23 <A3 F8> jumpTo: 17 <---- here's the jump
25 <7B> return: nil

#whileTrue is also inlined directly (slightly optimized byte code). The inlining is also the reason why there's no implementation of this on Boolean (apart from the fact that there's no point in reevaluating a boolean...).

#whileTrue is there so that you can easily create endless loops the only terminate e.g. when the process terminates, a semaphore is signaled, an exception occurs etc.

answered Oct 15, 2014 at 14:51
4
  • 1
    How can you see the bytecode? Commented Oct 15, 2014 at 14:53
  • Which dialect / IDE are you using? In Pharo / Squeak there's a button next to the text area that you can press. Commented Oct 15, 2014 at 14:56
  • I'm using Squeak. I will search that button. Thanks. Commented Oct 15, 2014 at 15:24
  • 1
    In Squeak the button is the right most one above the text area, labelled "source". Click on it and then select "byteCodes". Commented Oct 15, 2014 at 15:35
3

My Smalltalk is a bit rusty, and I don't have Smalltalk installed at the moment, so there might be some syntax errors in here, but you get the idea:

whileTrue: aBlock
 ↑ self value ifTrue: [aBlock value. self whileTrue: aBlock]

Here's a version in Ruby that I actually tested, of which the above (I hope) is a translation:

class Proc
 def vhile(block)
 self.().iff(thn: -> {block.(); vhile(block)})
 end
end

You need the following monkeypatches to get the Smalltalk-style conditionals to work:

class TrueClass
 def iff(thn:, els: ->{})
 thn.()
 end
end
class FalseClass
 def iff(thn:, els: ->{})
 els.()
 end
end
answered Oct 15, 2014 at 15:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.