Occasionally you see discussions (like on the IwannaLearnRuby page) about InternalIteration vs. ExternalIteration. I think those discussions are evidence of a LanguageSmell. In a language that supports CallWithCurrentContinuation, you don't need to choose; you can build a general-purpose ExternalIterator. For example, in the RubyLanguage: # A class that transforms an InternalIterator # (like :each or :each_index) into an object # that you can call :next on to keep getting # successive values. class ExternalIterator def initialize(iterationMethod) @iterationMethod = iterationMethod startLooping end def startLooping # Don't do anything yet - just save the current # context and return. callcc { |@context_of_looping_method| return } # If we got here, it's because someone called the # "next" method. Start running the iteration method, # but after each iteration, save the current context # and jump back to the context of the "next" method. @iterationMethod.call { |nextValue| callcc { |@context_of_looping_method| @context_of_next_method.call(nextValue) } } doneLooping! end def doneLooping! @context_of_looping_method = nil @context_of_next_method.call end def doneLooping? @context_of_looping_method.nil? end def next if not doneLooping? # Jump back to the looping method. (The # looping method will then go one more # time through the loop and then jump # back here.) callcc { |@context_of_next_method| @context_of_looping_method.call } end end end class Object # Just a convenience method. def iterator(methodName) ExternalIterator.new(method(methodName)) end end # Some simple tests. if __FILE__ == $0 def fibonacci yield 1 a, b = 1, 1 loop { yield b a, b = b, a+b } end f = iterator(:fibonacci) puts "Printing the first six Fibonacci numbers..." puts f.next # => 1 puts f.next # => 1 puts f.next # => 2 puts f.next # => 3 puts f.next # => 5 puts f.next # => 8 puts "Printing the indices of a four-element array..." g = ['a', 'b', 'c', 'd'].iterator(:each_index) puts g.next # => 0 puts g.next # => 1 puts g.next # => 2 puts g.next # => 3 puts "And here's what happens if we keep going off the end of the array..." puts g.next # => nil puts g.next # => nil puts g.next # => nil end ---- CategoryContinuation