Code problems

why is the following code not valid

def fibber
    a = 1
    b = 1
    lambda do
        yield(a)
        a,b = a+b,a
    end
end

Hi,

At Mon, 4 Jun 2007 12:36:50 +0900,
david karapetyan wrote in [ruby-talk:254217]:

why is the following code not valid

It is valid.

def fibber
    a = 1
    b = 1
    lambda do
        yield(a)
        a,b = a+b,a
    end
end

irb(main):009:0> fib = fibber{|x|p x}
=> #<Proc:0xb7c63a74@(irb):4>
irb(main):010:0> fib
1
=> [2, 1]
irb(main):011:0> fib
2
=> [3, 2]
irb(main):012:0> fib
3
=> [5, 3]

···

--
Nobu Nakada

thanks. i didn't realize i had to provide the block as well when i was
creating the closure. i was hoping for a closure that could take a different
block every time. i wanted fib to be a function that had access to a and b
and every call to fib would require a block. as it is fib has its block
fixed at creation time. do you know of a way of doing what i wanted to do
originally?

···

On 6/3/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Mon, 4 Jun 2007 12:36:50 +0900,
david karapetyan wrote in [ruby-talk:254217]:
> why is the following code not valid

It is valid.

> def fibber
> a = 1
> b = 1
> lambda do
> yield(a)
> a,b = a+b,a
> end
> end

irb(main):009:0> fib = fibber{|x|p x}
=> #<Proc:0xb7c63a74@(irb):4>
irb(main):010:0> fib
1
=> [2, 1]
irb(main):011:0> fib
2
=> [3, 2]
irb(main):012:0> fib
3
=> [5, 3]

--
Nobu Nakada

Hi,

At Mon, 4 Jun 2007 13:25:50 +0900,
david karapetyan wrote in [ruby-talk:254219]:

thanks. i didn't realize i had to provide the block as well when i was
creating the closure. i was hoping for a closure that could take a different
block every time. i wanted fib to be a function that had access to a and b
and every call to fib would require a block. as it is fib has its block
fixed at creation time. do you know of a way of doing what i wanted to do
originally?

You need ruby 1.9. Block passing to a block isn't supported in
1.8.

  def fibber
    a = 1
    b = 1
    lambda do |&block|
      block.call(a)
      a,b = a+b,a
    end
  end

  irb(main):010:0> fib = fibber
  => #<Proc:b7ba2338@(irb):6>
  irb(main):011:0> 10.times {fib.call {|x|p x}}
  1
  2
  3
  5
  8
  13
  21
  34
  55
  89
  => 10

···

--
Nobu Nakada

I thought I read somewhere that 1.9 wasn't going to support closures.
So it apparently does then?

···

On 6/3/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Mon, 4 Jun 2007 13:25:50 +0900,
david karapetyan wrote in [ruby-talk:254219]:
> thanks. i didn't realize i had to provide the block as well when i was
> creating the closure. i was hoping for a closure that could take a different
> block every time. i wanted fib to be a function that had access to a and b
> and every call to fib would require a block. as it is fib has its block
> fixed at creation time. do you know of a way of doing what i wanted to do
> originally?

You need ruby 1.9. Block passing to a block isn't supported in
1.8.

  def fibber
    a = 1
    b = 1
    lambda do |&block|
      block.call(a)
      a,b = a+b,a
    end
  end

  irb(main):010:0> fib = fibber
  => #<Proc:b7ba2338@(irb):6>
  irb(main):011:0> 10.times {fib.call {|x|p x}}
  1
  2
  3
  5
  8
  13
  21
  34
  55
  89
  => 10

--
Nobu Nakada

--
-fREW

cool and thanks for the help

···

On 6/3/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Mon, 4 Jun 2007 13:25:50 +0900,
david karapetyan wrote in [ruby-talk:254219]:
> thanks. i didn't realize i had to provide the block as well when i was
> creating the closure. i was hoping for a closure that could take a
different
> block every time. i wanted fib to be a function that had access to a and
b
> and every call to fib would require a block. as it is fib has its block
> fixed at creation time. do you know of a way of doing what i wanted to
do
> originally?

