Hugh> Icon has the suspend command which allows a function to
Hugh> produce a result in the way that return does, but it
Hugh> suspends execution so that if the function is called again
Hugh> in the same context execution can continue from where the
Hugh> suspend left off. It could be considered to be an inside-out
Hugh> yield. This is used to create generators rather than
Hugh> iterators. It is achieved by leaving the state of the
Hugh> function on the stack.
How about this ...
----------------------------------------------------------------------
require 'generator'
class FibGenerator < Generator
def generating_loop
generate(1)
a, b = 1, 1
loop do
generate(b)
a, b = b, a+b
end
end
end
fib = FibGenerator.new
puts fib.next # => 1
puts fib.next # => 1
puts fib.next # => 2
puts fib.next # => 3
puts fib.next # => 5
puts fib.next # => 8
----------------------------------------------------------------------
Its done with mirrors (and continuations) ...
-- File: generator.rb ------------------------------------------------
#!/usr/bin/env ruby
# -*- ruby -*-
class Generator
def initialize
do_generation
end
def next
callcc { |here|
@main_context = here;
@generator_context.call
}
end
private
def do_generation
callcc { |context|
@generator_context = context;
return
}
generating_loop
end
def generate(value)
callcc { |context|
@generator_context = context;
@main_context.call(value)
}
end
end
----------------------------------------------------------------------