5 ms·
List Comprehension in Swift
- catnaroek 9y ago> List comprehension should be no stranger to a Python or (and?) Haskell user. It’s a really compact syntax that deals with Cartesian product [emphasis mine] of lists. Ugh, no. I fail to see where the Cartesian product is in:: [(x,y,z) | x <- [1..5], y <- [x..10], z <- [x..y]] --- @dennisvennink What you feel doesn't matter. It's not a zip.
- falcor84 9y agoI'm not sure of the original intent, but you could approach this as the Cartesian product of [1..5] * [1..10] * [1..10] which is then filtered such that the 2nd value is not smaller than the first, and the 3rd value is inclusively between the two
- catnaroek 9y agoA subset of a Cartesian product is not a Cartesian product. inb4, spare me the wisecrack “It's the Cartesian product of itself and no other factors”.
- timjver 9y ago> It’s a really compact syntax that deals with Cartesian product of lists. Couldn't taking the subset of a Cartesian product be considered to be dealing with one?
- falcor84 9y agoExactly. Indeed, from what I recall from relational database theory, joins are usually treated as cartesian products (outer joins) which are then filtered by the join condition.
- dennisvennink 9y agoIndeed. Feels more like a zip (or convolution) to me.
- unfamiliar 9y agoI think you're being downvoted for being pedantic (and rude, in your edit), but I agree. This is a pretty good example of software engineers adopting mathematical terms they don't quite grasp in order to add an air of rigour to what they write. The statement is unhelpful for anyone that doesn't know what a Cartesian product is and irritatingly inaccurate for anyone who does.
- thewayfarer 9y ago> (Can’t wait until we can have variadic generic parameters!) This.
- stevedonovan 9y agoIt's a genuinely hard problem. There are proposals for Rust, but nothing actionable. Catching up with all the other cool things takes precedence. (side-note: Rust dodged the problem by using macros. As a C++ guy, I was a little uneasy with this, but they're _mostly_ hygenic)
- saghm 9y agoOut of curiosity, what are the non-hygienic parts are of Rust macros? I'm pretty sure that non-procedural macros are hygienic, although I don't know a whole lot about the implementation of procedural macros.
- steveklabnik 9y agoQuoting the subreddit the other day: > Nothing except local variable names (and nested macro capture names) is hygienic in macro_rules in fact. It's a thing that's being fixed in the new macro systems, yeah.
- catnaroek 9y agoCould you mention a genuine use case for variadic generics that's not “working around the stupidity of not reusing tuple types for so-called ‘n-ary’ procedures”?
- deleted 9y ago[deleted]
- 59nadir 9y agoI really dislike the proposed way to do this. If this is "Swifty", give me something else. The Haskell list comprehension made sense to me the first time I saw it, but there is no way I'd know what the mess in the article was doing until someone explained to me. Design has to come first. You can't just go with what's "Swifty" if that doesn't convey what's happening in a reasonable fashion.
- douglaswlance 9y agoDo you know Swift...?
- 59nadir 9y agoNo, but I didn't know Haskell the first time I saw a Haskell list comprehension either, and it still made perfect sense. The proposed Swift solution just looks like Perl level line noise. The only good thing about it is the processing being done in a block at the end.
- coldtea 9y ago>The Haskell list comprehension made sense to me the first time I saw it, but there is no way I'd know what the mess in the article was doing until someone explained to me. Given that this is basic Swift, the complaint makes no sense: let a = Array(1..<5, 3..<5, where: { n, _ in n % 2 == 0 }) { ($0, $1) } // [(2,3),(2,4),(2,5) ... let a = Array(1..<5, 3..<5) { ($0, $1) } // [(1,3),(1,4),(1,5),(2,3),(2,4) ...
- dozzie 9y agoWhat the heck? Why does it end up like this? I see very little connection, and I've seen list comprehensions in several different languages.
- 59nadir 9y agoThat's precisely it. It just looks like a bunch of noise and then there's a result. People complain about list comprehensions in several languages where at least there is a structure to them and they don't look like crap. I can't imagine what the Swift community would say about code clarity and usage recommendations with regards to this proposition.
- ralfd 9y agoCan someone explain the n modulo operation to me?
- fiala__ 9y agoit's an easy way to filter out odd/even numbers. `n % m` means "divide `n` by `m` and return the remainder". If you divide any even number by 2, the remainder is always 0, if you divide an odd number, it's always 1. Translate that to a boolean and you've got a nice odd/even filter.
- Someone 9y agoList comprehension is a bad idea, IMO. They were an improvement over not having anything like it, but python has improved over it (https://wiki.python.org/moin/Generators https://wiki.python.org/moin/Generators) ⇒ Generator expressions are the way to go. They would give you the sequence of elements without generating the (potentially enormous) data structure. From there, methods to reify the items in a sequence would give you your list, array, or dictionary, where needed. So, for Swift, I wouldn’t use Array(1..<5, 3..<5) { ($0, $1) } but the slightly longer Array(for i in 1..<5, j in 3..<5 yield (i,j)) I’m not sure that is easy to fit in the existing parser, though. If it can be fit in, I would allow that code in ‘normal’ nested for loops, too.
- rbehrends 9y agoThis does not require a different syntax. You'd just construct a lazy list instead of an array. Neither is an improvement over the other. Sometimes it's more important to have the results up front fast, sometimes generating them on demand is better.