You need ruby 1.9. Block passing to a block isn't supported in
1.8.

  def fibber
    a = 1
    b = 1
    lambda do |&block|
      block.call(a)
      a,b = a+b,a
    end
  end

  irb(main):010:0> fib = fibber
  => #<Proc:b7ba2338@(irb):6>
  irb(main):011:0> 10.times {fib.call {|x|p x}}
  1
  2
  3
  5
  8
  13
  21
  34
  55
  89
  => 10

--
Nobu Nakada

fREW wrote:

I thought I read somewhere that 1.9 wasn't going to support closures.

You are thinking of continuations, not closures, maybe?

IIRC, recent versions of YARV do not have closures.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Joel VanderWerf wrote:

fREW wrote:

I thought I read somewhere that 1.9 wasn't going to support closures.

You are thinking of continuations, not closures, maybe?

IIRC, recent versions of YARV do not have closures.

Now I'm the one spreading confusion. To clarify:

YARV *does* have closures

YARV does *not* have continuations (at least in recent versions)

Sorry...

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Isn't YARV supposed to be Ruby 1.9? Also, can someone explain the
difference between closures and continuations? I thought they were
the same thing.

···

On 6/4/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

Joel VanderWerf wrote:
> fREW wrote:
>> I thought I read somewhere that 1.9 wasn't going to support closures.
>
> You are thinking of continuations, not closures, maybe?
>
> IIRC, recent versions of YARV do not have closures.

Now I'm the one spreading confusion. To clarify:

YARV *does* have closures

YARV does *not* have continuations (at least in recent versions)

Sorry...

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

--
-fREW

Hi,

At Tue, 5 Jun 2007 02:58:20 +0900,
Joel VanderWerf wrote in [ruby-talk:254306]:

Now I'm the one spreading confusion. To clarify:

YARV *does* have closures

YARV does *not* have continuations (at least in recent versions)

YARV has continuations in the latest versions.

···

--
Nobu Nakada

Wow, congratulations, that must have been tough work!

Robert

···

On 6/4/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Tue, 5 Jun 2007 02:58:20 +0900,
Joel VanderWerf wrote in [ruby-talk:254306]:
> Now I'm the one spreading confusion. To clarify:
>
> YARV *does* have closures
>
> YARV does *not* have continuations (at least in recent versions)

YARV has continuations in the latest versions.

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

http://talklikeaduck.denhaven2.com/articles/2007/06/05/closing-in-on-closures-and-jumping-into-continuations

···

On 6/4/07, fREW <frioux@gmail.com> wrote:

Also, can someone explain the
difference between closures and continuations? I thought they were
the same thing.

--
Rick DeNatale

