On Nov 28, 9:19 am, MonkeeSage <MonkeeS... / gmail.com> wrote:
> On Nov 28, 6:29 am, "Just Another Victim of the Ambient Morality"
>
>
>
> <ihates... / hotmail.com> wrote:
> > Warning:  I don't really know what I'm talking about so if I make any
> > mistakes in terminology, please try to correct me...
>
> >     I've been doing a lot of Python programming and I've discovered that
> > it's actually a very powerful language.  The language, itself, lacks any
> > kind of elegance but it has all the power of Ruby and a little more
> > performance.  It also has a richer set of libraries, although not in all
> > areas, surprisingly.
> >     One thing that Ruby should take from Python are continuations.  Python
> > is moving away from list creation and version 3.0 functions will return
> > Python iterators, implemented with continuations, instead of actual lists,
> > since they are not used nearly as much as you might think.
> >     The reason why I say that Ruby needs continuations is because they are
> > more versatile than Ruby iterators.  The reason why I say _that_ is because
> > you can make Ruby iterators with continuations but you can't make
> > continuations with Ruby iterators.  This means that you can implement a
> > continuation iterator and Object class can automatically define a Ruby
> > iterator based on your continuation iterator.  After all, Ruby iterators are
> > nice.  I'm surprised by how annoyed I am that Python for loops don't return
> > a value...
> >     One weakness of Ruby iterators that continuations don't have is parallel
> > iteration.  If you have two containers that represent different aspects of
> > the same things, it's difficult to iterate over both of them in Ruby.  In
> > Python, you can do this:
>
> > list1 = [1, 2, 3, 4]
> > list2 = ['a', 'b', 'c', 'd']
>
> > # Okay, Python is more wordy than I'd like
> > # I could have just used zip() but you rarely need the list!
> > for num, letter in itertools.izip(list1, list2):
> >     # Do something with both numbers and letters
> >     print num, letter
> >     print
>
> >     How would one do this in Ruby?  You can use .each_with_index and index
> > the other list but that assumes that the other list is indexable, which only
> > happens to be true of arrays but is not true in general.  I've thought about
> > implementing some Ruby equivalent of zip() (or preferably izip()) and
> > discovered that I can't do so without continuations.
> >     ...Hence, my post.  I'm actually at odds with Pythonic philosophy.  The
> > idea that there should only be one way to do things is ludicrous and a
> > constant up hill battle.  One thing that Python does right is that it's not
> > afraid to "steal" from other languages and that's the right attitude to
> > have.  Adopt whatever is useful!
> >     Python 3.0 looks like great language.  I'm hoping that Ruby 2.0 will be
> > even better 'cause, frankly, Ruby is more fun to program in...
> >     Thank you...
>
> You actually need a generator, which can be implemented with
> continuations, but doesn't have to be (in 1.9 the generators are
> implemented with threads -- have a look at generator.rb in 1.8 and 1.9
> to see the differences). Using generators, you can implement izip (and
> all of itertools if you'd like, though most of it already has
> equivalent ruby solutions). Here is a pretty close translation of the
> python given in the itertools docs:
>
> ========
>
> require 'generator'
>
> module Enumerable
>   def izip(*enumerables)
>     enumerables = [self] + enumerables
>     generators = enumerables.map { | enum |
>       Generator.new(enum)
>     }
>     while generators[0].next?
>       result = generators.map { | gen |
>         gen.next
>       }
>       yield result
>     end
>   end
> end
>
> [1,2,3].izip([4,5,6]) { | x, y |
>   puts x, y
>
> }
>
> ========
>
> NB. generator.rb says that generators are slow in 1.8.
>
> Regards,
> Jordan

Ps. The SyncEnumerator class from generator does the same thing as
izip:

SyncEnumerator.new([1,2,3], [4,5,6]).each { | x, y |
  puts x, y
}