[ruby-core:95049] [Ruby master Feature#16147] List Comprehensions in Ruby
From:
sammomichael@...
Date:
2019-09-23 22:06:16 UTC
List:
ruby-core #95049
Issue #16147 has been updated by sammomichael (Samuel Michael).
Eregon (Benoit Daloze) wrote:
> Just my opinion: I don't think we should have list comprehensions in Ruby.
Thanks I appreciate the feedback!
> They are just a small subset of the far more powerful Enumerable methods, and IMHO are often less readable (e.g., nested list comprehensions in Python are what I would call unreadable).
> Also, I think they basically don't scale, they might look nice for small expressions, but as soon as it becomes bigger it's no longer possible to use the list comprehension syntax.
> So I think it's better to use map/select/filter_map directly.
You have some very good points! Nested comprehensions can get pretty gnarly. Still, I have heard anecdotally from a lot of professional developers that Python list comprehensions are useful to them. Julia inventors though well enough of them to include them in their new language, and a bunch of other languages have some variation as well. I tried to point out some of the benefits in my list above, but basically:
1. a versatile tool, a third (syntax)option alongside of enumerable methods for array generation
2. flexible and easy for beginners to understand
3. square brackets make the array return explicit
----------------------------------------
Feature #16147: List Comprehensions in Ruby
https://bugs.ruby-lang.org/issues/16147#change-81679
* Author: sammomichael (Samuel Michael)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
## List comprehensions are present in many languages and programmers are quite fond of their simplicity and power. Add to that the fact that Ruby has a for...in loop that is rarely used but could possibly be repurposed.
### Currently we can already do a hack like this to make Ruby support list comprehension syntax:
``` ruby
S = [for x in 0...9 do $* << x*2 if x.even? end, $*][1]
# [0, 4, 8, 12, 16]
```
Still, it would be far nicer if the for...in loop would return the desired array automatically, this is one way to approach that taking advantage of lambda bracket invocation syntax:
``` ruby
c = -> x do $*.clear
if x['if'] && x[0] != 'f' .
y = x[0...x.index('for')]
x = x[x.index('for')..-1]
(x.insert(x.index(x.split[3]) + x.split[3].length, " do $* << #{y}")
x.insert(x.length, "end; $*")
eval(x)
$*)
elsif x['if'] && x[0] == 'f'
(x.insert(x.index(x.split[3]) + x.split[3].length, " do $* << x")
x.insert(x.length, "end; $*")
eval(x)
$*)
elsif !x['if'] && x[0] != 'f'
y = x[0...x.index('for')]
x = x[x.index('for')..-1]
(x.insert(x.index(x.split[3]) + x.split[3].length, " do $* << #{y}")
x.insert(x.length, "end; $*")
eval(x)
$*)
else
eval(x.split[3]).to_a
end
end
```
so basically we are converting a string to proper ruby syntax for loop then we can use python syntax in a string to do:
``` ruby
c['for x in 1..10']
c['for x in 1..10 if x.even?']
c['x**2 for x in 1..10 if x.even?']
c['x**2 for x in 1..10']
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [2, 4, 6, 8, 10]
# [4, 16, 36, 64, 100]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>