From: Julian Snitow Date: 2003-03-24T13:35:23+09:00 Subject: Re: Iterate over two lists in parallel Gavin Sinclair wrote: > On Monday, March 24, 2003, 1:54:53 PM, Julian wrote: > > >>>Now I'm responding to my own messages, which is dangerously close to >>>talking to myself. But another, more common, problem where generators >>>have the advantage is trying to iterate over two lists in parallel. >>> > > >>Never understimate the amazing power of call/cc. > > >>(Programming in a language that lacks it is like commuting to work >>without a personal teleporter... :-) > > > > The above quote is from the thread concerned with producing slides > comparing Ruby and Python. > > I'd like someone, hopefully including Julian and Jim (Weirich), to > demonstrate how to iterate over twop lists in parallel. Extra marks > for setting a realistic example problem and solving it! > > Gavin > > k. :-) With block iterators: #!/usr/bin/ruby -w class Array def splice(foo) ((foo.size > size) ? foo.size : size).times do |i| yield self[i] if self[i] yield foo[i] if foo[i] end end end animals = ["monkey", "goat", "cow", "ox", "lizard", "lion", "bat", "gorilla", "tiger", "frog"] vehicles = ["car", "plane", "bicycle", "catapult", "unicycle", "hang glider", "bus", "pogo stick", "boat", "train", "gondola", "skateboard", "ski lift"] animals.splice(vehicles) { |val| puts val } ################################ And now a completely contrived example using continuations, since as we've shown above, this problem doesn't require anything so powerful. #!/usr/bin/ruby -w animals = ["monkey", "goat", "cow", "ox", "lizard", "lion", "bat", "gorilla", "tiger", "frog"] vehicles = ["car", "plane", "bicycle", "catapult", "unicycle", "hang glider", "bus", "pogo stick", "boat", "train", "gondola", "skateboard", "ski lift"] puts callcc { |outsideWorld| cc, dd = nil, nil curr, other = callcc { |cc| cc.call callcc { |dd| dd.call animals, vehicles } } # Here is where the continuation ``cc'' begins if(x = curr.shift) puts x end if curr == [] && other == [] outsideWorld.call "Free at last!" else dd.call other, curr end } # Continuation (locally known as 'outsideWorld' in the preceding block) begins here. puts "... And now the program can end." # :-) ###################################### Or have I misinterpreted the problem? It seems too trivial to be a "show me that this is possible" kind of problem... :-(