Search code examples
smalltalkextend

Smalltalk, using 'value' on BlockClosure


I am trying to create a method for the existing BlockClosure class. This is a method we wrote on the board in class, but it is not behaving exactly as I'd want it to. This is the code:

BlockClosure extend[
   times: count[
      count = 0
      ifTrue:
      [^self value.]
      ifFalse:
      [self value. self times: count - 1.].
   ]
].

I tried testing it out by inputting this into the gst interpreter:

st> x:= 5
5 
st> y := [x-1] times: 4.
a BlockClosure

But I want y to equal 1 in this case. Why is y's value becoming "a BlockClosure"?

EDIT: The correct times method.

BlockClosure extend[
   times: count[
      count = 0
      ifFalse:
      [self value. ^self times: count - 1.].
   ]
].

Solution

  • First of all, you're missing the ^ in the ifFalse: branch of the conditional statement, which is preventing the return value from propagating back from the recursive call:

    ifFalse:
    [self value. ^self times: count - 1]
    

    Secondly, this will actually set y to 4 instead, because you're computing x - 1 with the same x value each time. What you probably mean to do is reassign back to x each time:

    y := [x := x - 1] times: 4