From: Luke Graham Date: 2005-03-11T22:42:08+09:00 Subject: Re: Is iterating in lock-step possible? On Fri, 11 Mar 2005 15:57:08 +0900, Roshan James wrote: > I was trying to write code where I can have two or more computations > which generate values that I need to compare - with the ruby syntax > tying iterator usage to the code blocks by syntax, there is no way I can > do this. This is especially applicable when the iterators potentially > return an infinite stream of values. (Except for using contiuations... > Which is not really so much of a solution, because I might as well not > have used an iterator in a first place if I could create good > coroutines) Continuations are the right answer in this case. module Enumerable attr_accessor :co, :st, :res def nextco each { |e| callcc { |cc| @co = cc @res = e @st.call } } @res = nil @st.call end def next callcc { |cc| @st = cc @co ? @co.call : nextco } return @res end end a = [1,2,3] b = [4,5,6,7,8] while x = a.next and y = b.next puts x,y end Note there are three possible behaviours around the @res = nil line. One is to return nil after all items have been used up, another is to keep returning the last item by removing that line, and finally a loop can be wrapped around the each, to begin returning from the first item again. Its probably possible to do it in one function, but it makes more sense to me in two. > Yes I understand that I take a hit (wrt perf by choosing ruby), but > that's a BAD argument to favour wrapping state first by a iterators and > then once over by a continuation. As long as its wrapped safely and nicely, what does it matter? This way, you even get your choice of what to do when you run out of items ;) -- spooq