Hi Rick I am still struggeling with continuations :(, as a matter of
fact I hoped that they would behave as described above, but they do
not, it seems.

When I execute the code from your blog
def continuation
   i = 0
   lola = nil
   callcc {|cc| puts "In callcc";lola = cc}
   puts "i is now #{i}"
   i += 1
   lola
   end
cont = continuation
# point of looping
cont.call

http://rubyquiz.com/quiz70.html
I just get an endless loop, do you have an explanation for it?

I remember there was a Ruby Quiz Ruby Quiz - Constraint Processing (#70) with
an excellent solution of Jim Weirich.
One day I thought I understood the mechanism and optimized one callcc
away, boy I made a complete fool out of myself, you can find it on the
archives, I am not going to give the link ;).

Well, just confused...

Cheers
Robert

···

On 6/6/07, Rick DeNatale <rick.denatale@gmail.com> wrote:

On 6/4/07, fREW <frioux@gmail.com> wrote:
> Also, can someone explain the
> difference between closures and continuations? I thought they were
> the same thing.

http://talklikeaduck.denhaven2.com/articles/2007/06/05/closing-in-on-closures-and-jumping-into-continuations

--
Rick DeNatale

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

When I first learned about closures I was like, "Weird..." But then I
found a use for them and they are awesome. Continuations are even
weirder. I like the groundhog day analogy. Imagine how the program
feels!

···

On 6/5/07, Rick DeNatale <rick.denatale@gmail.com> wrote:

On 6/4/07, fREW <frioux@gmail.com> wrote:
> Also, can someone explain the
> difference between closures and continuations? I thought they were
> the same thing.

http://talklikeaduck.denhaven2.com/articles/2007/06/05/closing-in-on-closures-and-jumping-into-continuations

--
Rick DeNatale

--
-fREW

Robert, you are right, it loops in ruby, but not in irb.

I was trying to cook up a simple example and got hoist by irb's petard.

What happens in ruby is that calling the continuation goes back to the
method, which returns to the point before the cont.call and away we go
again.

Continuations normally aren't reused in the way I did in the example.
I'm actually not sure why it works the way it does in irb.

Here's a simpler example which shows the flow of control concept.

rick@frodo:/public/rubyscripts$ cat testcontin.rb
def continuation
  puts "Before callcc"
  callcc {|cc| puts "In callcc";return cc}
  puts "After callcc"
end

puts "Begin"
cont = continuation
puts "Got cont #{cont.inspect}"
if cont
  cont.call
  puts "After call"
end
puts "All done"
rick@frodo:/public/rubyscripts$ ruby testcontin.rb
Begin
Before callcc
In callcc
Got cont #<Continuation:0xb7de3840>
After callcc
Got cont nil
All done

···

On 6/6/07, Robert Dober <robert.dober@gmail.com> wrote:

>
Hi Rick I am still struggeling with continuations :(, as a matter of
fact I hoped that they would behave as described above, but they do
not, it seems.

When I execute the code from your blog
def continuation
   i = 0
   lola = nil
   callcc {|cc| puts "In callcc";lola = cc}
   puts "i is now #{i}"
   i += 1
   lola
   end
cont = continuation
# point of looping
cont.call

I just get an endless loop, do you have an explanation for it?

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

<snip>

Robert, you are right, it loops in ruby, but not in irb.

I was trying to cook up a simple example and got hoist by irb's petard.

What happens in ruby is that calling the continuation goes back to the
method, which returns to the point before the cont.call and away we go
again.

That confirms my limited understanding of it :slight_smile:

Continuations normally aren't reused in the way I did in the example.
I'm actually not sure why it works the way it does in irb.

Hmm maybe I can give some hint in my zenwalk ruby 1.8.6 irb it loops
as well as in my Windows (one click installer) irb, do you use a
special irb setup?

Here's a simpler example which shows the flow of control concept.

rick@frodo:/public/rubyscripts$ cat testcontin.rb
def continuation
  puts "Before callcc"
  callcc {|cc| puts "In callcc";return cc}
  puts "After callcc"
end

puts "Begin"
cont = continuation
puts "Got cont #{cont.inspect}"
if cont
  cont.call
  puts "After call"
end
puts "All done"
rick@frodo:/public/rubyscripts$ ruby testcontin.rb
Begin
Before callcc
In callcc
Got cont #<Continuation:0xb7de3840>
After callcc
Got cont nil
All done

That is a good example I really like to build on it.
Thanks.

Maybe I might add one thing which took me some minutes to work out :wink:
the nil value for the cont variable comes from : puts "After call".

Cheers
Robert

···

On 6/6/07, Rick DeNatale <rick.denatale@gmail.com> wrote:
--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Actually it comes from the puts "After callcc" as this change demonstrates;

rick@frodo:/public/rubyscripts$ cat testcontin.rb
def continuation
  puts "Before callcc"
  callcc {|lola| puts "In callcc";return lola}
  puts "After callcc"
  "returning"
end

puts "Begin"
cont = continuation
puts "Got cont #{cont.inspect}"
if cont
  cont.call
  puts "After call"
  "Hello"
end
puts "All done"
rick@frodo:/public/rubyscripts$ ruby testcontin.rb
Begin
Before callcc
In callcc
Got cont #<Continuation:0xb7d58768>
After callcc
Got cont "returning"
testcontin.rb:12: undefined method `call' for "returning":String (NoMethodError)

···

On 6/6/07, Robert Dober <robert.dober@gmail.com> wrote:

That is a good example I really like to build on it.
Thanks.

Maybe I might add one thing which took me some minutes to work out :wink:
the nil value for the cont variable comes from : puts "After call".

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Stupid typo of mine, sorry
R.

···

On 6/6/07, Rick DeNatale <rick.denatale@gmail.com> wrote:

On 6/6/07, Robert Dober <robert.dober@gmail.com> wrote:

>
> That is a good example I really like to build on it.
> Thanks.
>
> Maybe I might add one thing which took me some minutes to work out :wink:
> the nil value for the cont variable comes from : puts "After call".

Actually it comes from the puts "After callcc" as this change demonstrates;