From: Luke Graham Date: 2005-03-11T22:44:53+09:00 Subject: Re: Is iterating in lock-step possible? Gah, always miss something when I post code... Replace the first two lines of nextco with def nextco each_with_index { |e,i| On Fri, 11 Mar 2005 23:41:46 +1000, Luke Graham wrote: > 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 > -- spooq