MonkeeSage
11/28/2007 3:29:00 PM
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
}