Proposal: Python's list, generator, and dictionary comprehensions

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

1 Like

I like this in python. +1

¡¡¡

On Dec 17, 2015, at 8:26 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hi Amir,

Comprehensions are great in Python. However, Swift can already do all of these things via for...in, map() and/or generate(). Your examples:

Ex. #1

let l = 1...10.map { (Int) -> (Int) in
    return x*x
}

Ex. #2

let l2: [(Int, Int)]
for x in 1...10 {

    for y in 1...10 where (x + y) < 8 {
        l2.append((x, y))
    }
}

Ex. #3

let g = (1...10.map { (Int) -> (Int) in
    return x*x
}).generate()

Ex. #4

let d = [Int: Int]()

for x in 1...10 {
    d = x*x
}

Liam

¡¡¡

Sent from my iPhone

On Dec 17, 2015, at 11:26 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

3 Likes

Amir, your proposal contradicts "clarity over brevity" principle. As pointed by Liam all those things are fairly easy to do without any major complexity.

Pozdrawiam – Regards,
Adrian Kashivskyy

¡¡¡

Wiadomość napisana przez Amir Michail via swift-evolution <swift-evolution@swift.org> w dniu 17.12.2015, o godz. 17:26:

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

-1 from me. I find list comprehensions, on average, roughly as concise as methods on SequenceType, and generally harder to understand as soon as you have more than one collection.

Jordan

¡¡¡

On Dec 17, 2015, at 8:26 , Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

3 Likes

Data of 1: I misunderstood the second comprehension until I saw it written in
Swift, and I do know about list comprehensions from Erlang.

I agree that this seems to contradict "clarity over brevity".

<br

¡¡¡

—

Alex Popov Jr.

Principal iOS Developer | Shelfie

On Dec 17 2015, at 12:44 pm, Amir Michail via swift-evolution &lt;swift- evolution@swift.org&gt; wrote:
  

On Dec 17, 2015, at 3:27 PM, Adrian Kashivskyy &lt;[adrian.kashivskyy@me.com](mailto:adrian.kashivskyy@me.com)&gt; wrote:

Amir, your proposal contradicts "clarity over brevity" principle. As

pointed by Liam all those things are fairly easy to do without any major
complexity.

I think the comprehensions are very clear though.

Pozdrawiam – Regards,

Adrian Kashivskyy

Wiadomość napisana przez Amir Michail via swift-evolution &lt;[swift-

evolution@swift.org](mailto:swift-evolution@swift.org)&gt; w dniu 17.12.2015,
o godz. 17:26:

Python examples:
  
l = [x*x for x in range(10)] // list comprehension
  
l2 = [(x,y) for x in range(10) for y in range(10) if x + y &lt; 8] // another
list comprehension
  
g = (x*x for x in range(10)) // generator comprehension
  
d = {x:x*x for x in range(10)} // dictionary comprehension
  
I think most programmers would like using these. They are concise and easy to
understand.
  
_______________________________________________
swift-evolution mailing list
[swift-evolution@swift.org](mailto:swift-evolution@swift.org)
<https://lists.swift.org/mailman/listinfo/swift-evolution&gt;

!(https://u2002410.ct.sendgrid.net/wf/open?upn=CmwAv3oRa0AH4Hd1bWC6X-
2BzbhPqo1YEo6mPHEujr90sblMts0lyHPlhqzvj-2Fp-2BC5OEMkczNuE6qNGof856voE-
2BZnswBliGIoLaS-2BjycYlE0gnxN5cGJ98YQMEUtmMgZFbBpSh1ddBJSm21Gb1SvtRV0
-2BUl5I9pgd4gfaSj3QH9liTjcXY0B-2FKLe-
2BGskz0t2ZkdLzgQYgLttL6QnIT6UrERxZgyT9dQfFRCqL1CVFzAU-3D)

2 Likes

Amir, your proposal contradicts "clarity over brevity" principle. As pointed by Liam all those things are fairly easy to do without any major complexity.

I think the comprehensions are very clear though.

¡¡¡

On Dec 17, 2015, at 3:27 PM, Adrian Kashivskyy <adrian.kashivskyy@me.com> wrote:

Pozdrawiam – Regards,
Adrian Kashivskyy

Wiadomość napisana przez Amir Michail via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> w dniu 17.12.2015, o godz. 17:26:

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Yup, I thought it zips them (creates pairs of (1, 1), (2, 2), (3, 3), etc.).

Pozdrawiam – Regards,
Adrian Kashivskyy

¡¡¡

Wiadomość napisana przez Alex Popov via swift-evolution <swift-evolution@swift.org> w dniu 17.12.2015, o godz. 22:50:

Data of 1: I misunderstood the second comprehension until I saw it written in Swift, and I do know about list comprehensions from Erlang.

I agree that this seems to contradict "clarity over brevity".

—
Alex Popov Jr.
Principal iOS Developer | Shelfie

On Dec 17 2015, at 12:44 pm, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 17, 2015, at 3:27 PM, Adrian Kashivskyy <adrian.kashivskyy@me.com <mailto:adrian.kashivskyy@me.com>> wrote:

Amir, your proposal contradicts "clarity over brevity" principle. As pointed by Liam all those things are fairly easy to do without any major complexity.

I think the comprehensions are very clear though.

