Group: comp.lang.ruby


Subject: Ruby needs continuations...
From: Just Another Victim of the Ambient Morality
Date: 11/28/2007 12:29:53 PM
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...

Subject: Ruby needs continuations...
From: Just Another Victim of the Ambient Morality
Date: 11/28/2007 1:31:34 PM
"Austin Ziegler" <halostatue@gmail.com> wrote in message news:9e7db9110711280500j3d7b1c6byf36c6d769c05bcbd@mail.gmail.com... > On 11/28/07, Vitor Peres <dodecaphonic@gmail.com> wrote: >> On Nov 28, 2007 10:30 AM, Just Another Victim of the Ambient Morality < >> ihatespam@hotmail.com> wrote: >> > 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. > > Actually, Ruby 1.9 is losing continuations (hard to do with native > threads, expensive for stack frame manipulation in JRuby). However, > you don't need continuations to do parallel iteration, as Vitor > suggests: > >> Ruby does, however, have an implementation of zip in Enumerable. You can >> do >> >> list1 = [1, 2, 3, 4] >> list2 = ['a', 'b', 'c', 'd'] >> >> list1.zip(list2).each {|num, letter| puts "#{num} #{letter}" } >> >> just fine. You'll actually get the same result you would with your Python >> example. > > You're also able to do: > > a.zip(b, c, d, ...) > > to iterate multiple lists in parallel. Thank you, both, for pointing this out! Considering my failure to create such a method, I was about to ask how such a thing was implemented but then I just tried it out and I've discovered how: arrays. I've already mentioned that not all containers are indexable: linked lists are not and trees are not efficiently. Continuations allow even non-indexable containers to be iterated in parallel...

Subject: Ruby needs continuations...
From: Just Another Victim of the Ambient Morality
Date: 11/28/2007 1:36:01 PM
"Michael Fellinger" <m.fellinger@gmail.com> wrote in message news:9c00d3e00711280453l26abd03h9f5b8791ae699ef1@mail.gmail.com... > [1,2,3].zip([4,5,6]).each{|a,b| p a => b} > > also, ruby does have contiuations, check your facts (ri callcc) before > trying to complain, otherwise you will just appear as yet another > troll. Correct me if I'm wrong but aren't continuations being dropped for Ruby 2.0?

Subject: Ruby needs continuations...
From: Just Another Victim of the Ambient Morality
Date: 11/28/2007 2:27:15 PM
"Richard Conroy" <richard.conroy@gmail.com> wrote in message news:511fa3a20711280513m702a8b1ft2f0ee7f1130ee1be@mail.gmail.com... > On Nov 28, 2007 12:30 PM, Just Another Victim of the Ambient Morality > <ihatespam@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. > > Ruby has continuations. Though in practice they are not used much. > They have caused serious pain in implementing JRuby for instance, > to the point that IIRC JRuby does not support them out of the box (and > this doesn't diminish JRuby's value really). > > But there are a lot of really smart people looking into Ruby right now. > Don't expect the dormant Lisp-like features to stay unused. > > Python 'lacks any kind of elegance'? Thats unfair. It is more correct to > say, that Python has a different value system for code expressiveness. Indeed, I wasn't trying to be fair, I was just expressing a personal preference. While Python is clearly a powerful and useful language (I'm programming in it, aren't I?), its syntax choices irk me to no end. len() is a function that can take a list but .append() is a method of list's? Arg! Zero and empty strings evaluate to false? Arg! Both zip() and dict.items() are built-in but izip() hides in the itertools module while dict.itertimes() gets to be built-in? Arg! Considering how iterators are more useful than actual lists, double arg! As it so happened, I did expand on some of the differences between Python's code values and mine, later on in my post... > Python and Ruby are more or less peers on the Language Power Continuum. > Choice between either will depend more on specific task details, specific > library availability or personal preference. Of course. I'm programming in Python, aren't I?

Subject: Ruby needs continuations...
From: Just Another Victim of the Ambient Morality
Date: 11/28/2007 4:53:33 PM
"MonkeeSage" <MonkeeSage@gmail.com> wrote in message news:4f89dee4-b922-49ef-889f-e281e7ad0e8c@j44g2000hsj.googlegroups.com... > On Nov 28, 9:19 am, MonkeeSage <MonkeeS...@gmail.com> wrote: >> ======== >> >> 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 > } Thank you, MonkeeSage, this is exactly what I'm looking for! It's interesting that generators are slow enough to warn users about its lack of speed! Do you know if it would be any faster implemented with continuations? I'm surprised it's so slow considering Ruby employs green threads...

Subject: Ruby needs continuations...
From: Just Another Victim of the Ambient Morality
Date: 11/28/2007 5:30:24 PM
"MonkeeSage" <MonkeeSage@gmail.com> wrote in message news:d0ee96af-656e-4dd8-8a17-bcf46e4ff69a@e67g2000hsc.googlegroups.com... > On Nov 28, 10:53 am, "Just Another Victim of the Ambient Morality" > <ihates...@hotmail.com> wrote: >> "MonkeeSage" <MonkeeS...@gmail.com> wrote in message >> >> > 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 >> > } >> >> Thank you, MonkeeSage, this is exactly what I'm looking for! >> It's interesting that generators are slow enough to warn users about >> its >> lack of speed! Do you know if it would be any faster implemented with >> continuations? I'm surprised it's so slow considering Ruby employs green >> threads... > > Other way around. ;) The continuation version is slow. The threaded > version is fast. Ah, that's good to hear! I was confused there. It looks like, as long as we have these green threads, we won't really need continuations. This is starting to get off topic but, if you happen to know, if Ruby is moving towards native threads, will we keep green threads around? They're useful things, even with native threads available...