I agree we shouldn’t have both, that would cause confusion/bloat. The downside
I see of making zip a method on Sequence is that the first argument is not
somehow more “special” than the second. Were it not for the chaining (and
discoverability) issue, I’d be against it – it feels right as a free function.
By the same rationale, would max be a method on Comparable?
The bouncing-right-to-left issue is a more general problem, and is also a
problem with feeding results into initializers. An alternative is that someday
we could add the pipe-forward operator:
(note this is not a pitch, just a someday-idea :-)
// precedence would need some thought
infix operator |>
func |> <T,U>(lhs: T, rhs: (T)->U) -> U {
return rhs(lhs)
}
let words = ["five","four","three","two","one","blastoff!"]
((0...5).reversed() |> { zip($0, words) })
.forEach { print($0.0,$0.1, separator: ": ") }
Still pretty ugly though. Some language sugar (again not a pitch) might help:
((0...5).reversed() |> zip(_, words))
.forEach { print($0.0,$0.1, separator: ": ") }
Then again, I don’t know if facilitating chaining like this is really that
important. I usually find assigning to an intermediate variable to be just as
readable when the chaining doesn’t quite flow right.
> On May 7, 2017, at 11:01 AM, Xiaodi Wu <[email protected]> wrote:
>
> I don't see where anything is broken. It sounds like you simply prefer one
> style over another, which is fine but cannot justify two features in the
> standard library that do the same thing. As you demonstrate, you can easily
> write your own method if that's your preference.
> On Sun, May 7, 2017 at 04:18 Pavol Vaskovic <[email protected]
> <mailto:[email protected]>> wrote:
>
>> On 7 May 2017, at 10:30, Xiaodi Wu <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Sorry, I'm confused: what is the point of adding a method that does the same
>> thing as an existing free function? With one-sided ranges now a part of the
>> language, I'd support removal of `enumerated()` with no other changes.
>
> I’m talking about scenario where you have a chain of sequence operations, say:
>
> (1...N).makeIterator().enumerated().lazy.prefix(while: {$0.0 <
> oneLess}).count()
>
> With a free function, you need to break the chain in order to replace
> enumerated with zip:
>
> zip((1...N).makeIterator(), 0...oneLess).lazy.prefix(while: {$0.0 <
> oneLess}).count()
>
> It forces you to rearrange your code into less than ideal order. Free
> function zip works great if you start with it. Not when you need to employ it
> in the middle of the chain.
>
> (1...N).makeIterator().zipped(with: 0...oneLess).lazy.prefix(while: {$0.0 <
> oneLess}).count()
>
> Just to be clear, how much change I’m proposing here, in case we remove
> enumerated:
>
> extension Sequence {
> func zipped<S>(with otherSequence: S) -> Zip2Sequence<Self, S> where S:
> Sequence {
> return zip (self, otherSequence)
> }
> }
>
> Best regards
> Pavol Vaskovic
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution