[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>

In This Thread

Prev Next