Pozdrawiam – Regards,
Adrian Kashivskyy

Wiadomość napisana przez Amir Michail via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> w dniu 17.12.2015, o godz. 17:26:

Python examples:

l = [x*x for x in range(10)] // list comprehension

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8] // another list comprehension

g = (x*x for x in range(10)) // generator comprehension

d = {x:x*x for x in range(10)} // dictionary comprehension

I think most programmers would like using these. They are concise and easy to understand.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Whether Comprehensions should be introduced to the language is worth consideration (Are they vital? Probably not). But I don’t find the Swift examples using ‘for' statements particularly compelling. The ‘for’ statement needs to declare a mutable variable which is updated from within the loop. It works, but it’s not particularly elegant.

var l2: [(Int, Int)] =
for x in 1...10 {
  for y in 1...10 where (x + y) < 8 {
    l2.append((x, y))
  }
}

It could be achieved using an expression, but it’s pretty horrible too for several reasons:

let l3 = (1...10).flatMap { x in
  (1...10).map { y in (x,y) }
}.filter { (x, y) in x + y < 8 }

(Maybe there’s a more elegant solution?)

If Swift had Comprehensions, they probably wouldn’t look exactly like the example below, but in my opinion it’s superior to the 2 code samples above.

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8]

Al

¡¡¡

On 17 Dec 2015, at 20:25, Liam Butler-Lawrence via swift-evolution <swift-evolution@swift.org> wrote:

Comprehensions are great in Python. However, Swift can already do all of these things via for...in, map() and/or generate().

Using a sequence meant to represent a [Cartesian Product](
https://github.com/griotspeak/CartesianProduct\)

You can write this

        for (i, j) in (0...10) • (0...10) where i + j < 8 {

            print(i)

        }

I am not dead set on the • operator as cartesian product and only added it
back in to demonstrate that this can be *this* pretty.

TJ

¡¡¡

On Thu, Dec 17, 2015 at 7:41 PM, Al Skipp via swift-evolution < swift-evolution@swift.org> wrote:

On 17 Dec 2015, at 20:25, Liam Butler-Lawrence via swift-evolution < > swift-evolution@swift.org> wrote:

Comprehensions are great in Python. However, Swift can already do all of
these things via for...in, map() and/or generate().

Whether Comprehensions should be introduced to the language is worth
consideration (Are they vital? Probably not). But I don’t find the Swift
examples using ‘for' statements particularly compelling. The ‘for’
statement needs to declare a mutable variable which is updated from within
the loop. It works, but it’s not particularly elegant.

var l2: [(Int, Int)] =
for x in 1...10 {
  for y in 1...10 where (x + y) < 8 {
    l2.append((x, y))
  }
}

It could be achieved using an expression, but it’s pretty horrible too for
several reasons:

let l3 = (1...10).flatMap { x in
  (1...10).map { y in (x,y) }
}.filter { (x, y) in x + y < 8 }

(Maybe there’s a more elegant solution?)

If Swift had Comprehensions, they probably wouldn’t look exactly like the
example below, but in my opinion it’s superior to the 2 code samples above.

l2 = [(x,y) for x in range(10) for y in range(10) if x + y < 8]

Al

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Has there been any progress in adding Python's comprehensions to Swift?

To my knowledge, there hasn't been any work on adding Python-style comprehensions in Swift. However, there has been work on other parts of Swift (such as improving the APIs for collection types and the introduction of Swift Algorithms) which practically eliminates the need for comprehensions. All four examples given can already be trivially written in Swift today.

import Algorithms

let l = (0..<10).map { x in x * x }
let l2 = product(0..<10, 0..<10).filter { x, y in x + y < 8 }
let g = (0..<10).lazy.map { x in x * x }
let d = Dictionary(uniqueKeysWithValues: (0..<10).lazy.map { x in (x, x * x) })
6 Likes

Python comprehensions are clear and easy to understand though.

I don’t understand the point if the same effect can already be achieved with .map?

1 Like

Comprehensions are easier to read and write than using map and filter.

They really aren’t, practically by definition. They’re tough to write due to the many operators with varied meanings and much harder to read for the same reason. Swift suffers a bit here due to the use of functional terms rather than plain English, but at least there’s some knowledge transfer from other domains. Comprehensions are inscrutable to anyone who isn’t already familiar with them.

17 Likes

and yet the population of people who learn python is enormous compared to the number of people who learn swift. so i think the “knowledge transfer” argument is one in favor of adding comprehensions to swift.

Only if you know Python already. I looked at the examples, and I understood none of them.

3 Likes

If we added every feature found in more popular languages, Swift wouldn't be Swift. It would be a Frankenstein's monster of those other languages.

The Core Team does look to other languages for inspiration and guidance for new features, because there's no value in coming up with new syntax or semantics out of some kind of NIH infection.

3 Likes

swift does add “every feature found in more popular languages”. other languages have class inheritance, so we have class inheritance. other languages have type erasure, so we have Any and any. other languages have dynamic member lookup, so we have dynamic member lookup. other languages have macros, so it looks like we are getting macros.

none of these are things that i think should show up (frequently) in “good quality” swift code. and yet the language supports them because these are things developers from other universes are used to, and it didn’t, then swift would just continue existing in it’s own little bubble.

NIH infection?

1 Like