tags:

views:

234

answers:

2

I've come up with this:

def f x, &b
  yield x, b
end
f 4 do |i, b|
  p i
  f i - 1, &b if i > 0
end

Result:

4
3
2
1
0

Is there another way?

+2  A: 

It depends upon the particulars of your actual code, but given your example, if you name the block beforehand, you can avoid yielding the value and the block in your function. Eg:

def f(x, &b)
  yield x
end

foo = lambda do |i|
  p i
  f(i-1,&foo) if i > 0
end
f(4,&foo)

However, I'd like to find a more elegant solution to this problem. I suspect this is would be a good application of the Y combinator. As soon as I have something better for you, I'll update this message.

Ian
That's good, though I was doubtful about lambda for my case because it's about the same number of bytes as def f..end. This became a bit interesting abstractly but it all started with this: http://stackoverflow.com/questions/1766675/code-golf-running-water/1770264#1770264
DigitalRoss
Yeah, unfortunately, if it's the least number of characters used that you're after, using lambda's probably isn't going to be very helpful. Even the abbreviated -> syntax found in Ruby 1.9 still probably wouldn't save much, once you include the y-combinator code. If you're unfamiliar with it, or if any other reader is, examples in Ruby can be found here: http://nex-3.com/posts/43-fun-with-the-y-combinator-in-ruby and here: http://www.eecs.harvard.edu/~cduan/technical/ruby/ycombinator.shtml
Ian
Still, a very interesting problem. I'll chew on it a bit more before accepting that the named lambda is the shortest way to go.
Ian
A: 
def f(x, &b)
  b.call x
  f(x-1,&b) if x>0
end

f(4) do |x|
 p x
end
haoqi