If something is to happen I cast my vote for #2.

I actually—and intentionally—use what that would call `numbered()` rather 
frequently; it’s not hard to write but not having to write it is nicer.

Since the “indexed” version is also useful it’d be nice to have both, and with 
unambiguous names.

> On Apr 15, 2016, at 4:59 PM, Brent Royal-Gordon via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> A discussion in the "mapValues" thread reminded me of a longstanding issue I 
> have with Swift.
> 
> `enumerate()` is an attractive nuisance. (That is, it looks like the thing 
> you want, but it's not actually the right one.) Most people use it because 
> they want to enumerate over indices and elements at the same time. In 
> reality, though, the first element of an `enumerate()` tuple is not the 
> index—it's a monotonically increasing integer starting at 0. That *happens* 
> to work for `Array`:
> 
>>        1>     let array = Array(0..<10) 
>>        2.     for (i, elem) in array.enumerate() { 
>>        3.         print(array[i]) 
>>        4.     }
>>      0
>>      1
>>      2
>>      3
>>      4
>>      5
>>      6
>>      7
>>      8
>>      9
> 
> But if you stray even a little bit from the golden path, things start to go 
> wrong:
> 
>>        5>     let range = array[2..<8]
>>        6.     for (i, elem) in range.enumerate() { 
>>        7.         print(range[i])
>>        8.     } 
>>      fatal error: Index out of bounds
> 
> You can scarcely blame users for making this mistake, though—"The Swift 
> Programming Language" encourages the misconception. "Iterating Over an Array" 
> in "Collection Types":
> 
>> If you need the integer index of each item as well as its value, use the 
>> `enumerate()` method to iterate over the array instead. For each item in the 
>> array, the `enumerate()` method returns a tuple composed of the index and 
>> the value for that item.
> 
> 
> While the text is technically accurate—it only talks about iterating over 
> arrays and the numbers generated by `enumerate()` happen to correspond to 
> array indices—it creates a false implication that `enumerate()` is defined to 
> return indices, which isn't true of other collections.
> 
> This is made worse by the fact that `enumerate()` is not really a good name. 
> It is not a common word, so people don't read it and immediately understand 
> what it does; they memorize a Swift-specific meaning, and that meaning may 
> incorporate the misconception that `enumerate()` includes indices. It is also 
> not technically accurate: although it has "number" in its Latin roots, 
> "enumerate" means either "to count" or "to list", not "to number" (i.e. 
> assign numbers to). I know `enumerate()` is used in a couple of other 
> languages (certainly Python, possibly others), but I don't think that 
> overrides the fact that it's confusing.
> 
> I have three possible solutions to propose.
> 
> 
> 
> OPTION ONE
> 
> * Remove `enumerate()`.
> 
> * Provide a type and postfix operator which allows you to write an infinite 
> sequence as `0...`. (This might call a ClosedRange constructor which 
> constrains the type to a protocol which provides `max`. This would imply that 
> `FloatingPoint` and `Integer` protocols would need to conform to a common 
> protocol declaring a `max` property, and in the case of `FloatingPoint`, 
> `max` should probably be positive infinity.)
> 
> * Fix-It calls to `x.enumerate()` as `zip(0..., x)`. This is more complicated 
> to look at, but it's *far* more explicit about what the operation actually 
> does. (For bonus points, we could perhaps look at how the EnumerateSequence 
> is used, and if the number is used as an index, go with `zip(x.indices, x)` 
> instead.)
> 
> 
> 
> OPTION TWO
> 
> * Rename `enumerate()` to something more explicit, like `withIntegers()` or 
> `numbered()`. (It might even make sense to add a `from:` parameter which 
> defaults to 0.)
> 
> * Add to Collection an equivalent method with a similar name that provides 
> indices, like `withIndices()` or `indexed()`.
> 
> * Fix-It calls to `enumerate()` into either `numbered()` or `indexed()` (or 
> whatever they end up being called) depending on the way they are used.
> 
> 
> 
> OPTION THREE
> 
> Combine the other two options:
> 
> * Provide the infinite numeric sequence type from Option One.
> 
> * Provide `numbered()` and `indexed()` (or whatever) methods which are 
> explicitly typed to merely zip over the sequence/collection with an infinite 
> integer sequence/Indices collection.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> _______________________________________________
> swift-evolution mailing list
> 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

Reply via email to