From: Jacob Fugal Date: 2005-08-12T01:09:08+09:00 Subject: Re: Yet Another useless Ruby 2 Idea On 8/10/05, Ben Giddings wrote: > On Aug 4, 2005, at 13:20, Jeff Wood wrote: > > But still, you can see that the python syntax is quite a bit more > > readable ( at least in this case ). > > I completely disagree. "item for item in items if item"? How is > that easy to understand? Ummm, maybe a closer translation would be: "computation for item in collection if condition" Naming computation/item/collection/condition the same and then declaring unreadability is a straw man. Given the translation above, consider the following english comment of what is actually happening: "do computation for each item in collection with condition" The "do" and "each" are implicit. That's fine with me, the language shouldn't read as full english or it will be too verbose. The only other change is replacing "if" by "with". It be nice if the list comprehension used "with" instead: manager_salaries = [e.salary for e in employees with e.manager?] vs. manager_salaries = [e.salary for e in employees if e.manager?] Depends on who you are. Me? I like "with" better, but can live with "if" just fine. I think the main readability argument for list comprehensions is that the flow of the construct is similar to the flow of the english sentence that describes it. Ok, is a select/collect implementation less readable? manager_salaries = employees. select{ |e| e.manager? }. collect{ |e| e.salary } English translation: "For each item in collection with condition, do computation" NO! An argument for readability of list comprehensions is not an argument against readability of select/each/collect etc. I love thems, and I want to keep thems! :) Adding list comprehensions wouldn't imply removal of the equally readable and powerful block constructs we're used to. However, notice one thing about the select/collect implementation above. We iterate through employees once and create a temporary array. We then iterate through that temporary array again during the collect. That seems a bit inefficient to me. The list comprehension -- with equal readability -- removes that inefficiency. Does Ruby need list comprehensions to solve that? Not necessarily: module Enumerable def collect_filtered(filter: filter, mapping: mapping) self.inject([]) { |c,e| filter[e] ? c << mapping[e] : c } end end manager_salaries = employees.collect_filtered( filter: -> (e) { e.manager? }, mapping: -> (e) { e.salary } ) I've opted to use the proposed 2.0 syntax for lambdas for consistency with the assumption of named parameters. This would be much less readable without the named parameters. This solves the efficiency problem, but does it really retain the readability of either the inefficient select/collect implementation or the list comprehension? I, personally, don't think so. I hope you've enjoyed this little detour through my thought process... Jacob Fugal