Re: [swift-evolution] Removing enumerated?

2017-02-17 Thread Ole Begemann via swift-evolution

> On 17 Feb 2017, at 16:53, Vladimir.S via swift-evolution 
>  wrote:
> 
> Btw, in context of discussion of indices,
> should this be fixed soon:
> 
> func function(c: C) {
>  for index in c.indices {
>print(c[index])
>  }
> }
> ERROR: cannot subscript a value of type 'C' with an index of type 
> 'C.Indices.Iterator.Element'
> 
> ?
> (have access for Swift 3.0.2 Release only for now, so probably this already 
> fixed in dev version)

This will work once SE-0142 "Permit where clauses to constrain associated 
types" 
(https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md)
 is implemented and the standard library takes advantage of this.

For the time being, you need to add an explicit constraint to the function:

func function(c: C)
where C.Indices.Iterator.Element == C.Index {
for index in c.indices {
print(c[index])
}
}

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


Re: [swift-evolution] Removing enumerated?

2017-02-17 Thread Vladimir.S via swift-evolution

Btw, in context of discussion of indices,
should this be fixed soon:

func function(c: C) {
  for index in c.indices {
print(c[index])
  }
}
ERROR: cannot subscript a value of type 'C' with an index of type 
'C.Indices.Iterator.Element'


?
(have access for Swift 3.0.2 Release only for now, so probably this already 
fixed in dev version)


On 01.02.2017 1:54, Xiaodi Wu via swift-evolution wrote:

On Tue, Jan 31, 2017 at 1:16 PM, Ben Cohen via swift-evolution
> wrote:

I think whether enumerated() is justified as a method on Sequence is
one example of a wider question which definitely needs some discussion,
which is: where should the standard library draw the line in providing
convenience functions that can easily be composed from other functions
in the std lib? Here’s another example:

SE-100


 is
a proposal to add an init to Dictionary from a sequence of key/value
pairs. It’s a commonly requested feature, and IMO much needed and
should be added as soon as we move to the appropriate phase in Swift’s
evolution.

Another commonly requested Dictionary feature is similar: add a
Dictionary.init that takes a sequence, and a closure that maps that
sequence to keys. This is useful, for example, when you have a sequence
of objects that you frequently need to index into via one property on
those objects, so you want to build a fast lookup cache using that
property.

Now, if we implement SE-100, that second request can be easily
composed. It would be something like Dictionary(sequence.lazy.map {
(key: $0.someProperty, value: $0) } )

Some people look at that line of code and think sure, that’s what I’d
do and it’s easy enough that the second helper shouldn’t be added as
it’s superfluous. Others look at it and say that it is unreadable
clever-code FP nonsense, and we should just add the helper method
because most programmers wouldn’t be able to read or write that easily.

As we expand (and maybe contract :) the standard library, this kind of
question comes up a lot, so it is worth setting out some criteria for
judging these “helper” methods. Here’s my take on such a list (warning:
objectivity and subjectivity blended together in the below).

*1. Is it truly a frequent operation?*

The operation needs to carry its weight. Even once we have ABI
stability, so the size of the std lib becomes less of a concern as it
could ship as part of the OS, we still need to keep helper method
growth under control. APIs bristling with methods like an
over-decorated Xmas tree are bad for usability. As mentioned in the
String manifesto, String+Foundation currently has over 200
methods/properties. Helpers are no good if you can’t find them to use them.

Someone mentioned that they actually don’t find themselves using
enumerated() all that often. I suspect enumerated in its current form
isn’t all that useful. In a quick (and non-scientific) review of search
results for its use on GitHub, nearly all the examples I see of it are
either 1) misuse – see more below, or 2) use of it to perform the
equivalent of in-place map where the index is used to subscript into
the array and replace it with a transformed element.


So, in general, I agree with your overarching points. But I have to push
back on this part:

Although it's clearly a misuse when one assumes `startIndex == 0` while
working with a generic Collection, it's been said on this list many times
that `0..

Re: [swift-evolution] Removing enumerated?

2017-02-06 Thread Dave Abrahams via swift-evolution

on Sun Feb 05 2017, Patrick Pijnappel  wrote:

> Note that zip(a.indices, a) requires advancing the index twice each
> iteration, which for non-array collections is not necessarily super
> trivial. Considering we're talking about such a low-level operation as
> iterating through a collection this might be worth considering.

If you're worried about this, there's a really easy solution: write your
loop over a.indices and the subscript a using those indices to get the
element.

> Personally I'm in favor of adding indexed().

As mentioned earlier in the thread, I'm strongly opposed to adding it at
this time.

-- 
-Dave

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


Re: [swift-evolution] Removing enumerated?

2017-02-05 Thread Ben Cohen via swift-evolution
> On Feb 5, 2017, at 16:47, Patrick Pijnappel  
> wrote:
> 
> Note that zip(a.indices, a) requires advancing the index twice each 
> iteration, which for non-array collections is not necessarily super trivial. 
> Considering we're talking about such a low-level operation as iterating 
> through a collection this might be worth considering.
> 
> Personally I'm in favor of adding indexed().
> 

This isn't necessarily as much of a slam-dunk as you might think. Just as index 
advancement can theoretically be expensive, so can subscripting (though both 
need to be constant time, the constant factor could be high for either). Unless 
we made indexed() a protocol customization point rather than an extension 
(unlikely – we need to keep the number of those under control) and the 
collection provided a customized version, indexed() would need to use 
subscripting to return the element given the index it's tracking. Whereas 
iteration, being a much more limited forward-only API, might be implemented to 
be more efficient. So it's one hypothetical cost vs another. Alternatively, 
indexed() could be implemented to use an iterator for the elements part in 
parallel to the index advancement, in which case it's identical to the zip 
version. At least with the zip version, it's transparent which strategy is 
being used. In practice, for any Collection both costs should ideally be kept 
as small as possible, and so their cost is hopefully not material often enough 
to be factored into the decision of whether indexed() should exist on 
Collection, which should be decided on API ergonomics grounds.


PS for the standard library collections at least, any benchmarks that find that 
indexing/subscripting is significantly faster than iteration should be raised 
as bugs against the std lib/compiler/optimizer depending on where the problem 
is :)

>> On Mon, Feb 6, 2017 at 3:14 AM, Ben Cohen via swift-evolution 
>>  wrote:
>> On Feb 5, 2017, at 08:12, Ben Cohen  wrote:
>> 
>> >> On Feb 4, 2017, at 14:43, Dave Abrahams via swift-evolution 
>> >>  wrote:
>> >>
>> >>
>> >> on Fri Feb 03 2017, Ben Cohen  wrote:
>> >>
>>  On Feb 3, 2017, at 3:27 PM, Dave Abrahams via swift-evolution
>>   wrote:
>> 
>>  I don't always make zip a method, but when I do, its argument label is
>>  “to:”
>> >>>
>> >>> Hmm, that doesn’t sound very natural to me.
>> >>>
>> >>> Then again the problem with “zip(with:)" is it’s already kind of a
>> >>> term of art for a version that takes a function to combine the two
>> >>> values.
>> >>>
>> >>> There’s also the question of how to spell a non-truncating versions
>> >>> (returning optionals or taking a pad value).
>> >>
>> >> Is there a use-case for such a zip?
>> >>
>> >
>> > Whenever it's not OK to not silently discard the elements in the longer 
>> > list (which can be a correctness trap of zip if you're not careful). Say 
>> > you're matching up contestants from two groups, but want to give byes to 
>> > the unmatched contestants in the larger group. Or you're generating a list 
>> > of positioned racers in a 8-car race, putting in a computer player when 
>> > you run out of real players.
>> >
>> 
>> Gah, accidental double-negation, meant "not OK to silently discard"
>> 
>> >> --
>> >> -Dave
>> >>
>> >> ___
>> >> 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
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Removing enumerated?

2017-02-05 Thread Patrick Pijnappel via swift-evolution
Note that zip(a.indices, a) requires advancing the index twice each
iteration, which for non-array collections is not necessarily super
trivial. Considering we're talking about such a low-level operation as
iterating through a collection this might be worth considering.

Personally I'm in favor of adding indexed().

On Mon, Feb 6, 2017 at 3:14 AM, Ben Cohen via swift-evolution <
swift-evolution@swift.org> wrote:

> On Feb 5, 2017, at 08:12, Ben Cohen  wrote:
>
> >> On Feb 4, 2017, at 14:43, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >>
> >> on Fri Feb 03 2017, Ben Cohen  wrote:
> >>
>  On Feb 3, 2017, at 3:27 PM, Dave Abrahams via swift-evolution
>   wrote:
> 
>  I don't always make zip a method, but when I do, its argument label is
>  “to:”
> >>>
> >>> Hmm, that doesn’t sound very natural to me.
> >>>
> >>> Then again the problem with “zip(with:)" is it’s already kind of a
> >>> term of art for a version that takes a function to combine the two
> >>> values.
> >>>
> >>> There’s also the question of how to spell a non-truncating versions
> >>> (returning optionals or taking a pad value).
> >>
> >> Is there a use-case for such a zip?
> >>
> >
> > Whenever it's not OK to not silently discard the elements in the longer
> list (which can be a correctness trap of zip if you're not careful). Say
> you're matching up contestants from two groups, but want to give byes to
> the unmatched contestants in the larger group. Or you're generating a list
> of positioned racers in a 8-car race, putting in a computer player when you
> run out of real players.
> >
>
> Gah, accidental double-negation, meant "not OK to silently discard"
>
> >> --
> >> -Dave
> >>
> >> ___
> >> 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
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Removing enumerated?

2017-02-05 Thread Ben Cohen via swift-evolution
On Feb 5, 2017, at 08:12, Ben Cohen  wrote:

>> On Feb 4, 2017, at 14:43, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Fri Feb 03 2017, Ben Cohen  wrote:
>> 
 On Feb 3, 2017, at 3:27 PM, Dave Abrahams via swift-evolution
  wrote:
 
 I don't always make zip a method, but when I do, its argument label is
 “to:”
>>> 
>>> Hmm, that doesn’t sound very natural to me.
>>> 
>>> Then again the problem with “zip(with:)" is it’s already kind of a
>>> term of art for a version that takes a function to combine the two
>>> values.
>>> 
>>> There’s also the question of how to spell a non-truncating versions
>>> (returning optionals or taking a pad value).
>> 
>> Is there a use-case for such a zip?
>> 
> 
> Whenever it's not OK to not silently discard the elements in the longer list 
> (which can be a correctness trap of zip if you're not careful). Say you're 
> matching up contestants from two groups, but want to give byes to the 
> unmatched contestants in the larger group. Or you're generating a list of 
> positioned racers in a 8-car race, putting in a computer player when you run 
> out of real players.
> 

Gah, accidental double-negation, meant "not OK to silently discard"

>> -- 
>> -Dave
>> 
>> ___
>> 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


Re: [swift-evolution] Removing enumerated?

2017-02-05 Thread Ben Cohen via swift-evolution
> On Feb 4, 2017, at 14:43, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Fri Feb 03 2017, Ben Cohen  wrote:
> 
>>> On Feb 3, 2017, at 3:27 PM, Dave Abrahams via swift-evolution
>>>  wrote:
>>> 
>>> I don't always make zip a method, but when I do, its argument label is
>>> “to:”
>> 
>> Hmm, that doesn’t sound very natural to me.
>> 
>> Then again the problem with “zip(with:)" is it’s already kind of a
>> term of art for a version that takes a function to combine the two
>> values.
>> 
>> There’s also the question of how to spell a non-truncating versions
>> (returning optionals or taking a pad value).
> 
> Is there a use-case for such a zip?
> 

Whenever it's not OK to not silently discard the elements in the longer list 
(which can be a correctness trap of zip if you're not careful). Say you're 
matching up contestants from two groups, but want to give byes to the unmatched 
contestants in the larger group. Or you're generating a list of positioned 
racers in a 8-car race, putting in a computer player when you run out of real 
players.

> -- 
> -Dave
> 
> ___
> 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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Shawn Erickson via swift-evolution
I use enumerated in many location in my code and have never expected it to
be indexes but a counting of how many times I have looped. It says clearly
what is does on the tin: "Returns a sequence of pairs (n, x), where n
represents a consecutive integer starting at zero, and x represents an
element of the sequence.". I get some new folks have confusion but reading
the docs is always part of learning IMHO.

I would hate to see it removed without strong replacement that is
reasonably readable. I think leveraging zip and the potential range style
is on the edge of being readable but is learnable.

-Shawn
On Fri, Feb 3, 2017 at 4:11 PM Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

>
> > On Feb 3, 2017, at 4:20 PM, Dave Abrahams  wrote:
> >
> >
> > on Fri Feb 03 2017, Erica Sadun  wrote:
> >
> >>> On Feb 3, 2017, at 2:58 PM, Ben Cohen  wrote:
> >>>
> >>>
>  On Feb 3, 2017, at 11:12 AM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org
> >> > wrote:
> 
> >>
>  I believe what people *want* is `indexed` over `enumerated`, and
> consistently for both array and array slices.
> 
> >>>
> >>> I don’t know if that’s true.
> >>>
> >>> Here’s an example (the only use of enumerated) from Alamofire:
> >>>
> >>> let acceptLanguage =
> Locale.preferredLanguages.prefix(6).enumerated().map { index, languageCode
> in
> >>>let quality = 1.0 - (Double(index) * 0.1)
> >>>return "\(languageCode);q=\(quality)"
> >>> }.joined(separator: ", ")
> >>>
> >>> Here the intent is a counter, not indices. They just happen to be the
> same. But if they’d used indexed() it would certainly hurt readability,
> albeit midly.
> >>>
> >>> Suppose there wasn’t an enumerate or an indexed, and zipped was the
> standard way of doing it. That might lead to another solution:
> >>>
> >>> let qualities = stride(from: 1.0, to: 0.4, by: -0.1)
> >>> let acceptLanguage = Locale.preferredLanguages.zipped(with:
> qualities).map {
> >>>languageCode, quality in "\(languageCode);q=\(quality)"
> >>> }.joined(separator: ", ")
> >>>
> >>> The use of stride here feels more what was intended, rather than
> >>> backing into the quality via an “index” value. And avoids any risk
> >>> with indexed of this getting applied incorrectly to slices.
> >>>
> >>
> >> I think enumerated as it stands is an attractive nuisance / moral
> >> hazard. Most of the language learners I interact with miss the point
> >> and the nuance of how it works.
> >>
> >> let list = [0, 1, 2, 3, 4]
> >> let slice = list[2...3]
> >> for (idx, value) in slice.enumerated() {
> >>print(idx, value)
> >> }
> >>
> >> I think people would not expect 0, 2 / 1, 3. I also don’t think they’d
> >> expect the actual outcome from a dictionary, whether index or
> >> enumeration because there’s no inherent semantic “enumeration” of
> >> dictionary values:
> >>
> >> let dict = [0:"a", 1:"b", 2:"c"]
> >> for (idx, value) in dict.enumerated() {
> >>print(idx, value)
> >> }
> >>
> >> 0 (2, "c")
> >> 1 (0, "a")
> >> 2 (1, "b")
> >>
> >> I’d like to see enumerated gone and I have a mild preference for
> >> introducing indexed, either under its own name or as a new behavior
> >> for enumerated (although T where T.Iterator.Element is Int)
> >>
> >> 120 gists with “enumerated”, of which a casual scan shows that almost
> >> none of them are actually using it meaningfully. (Take a look.) I
> >> think I did this API right:
> >> https://api.github.com/search/repositories?q=enumerate+language:swift
> >> 
> >> and if so, not much in repos.
> >
> > Ben's not arguing that enumerated should stay.  He's just saying that
> > there's no good reason to provide indexed(), and I agree with that.
> >
> > --
> > -Dave
>
> And I think I just argued my way to agreeing with him.
>
> -- E
>
>
> ___
> 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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Erica Sadun via swift-evolution

> On Feb 3, 2017, at 4:20 PM, Dave Abrahams  wrote:
> 
> 
> on Fri Feb 03 2017, Erica Sadun  wrote:
> 
>>> On Feb 3, 2017, at 2:58 PM, Ben Cohen  wrote:
>>> 
>>> 
 On Feb 3, 2017, at 11:12 AM, Erica Sadun via swift-evolution 
 > > wrote:
 
>> 
 I believe what people *want* is `indexed` over `enumerated`, and 
 consistently for both array and array slices.
 
>>> 
>>> I don’t know if that’s true.
>>> 
>>> Here’s an example (the only use of enumerated) from Alamofire:
>>> 
>>> let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { 
>>> index, languageCode in
>>>let quality = 1.0 - (Double(index) * 0.1)
>>>return "\(languageCode);q=\(quality)"
>>> }.joined(separator: ", ")
>>> 
>>> Here the intent is a counter, not indices. They just happen to be the same. 
>>> But if they’d used indexed() it would certainly hurt readability, albeit 
>>> midly.
>>> 
>>> Suppose there wasn’t an enumerate or an indexed, and zipped was the 
>>> standard way of doing it. That might lead to another solution:
>>> 
>>> let qualities = stride(from: 1.0, to: 0.4, by: -0.1)
>>> let acceptLanguage = Locale.preferredLanguages.zipped(with: qualities).map {
>>>languageCode, quality in "\(languageCode);q=\(quality)"
>>> }.joined(separator: ", ")
>>> 
>>> The use of stride here feels more what was intended, rather than
>>> backing into the quality via an “index” value. And avoids any risk
>>> with indexed of this getting applied incorrectly to slices.
>>> 
>> 
>> I think enumerated as it stands is an attractive nuisance / moral
>> hazard. Most of the language learners I interact with miss the point
>> and the nuance of how it works.
>> 
>> let list = [0, 1, 2, 3, 4]
>> let slice = list[2...3]
>> for (idx, value) in slice.enumerated() {
>>print(idx, value)
>> }
>> 
>> I think people would not expect 0, 2 / 1, 3. I also don’t think they’d
>> expect the actual outcome from a dictionary, whether index or
>> enumeration because there’s no inherent semantic “enumeration” of
>> dictionary values:
>> 
>> let dict = [0:"a", 1:"b", 2:"c"]
>> for (idx, value) in dict.enumerated() {
>>print(idx, value)
>> }
>> 
>> 0 (2, "c")
>> 1 (0, "a")
>> 2 (1, "b")
>> 
>> I’d like to see enumerated gone and I have a mild preference for
>> introducing indexed, either under its own name or as a new behavior
>> for enumerated (although T where T.Iterator.Element is Int)
>> 
>> 120 gists with “enumerated”, of which a casual scan shows that almost
>> none of them are actually using it meaningfully. (Take a look.) I
>> think I did this API right:
>> https://api.github.com/search/repositories?q=enumerate+language:swift
>> 
>> and if so, not much in repos.
> 
> Ben's not arguing that enumerated should stay.  He's just saying that
> there's no good reason to provide indexed(), and I agree with that.
> 
> -- 
> -Dave

And I think I just argued my way to agreeing with him.

-- E


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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Ben Cohen via swift-evolution

> On Feb 3, 2017, at 3:27 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> I don't always make zip a method, but when I do, its argument label is
> “to:”

Hmm, that doesn’t sound very natural to me.

Then again the problem with “zip(with:)" is it’s already kind of a term of art 
for a version that takes a function to combine the two values.

There’s also the question of how to spell a non-truncating versions (returning 
optionals or taking a pad value).

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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Haravikk via swift-evolution
I'm in favour of getting rid of enumerated; I think like many people I used it 
expecting to get actual indices, and it's very easy to think this when working 
with arrays (as the values will in fact be perfectly valid). In reality the 
right way to do it is with one of the following:

for eachIndex in myArray.indices { print("\(eachIndex): " + myArray[eachIndex]) 
}
for eachIndex in myArray.startIndex ..< myArray.endIndex { print("\(eachIndex): 
" + myArray[eachIndex]) }
var offset = 0; for eachEntry in myArray { print("\(offset): \(eachEntry)"); 
offset += 1 }

However, I think I'd still support the inclusion of an enumerating and an 
indexing type that sequences/collections can be wrapped in to perform 
enumeration/indexing if you still want it.

> On 31 Jan 2017, at 14:24, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Hey everyone,
> 
> I've organized a number of Swift workshops over the last two years. There are 
> a couple of things that keep coming up, and a couple of mistakes that I see 
> people making over and over again. One of them is that in almost every 
> workshop, there's someone who thinks that `enumerated()` returns a list of 
> (index, element) pairs. This is only true for arrays. It breaks when using 
> array slices, or any other kind of collection. In our workshops, I sometimes 
> see people doing something like `x.reversed().enumerated()`, where `x` is an 
> array, and somehow it produces behavior they don't understand.
> 
> A few ways I think this could be improved:
> 
> - Move enumerated to Array
> - Change enumerated to return `(Index, Iterator.Element)` (this would mean we 
> at least need to move it to collection)
> - Remove enumerated
> - Keep things as is
> 
> In any case, just wanted to share my experience (gained from teaching 
> people). 
> 
> -- 
> Chris Eidhof
> ___
> 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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Dave Abrahams via swift-evolution

on Fri Feb 03 2017, Ben Cohen  wrote:

>> On Feb 2, 2017, at 8:46 PM, Chris Lattner 
> wrote:
>> 
>> It seems that you are leaning towards removing enumerated(). 
>
> I’m actually kind of conflicted.
>
> Replacing enumerated() with indexed() feels replacing one problem for
> another. Sometimes people want to number things, and might assume
> indexed() will be zero-based for slices.
>
> Adding indexed() while keeping enumerated() seems too much clutter on
> the API though. Once we have 0… both can be expressed simply with zip,
> and in my view is zip(a, 0…), zip(a, a.indices), zip(1…, a) just as
> clear, maybe clearer in some cases as they will encourage code to show
> intent more (i.e. are you counting or indexing? even when they are the
> same, it’s better to say which). Encouraging learning about zip will
> also help introduce people to better ways of expressing other
> similar-but-different loops.
>
> The trouble with zip is it isn’t discoverable – another entry that
> probably belongs on that list of criteria. Unlike enumerated, users
> aren’t going to stumble over it.
>
> Maybe moving zip to be a method on Sequence rather than a free
> function would help with this? e.g. something like a.zipped(with: 0…),
> a.zipped(with: a.indices). The documentation for it could even
> explicitly mention the counting and index use cases. The main downside
> is it pushes the order of the lhs/rhs to be self first.

I don't always make zip a method, but when I do, its argument label is
“to:”

-- 
-Dave

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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Dave Abrahams via swift-evolution

on Fri Feb 03 2017, Erica Sadun  wrote:

>> On Feb 3, 2017, at 2:58 PM, Ben Cohen  wrote:
>> 
>> 
>>> On Feb 3, 2017, at 11:12 AM, Erica Sadun via swift-evolution 
>>>  > wrote:
>>> 
>
>>> I believe what people *want* is `indexed` over `enumerated`, and 
>>> consistently for both array and array slices.
>>> 
>> 
>> I don’t know if that’s true.
>> 
>> Here’s an example (the only use of enumerated) from Alamofire:
>> 
>> let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { 
>> index, languageCode in
>> let quality = 1.0 - (Double(index) * 0.1)
>> return "\(languageCode);q=\(quality)"
>> }.joined(separator: ", ")
>> 
>> Here the intent is a counter, not indices. They just happen to be the same. 
>> But if they’d used indexed() it would certainly hurt readability, albeit 
>> midly.
>> 
>> Suppose there wasn’t an enumerate or an indexed, and zipped was the standard 
>> way of doing it. That might lead to another solution:
>> 
>> let qualities = stride(from: 1.0, to: 0.4, by: -0.1)
>> let acceptLanguage = Locale.preferredLanguages.zipped(with: qualities).map {
>> languageCode, quality in "\(languageCode);q=\(quality)"
>> }.joined(separator: ", ")
>> 
>> The use of stride here feels more what was intended, rather than
>> backing into the quality via an “index” value. And avoids any risk
>> with indexed of this getting applied incorrectly to slices.
>> 
>
> I think enumerated as it stands is an attractive nuisance / moral
> hazard. Most of the language learners I interact with miss the point
> and the nuance of how it works.
>
> let list = [0, 1, 2, 3, 4]
> let slice = list[2...3]
> for (idx, value) in slice.enumerated() {
> print(idx, value)
> }
>
> I think people would not expect 0, 2 / 1, 3. I also don’t think they’d
> expect the actual outcome from a dictionary, whether index or
> enumeration because there’s no inherent semantic “enumeration” of
> dictionary values:
>
> let dict = [0:"a", 1:"b", 2:"c"]
> for (idx, value) in dict.enumerated() {
> print(idx, value)
> }
>
> 0 (2, "c")
> 1 (0, "a")
> 2 (1, "b")
>
> I’d like to see enumerated gone and I have a mild preference for
> introducing indexed, either under its own name or as a new behavior
> for enumerated (although T where T.Iterator.Element is Int)
>
> 120 gists with “enumerated”, of which a casual scan shows that almost
> none of them are actually using it meaningfully. (Take a look.) I
> think I did this API right:
> https://api.github.com/search/repositories?q=enumerate+language:swift
> 
> and if so, not much in repos.

Ben's not arguing that enumerated should stay.  He's just saying that
there's no good reason to provide indexed(), and I agree with that.

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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Erica Sadun via swift-evolution

> On Feb 3, 2017, at 2:58 PM, Ben Cohen  wrote:
> 
> 
>> On Feb 3, 2017, at 11:12 AM, Erica Sadun via swift-evolution 
>> > wrote:
>> 
>> I believe what people *want* is `indexed` over `enumerated`, and 
>> consistently for both array and array slices.
>> 
> 
> I don’t know if that’s true.
> 
> Here’s an example (the only use of enumerated) from Alamofire:
> 
> let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { 
> index, languageCode in
> let quality = 1.0 - (Double(index) * 0.1)
> return "\(languageCode);q=\(quality)"
> }.joined(separator: ", ")
> 
> Here the intent is a counter, not indices. They just happen to be the same. 
> But if they’d used indexed() it would certainly hurt readability, albeit 
> midly.
> 
> Suppose there wasn’t an enumerate or an indexed, and zipped was the standard 
> way of doing it. That might lead to another solution:
> 
> let qualities = stride(from: 1.0, to: 0.4, by: -0.1)
> let acceptLanguage = Locale.preferredLanguages.zipped(with: qualities).map {
> languageCode, quality in "\(languageCode);q=\(quality)"
> }.joined(separator: ", ")
> 
> The use of stride here feels more what was intended, rather than backing into 
> the quality via an “index” value. And avoids any risk with indexed of this 
> getting applied incorrectly to slices.
> 

I think enumerated as it stands is an attractive nuisance / moral hazard. Most 
of the language learners I interact with miss the point and the nuance of how 
it works.

let list = [0, 1, 2, 3, 4]
let slice = list[2...3]
for (idx, value) in slice.enumerated() {
print(idx, value)
}

I think people would not expect 0, 2 / 1, 3. I also don’t think they’d expect 
the actual outcome from a dictionary, whether index or enumeration because 
there’s no inherent semantic “enumeration” of dictionary values:

 
let dict = [0:"a", 1:"b", 2:"c"]
for (idx, value) in dict.enumerated() {
print(idx, value)
}

0 (2, "c")
1 (0, "a")
2 (1, "b")

I’d like to see enumerated gone and I have a mild preference for introducing 
indexed, either under its own name or as a new behavior for enumerated 
(although T where T.Iterator.Element is Int)

120 gists with “enumerated”, of which a casual scan shows that almost none of 
them are actually using it meaningfully. (Take a look.) I think I did this API 
right: https://api.github.com/search/repositories?q=enumerate+language:swift 
 and if 
so, not much in repos.


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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Ben Cohen via swift-evolution

> On Feb 3, 2017, at 11:12 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> I believe what people *want* is `indexed` over `enumerated`, and consistently 
> for both array and array slices.
> 

I don’t know if that’s true.

Here’s an example (the only use of enumerated) from Alamofire:

let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { 
index, languageCode in
let quality = 1.0 - (Double(index) * 0.1)
return "\(languageCode);q=\(quality)"
}.joined(separator: ", ")

Here the intent is a counter, not indices. They just happen to be the same. But 
if they’d used indexed() it would certainly hurt readability, albeit midly.

Suppose there wasn’t an enumerate or an indexed, and zipped was the standard 
way of doing it. That might lead to another solution:

let qualities = stride(from: 1.0, to: 0.4, by: -0.1)
let acceptLanguage = Locale.preferredLanguages.zipped(with: qualities).map {
languageCode, quality in "\(languageCode);q=\(quality)"
}.joined(separator: ", ")

The use of stride here feels more what was intended, rather than backing into 
the quality via an “index” value. And avoids any risk with indexed of this 
getting applied incorrectly to slices.



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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Matthew Johnson via swift-evolution

> On Feb 3, 2017, at 3:41 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
> 
>> On Feb 2, 2017, at 8:46 PM, Chris Lattner > > wrote:
>> 
>> It seems that you are leaning towards removing enumerated(). 
> 
> I’m actually kind of conflicted.
> 
> Replacing enumerated() with indexed() feels replacing one problem for 
> another. Sometimes people want to number things, and might assume indexed() 
> will be zero-based for slices.
> 
> Adding indexed() while keeping enumerated() seems too much clutter on the API 
> though. Once we have 0… both can be expressed simply with zip, and in my view 
> is zip(a, 0…), zip(a, a.indices), zip(1…, a) just as clear, maybe clearer in 
> some cases as they will encourage code to show intent more (i.e. are you 
> counting or indexing? even when they are the same, it’s better to say which). 
> Encouraging learning about zip will also help introduce people to better ways 
> of expressing other similar-but-different loops.
> 
> The trouble with zip is it isn’t discoverable – another entry that probably 
> belongs on that list of criteria. Unlike enumerated, users aren’t going to 
> stumble over it.
> 
> Maybe moving zip to be a method on Sequence rather than a free function would 
> help with this? e.g. something like a.zipped(with: 0…), a.zipped(with: 
> a.indices). The documentation for it could even explicitly mention the 
> counting and index use cases. The main downside is it pushes the order of the 
> lhs/rhs to be self first.

I think the downside is significant.  I think the visual relationship of 
`zip(a, 0…)` with the tuples it produces is pretty important.  It also scales 
well if (when?) it becomes variadic.

Discoverability is a problem, but no more so than with any other top level 
operator somebody might not be familiar with (Swift has a few of those 
depending on somebody’s background)

I think the discoverability problem is best addressed by identifying and 
raising awareness of common use cases for zip rather than just moving it so it 
appears in autocomplete.  When people learn how it can make their code better 
they will use it.

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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Ben Cohen via swift-evolution

> On Feb 2, 2017, at 8:46 PM, Chris Lattner  wrote:
> 
> It seems that you are leaning towards removing enumerated(). 

I’m actually kind of conflicted.

Replacing enumerated() with indexed() feels replacing one problem for another. 
Sometimes people want to number things, and might assume indexed() will be 
zero-based for slices.

Adding indexed() while keeping enumerated() seems too much clutter on the API 
though. Once we have 0… both can be expressed simply with zip, and in my view 
is zip(a, 0…), zip(a, a.indices), zip(1…, a) just as clear, maybe clearer in 
some cases as they will encourage code to show intent more (i.e. are you 
counting or indexing? even when they are the same, it’s better to say which). 
Encouraging learning about zip will also help introduce people to better ways 
of expressing other similar-but-different loops.

The trouble with zip is it isn’t discoverable – another entry that probably 
belongs on that list of criteria. Unlike enumerated, users aren’t going to 
stumble over it.

Maybe moving zip to be a method on Sequence rather than a free function would 
help with this? e.g. something like a.zipped(with: 0…), a.zipped(with: 
a.indices). The documentation for it could even explicitly mention the counting 
and index use cases. The main downside is it pushes the order of the lhs/rhs to 
be self first.



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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Erica Sadun via swift-evolution

> On Feb 3, 2017, at 10:57 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Thu Feb 02 2017, Chris Lattner  > wrote:
> 
>> On Jan 31, 2017, at 11:16 AM, Ben Cohen via swift-evolution 
>>  wrote:
>>> 
>>> As we expand (and maybe contract :) the standard library, this kind
>>> of question comes up a lot, so it is worth setting out some criteria
>>> for judging these “helper” methods. Here’s my take on such a list
>>> (warning: objectivity and subjectivity blended together in the
>>> below).
>> 
>> This is great perspective Ben, thank you for taking time to write this up!
>> 
>> It seems that you are leaning towards removing enumerated().  What do
>> you think about the proposal of removing enumerated but adding
>> indexed() to replace it?  It would provide the same behavior for
>> common array cases, while providing more useful/defensible
>> functionality for other collections.
> 
> indexed() is trivially composed from other library primitives:
> 
>  zip(c.indices, c)
> 
> enumerated() only exists in the standard library, and was explicitly
> designed as it was, because what it does is not currently easy to
> write.  As soon as we enable "0...", that changes.
> 
> I'm not against having trivial helper functions in principle, but I
> don't think the Standard Library or the language is yet at the stage of
> maturity where we can see clearly which ones are important enough, and
> pay for the API surface area they add.  For that reason I feel strongly
> that for the time being we should remain very conservative about adding
> such things, and only introduce them where there's real compelling
> evidence that they are a win.  There is no such evidence for indexed()
> as far as I can tell.

I believe what people *want* is `indexed` over `enumerated`, and consistently 
for both array and array slices.

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


Re: [swift-evolution] Removing enumerated?

2017-02-03 Thread Dave Abrahams via swift-evolution

on Thu Feb 02 2017, Chris Lattner  wrote:

> On Jan 31, 2017, at 11:16 AM, Ben Cohen via swift-evolution 
>  wrote:
>> 
>> As we expand (and maybe contract :) the standard library, this kind
>> of question comes up a lot, so it is worth setting out some criteria
>> for judging these “helper” methods. Here’s my take on such a list
>> (warning: objectivity and subjectivity blended together in the
>> below).
>
> This is great perspective Ben, thank you for taking time to write this up!
>
> It seems that you are leaning towards removing enumerated().  What do
> you think about the proposal of removing enumerated but adding
> indexed() to replace it?  It would provide the same behavior for
> common array cases, while providing more useful/defensible
> functionality for other collections.

indexed() is trivially composed from other library primitives:

  zip(c.indices, c)

enumerated() only exists in the standard library, and was explicitly
designed as it was, because what it does is not currently easy to
write.  As soon as we enable "0...", that changes.

I'm not against having trivial helper functions in principle, but I
don't think the Standard Library or the language is yet at the stage of
maturity where we can see clearly which ones are important enough, and
pay for the API surface area they add.  For that reason I feel strongly
that for the time being we should remain very conservative about adding
such things, and only introduce them where there's real compelling
evidence that they are a win.  There is no such evidence for indexed()
as far as I can tell.

-- 
-Dave

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


Re: [swift-evolution] Removing enumerated?

2017-02-02 Thread Erica Sadun via swift-evolution

> On Feb 2, 2017, at 9:46 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> On Jan 31, 2017, at 11:16 AM, Ben Cohen via swift-evolution 
>  wrote:
>> 
>> As we expand (and maybe contract :) the standard library, this kind of 
>> question comes up a lot, so it is worth setting out some criteria for 
>> judging these “helper” methods. Here’s my take on such a list (warning: 
>> objectivity and subjectivity blended together in the below).
> 
> This is great perspective Ben, thank you for taking time to write this up!
> 
> It seems that you are leaning towards removing enumerated().  What do you 
> think about the proposal of removing enumerated but adding indexed() to 
> replace it?  It would provide the same behavior for common array cases, while 
> providing more useful/defensible functionality for other collections.
> 
> -Chris

https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2 


This could easily be adapted to incorporate both the removal of enumerated as 
well as the addition of indexed, and I love the idea of using Ben's list as a 
template for the justification section, plus adding the feedback from this 
thread.

-- E


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


Re: [swift-evolution] Removing enumerated?

2017-02-02 Thread Chris Lattner via swift-evolution
On Jan 31, 2017, at 11:16 AM, Ben Cohen via swift-evolution 
 wrote:
> 
> As we expand (and maybe contract :) the standard library, this kind of 
> question comes up a lot, so it is worth setting out some criteria for judging 
> these “helper” methods. Here’s my take on such a list (warning: objectivity 
> and subjectivity blended together in the below).

This is great perspective Ben, thank you for taking time to write this up!

It seems that you are leaning towards removing enumerated().  What do you think 
about the proposal of removing enumerated but adding indexed() to replace it?  
It would provide the same behavior for common array cases, while providing more 
useful/defensible functionality for other collections.

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Jonathan Hull via swift-evolution

> On Jan 31, 2017, at 12:46 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
>> // apply alternating view background colors
>> for (i, view) in views.enumerated() {
>> view.backgroundColor = i % 2 ? bgColor1 : bgColor2
>> }
>> 
> 
> This is an interesting one because it highlights something else I think is 
> missing from the std lib: Sequence.cycle, which would make an infinite 
> sequence by repeating a sequence, enabling what I think is probably a 
> readability win in some cases:
> 
> let colors = [bgColor1, bgColor2].cycle
> for (color, view) in zip(colors, views) {
>   view.backgroundColor = color
> }

This is a common enough need for me that I have built a special class for it.  
Here is the code in case it is useful to others trying to do the same thing:
https://gist.github.com/jonhull/b9cd8a50abca16ea49eade2c91edf8a2

At it’s heart, it takes an array (or a single value) and turns it into an 
endless repeating collection.  It also has facilities for random output, and to 
compose with other sources, allowing complex repeating patterns from simple 
sources.  I originally made it for creating fill patterns in a drawing 
framework (e.g. stripes like your example above), but I have found it generally 
useful over time.

Thanks,
Jon___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 2:46 PM, Ben Cohen  wrote:
> 
>> 
>> On Jan 31, 2017, at 12:18 PM, Matthew Johnson > > wrote:
>> 
>>> 
>>> On Jan 31, 2017, at 1:16 PM, Ben Cohen via swift-evolution 
>>> > wrote:
>>> 
>>> I think whether enumerated() is justified as a method on Sequence is one 
>>> example of a wider question which definitely needs some discussion, which 
>>> is: where should the standard library draw the line in providing 
>>> convenience functions that can easily be composed from other functions in 
>>> the std lib? Here’s another example: 
>>> 
>>> SE-100 
>>> 
>>>  is a proposal to add an init to Dictionary from a sequence of key/value 
>>> pairs. It’s a commonly requested feature, and IMO much needed and should be 
>>> added as soon as we move to the appropriate phase in Swift’s evolution. 
>>> 
>>> Another commonly requested Dictionary feature is similar: add a 
>>> Dictionary.init that takes a sequence, and a closure that maps that 
>>> sequence to keys. This is useful, for example, when you have a sequence of 
>>> objects that you frequently need to index into via one property on those 
>>> objects, so you want to build a fast lookup cache using that property.
>>> 
>>> Now, if we implement SE-100, that second request can be easily composed. It 
>>> would be something like Dictionary(sequence.lazy.map { (key: 
>>> $0.someProperty, value: $0) } )
>>> 
>>> Some people look at that line of code and think sure, that’s what I’d do 
>>> and it’s easy enough that the second helper shouldn’t be added as it’s 
>>> superfluous. Others look at it and say that it is unreadable clever-code FP 
>>> nonsense, and we should just add the helper method because most programmers 
>>> wouldn’t be able to read or write that easily.
>>> 
>>> As we expand (and maybe contract :) the standard library, this kind of 
>>> question comes up a lot, so it is worth setting out some criteria for 
>>> judging these
>>> “helper” methods. Here’s my take on such a list (warning: objectivity and 
>>> subjectivity blended together in the below).
>> 
>> This is a great analysis and list of criteria.  Thanks for putting this 
>> together Ben!
>> 
>>> 
>>> 1. Is it truly a frequent operation?
>>> 
>>> The operation needs to carry its weight. Even once we have ABI stability, 
>>> so the size of the std lib becomes less of a concern as it could ship as 
>>> part of the OS, we still need to keep helper method growth under control. 
>>> APIs bristling with methods like an over-decorated Xmas tree are bad for 
>>> usability. As mentioned in the String manifesto, String+Foundation 
>>> currently has over 200 methods/properties. Helpers are no good if you can’t 
>>> find them to use them.
>>> 
>>> Someone mentioned that they actually don’t find themselves using 
>>> enumerated() all that often. I suspect enumerated in its current form isn’t 
>>> all that useful. In a quick (and non-scientific) review of search results 
>>> for its use on GitHub, nearly all the examples I see of it are either 1) 
>>> misuse – see more below, or 2) use of it to perform the equivalent of 
>>> in-place map where the index is used to subscript into the array and 
>>> replace it with a transformed element.
>>> 
>>> I think the std lib needs an in-place map, and if enumerated() is removed, 
>>> this one most-common use case should be added at the same time.
>> 
>> I just did a quick search in a couple of projects and found a handful of 
>> good examples of valid uses of `enumerated`.  I have simplified the examples 
>> from real world code, but I think they demonstrate the kinds of things this 
>> is good for.
>> 
>> // only show the first 5 views
>> for (i, view) in views.enumerated() {
>> view.hidden = i >= 5
>> }
>> 
> 
> Interesting that several of these rely on reference types as elements. This 
> does make the loops a lot simpler. In-place amendment of an array would be 
> messier, and the combination with zip definitely pushes back against my 
> notion that an in-place map would be a useful alternative (since you couldn’t 
> mutate the mutable half of the zipped collection in-place without us jumping 
> through some hoops).
> 
> 
>> // apply alternating view background colors
>> for (i, view) in views.enumerated() {
>> view.backgroundColor = i % 2 ? bgColor1 : bgColor2
>> }
>> 
> 
> This is an interesting one because it highlights something else I think is 
> missing from the std lib: Sequence.cycle, which would make an infinite 
> sequence by repeating a sequence, enabling what I think is probably a 
> readability win in some cases:
> 
> let colors = [bgColor1, bgColor2].cycle
> for (color, view) in zip(colors, views) {
>   view.backgroundColor = color
> }
> 
> Also i%2 used as a boolean – 

Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ben Cohen via swift-evolution

> On Jan 31, 2017, at 12:18 PM, Matthew Johnson  wrote:
> 
>> 
>> On Jan 31, 2017, at 1:16 PM, Ben Cohen via swift-evolution 
>> > wrote:
>> 
>> I think whether enumerated() is justified as a method on Sequence is one 
>> example of a wider question which definitely needs some discussion, which 
>> is: where should the standard library draw the line in providing convenience 
>> functions that can easily be composed from other functions in the std lib? 
>> Here’s another example: 
>> 
>> SE-100 
>> 
>>  is a proposal to add an init to Dictionary from a sequence of key/value 
>> pairs. It’s a commonly requested feature, and IMO much needed and should be 
>> added as soon as we move to the appropriate phase in Swift’s evolution. 
>> 
>> Another commonly requested Dictionary feature is similar: add a 
>> Dictionary.init that takes a sequence, and a closure that maps that sequence 
>> to keys. This is useful, for example, when you have a sequence of objects 
>> that you frequently need to index into via one property on those objects, so 
>> you want to build a fast lookup cache using that property.
>> 
>> Now, if we implement SE-100, that second request can be easily composed. It 
>> would be something like Dictionary(sequence.lazy.map { (key: 
>> $0.someProperty, value: $0) } )
>> 
>> Some people look at that line of code and think sure, that’s what I’d do and 
>> it’s easy enough that the second helper shouldn’t be added as it’s 
>> superfluous. Others look at it and say that it is unreadable clever-code FP 
>> nonsense, and we should just add the helper method because most programmers 
>> wouldn’t be able to read or write that easily.
>> 
>> As we expand (and maybe contract :) the standard library, this kind of 
>> question comes up a lot, so it is worth setting out some criteria for 
>> judging these
>> “helper” methods. Here’s my take on such a list (warning: objectivity and 
>> subjectivity blended together in the below).
> 
> This is a great analysis and list of criteria.  Thanks for putting this 
> together Ben!
> 
>> 
>> 1. Is it truly a frequent operation?
>> 
>> The operation needs to carry its weight. Even once we have ABI stability, so 
>> the size of the std lib becomes less of a concern as it could ship as part 
>> of the OS, we still need to keep helper method growth under control. APIs 
>> bristling with methods like an over-decorated Xmas tree are bad for 
>> usability. As mentioned in the String manifesto, String+Foundation currently 
>> has over 200 methods/properties. Helpers are no good if you can’t find them 
>> to use them.
>> 
>> Someone mentioned that they actually don’t find themselves using 
>> enumerated() all that often. I suspect enumerated in its current form isn’t 
>> all that useful. In a quick (and non-scientific) review of search results 
>> for its use on GitHub, nearly all the examples I see of it are either 1) 
>> misuse – see more below, or 2) use of it to perform the equivalent of 
>> in-place map where the index is used to subscript into the array and replace 
>> it with a transformed element.
>> 
>> I think the std lib needs an in-place map, and if enumerated() is removed, 
>> this one most-common use case should be added at the same time.
> 
> I just did a quick search in a couple of projects and found a handful of good 
> examples of valid uses of `enumerated`.  I have simplified the examples from 
> real world code, but I think they demonstrate the kinds of things this is 
> good for.
> 
> // only show the first 5 views
> for (i, view) in views.enumerated() {
> view.hidden = i >= 5
> }
> 

Interesting that several of these rely on reference types as elements. This 
does make the loops a lot simpler. In-place amendment of an array would be 
messier, and the combination with zip definitely pushes back against my notion 
that an in-place map would be a useful alternative (since you couldn’t mutate 
the mutable half of the zipped collection in-place without us jumping through 
some hoops).


> // apply alternating view background colors
> for (i, view) in views.enumerated() {
> view.backgroundColor = i % 2 ? bgColor1 : bgColor2
> }
> 

This is an interesting one because it highlights something else I think is 
missing from the std lib: Sequence.cycle, which would make an infinite sequence 
by repeating a sequence, enabling what I think is probably a readability win in 
some cases:

let colors = [bgColor1, bgColor2].cycle
for (color, view) in zip(colors, views) {
view.backgroundColor = color
}

Also i%2 used as a boolean – what language is this? :)

> // linear layout
> for (i, view) in views.enumerated() {
>let x = width * CGFloat(i)
>view.frame = CGRect(x: x, y: 0, width: width, height: height)
> }
> 
> // deriving locations for an equally 

Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 1:16 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
> I think whether enumerated() is justified as a method on Sequence is one 
> example of a wider question which definitely needs some discussion, which is: 
> where should the standard library draw the line in providing convenience 
> functions that can easily be composed from other functions in the std lib? 
> Here’s another example: 
> 
> SE-100 
> 
>  is a proposal to add an init to Dictionary from a sequence of key/value 
> pairs. It’s a commonly requested feature, and IMO much needed and should be 
> added as soon as we move to the appropriate phase in Swift’s evolution. 
> 
> Another commonly requested Dictionary feature is similar: add a 
> Dictionary.init that takes a sequence, and a closure that maps that sequence 
> to keys. This is useful, for example, when you have a sequence of objects 
> that you frequently need to index into via one property on those objects, so 
> you want to build a fast lookup cache using that property.
> 
> Now, if we implement SE-100, that second request can be easily composed. It 
> would be something like Dictionary(sequence.lazy.map { (key: $0.someProperty, 
> value: $0) } )
> 
> Some people look at that line of code and think sure, that’s what I’d do and 
> it’s easy enough that the second helper shouldn’t be added as it’s 
> superfluous. Others look at it and say that it is unreadable clever-code FP 
> nonsense, and we should just add the helper method because most programmers 
> wouldn’t be able to read or write that easily.
> 
> As we expand (and maybe contract :) the standard library, this kind of 
> question comes up a lot, so it is worth setting out some criteria for judging 
> these
> “helper” methods. Here’s my take on such a list (warning: objectivity and 
> subjectivity blended together in the below).

This is a great analysis and list of criteria.  Thanks for putting this 
together Ben!

> 
> 1. Is it truly a frequent operation?
> 
> The operation needs to carry its weight. Even once we have ABI stability, so 
> the size of the std lib becomes less of a concern as it could ship as part of 
> the OS, we still need to keep helper method growth under control. APIs 
> bristling with methods like an over-decorated Xmas tree are bad for 
> usability. As mentioned in the String manifesto, String+Foundation currently 
> has over 200 methods/properties. Helpers are no good if you can’t find them 
> to use them.
> 
> Someone mentioned that they actually don’t find themselves using enumerated() 
> all that often. I suspect enumerated in its current form isn’t all that 
> useful. In a quick (and non-scientific) review of search results for its use 
> on GitHub, nearly all the examples I see of it are either 1) misuse – see 
> more below, or 2) use of it to perform the equivalent of in-place map where 
> the index is used to subscript into the array and replace it with a 
> transformed element.
> 
> I think the std lib needs an in-place map, and if enumerated() is removed, 
> this one most-common use case should be added at the same time.

I just did a quick search in a couple of projects and found a handful of good 
examples of valid uses of `enumerated`.  I have simplified the examples from 
real world code, but I think they demonstrate the kinds of things this is good 
for.

// only show the first 5 views
for (i, view) in views.enumerated() {
view.hidden = i >= 5
}

// apply alternating view background colors
for (i, view) in views.enumerated() {
view.backgroundColor = i % 2 ? bgColor1 : bgColor2
}

// linear layout
for (i, view) in views.enumerated() {
   let x = width * CGFloat(i)
   view.frame = CGRect(x: x, y: 0, width: width, height: height)
}

// deriving locations for an equally spaced gradient
let locations = colors.enumerated.map { CGFloat($0.0) / CGFloat(colors.count - 
1) }

There are other ways to accomplish similar things (use `prefix` and `dropFirst` 
comes to mind), but many reasonable people would argue that using `enumerated` 
is a very straightforward way to do a lot of things.

> 
> 2. Is the helper more readable? Is the composed equivalent obvious at a 
> glance?
> 
> When an operation is very common, the big win with a helper method is it 
> creates a readable vocabulary. If enumerated() is very common, and everyone 
> sees it everywhere, it makes that code easier to read at a glance.
> 
> That said, I think that the alternative – zip(0…, sequence) – is just as 
> readable once you are familiar with zip and ranges, two concepts that, IMO at 
> least, it is important that every Swift programmer learn about early on. I 
> would even go so far as to say that enumerated is harmful if it discourages 
> new users from discovering zip.

This is a very good point.  Requiring programmers to zip with a range could 
help them 

Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ben Cohen via swift-evolution
I think whether enumerated() is justified as a method on Sequence is one 
example of a wider question which definitely needs some discussion, which is: 
where should the standard library draw the line in providing convenience 
functions that can easily be composed from other functions in the std lib? 
Here’s another example: 

SE-100 

 is a proposal to add an init to Dictionary from a sequence of key/value pairs. 
It’s a commonly requested feature, and IMO much needed and should be added as 
soon as we move to the appropriate phase in Swift’s evolution. 

Another commonly requested Dictionary feature is similar: add a Dictionary.init 
that takes a sequence, and a closure that maps that sequence to keys. This is 
useful, for example, when you have a sequence of objects that you frequently 
need to index into via one property on those objects, so you want to build a 
fast lookup cache using that property.

Now, if we implement SE-100, that second request can be easily composed. It 
would be something like Dictionary(sequence.lazy.map { (key: $0.someProperty, 
value: $0) } )

Some people look at that line of code and think sure, that’s what I’d do and 
it’s easy enough that the second helper shouldn’t be added as it’s superfluous. 
Others look at it and say that it is unreadable clever-code FP nonsense, and we 
should just add the helper method because most programmers wouldn’t be able to 
read or write that easily.

As we expand (and maybe contract :) the standard library, this kind of question 
comes up a lot, so it is worth setting out some criteria for judging these 
“helper” methods. Here’s my take on such a list (warning: objectivity and 
subjectivity blended together in the below).

1. Is it truly a frequent operation?

The operation needs to carry its weight. Even once we have ABI stability, so 
the size of the std lib becomes less of a concern as it could ship as part of 
the OS, we still need to keep helper method growth under control. APIs 
bristling with methods like an over-decorated Xmas tree are bad for usability. 
As mentioned in the String manifesto, String+Foundation currently has over 200 
methods/properties. Helpers are no good if you can’t find them to use them.

Someone mentioned that they actually don’t find themselves using enumerated() 
all that often. I suspect enumerated in its current form isn’t all that useful. 
In a quick (and non-scientific) review of search results for its use on GitHub, 
nearly all the examples I see of it are either 1) misuse – see more below, or 
2) use of it to perform the equivalent of in-place map where the index is used 
to subscript into the array and replace it with a transformed element.

I think the std lib needs an in-place map, and if enumerated() is removed, this 
one most-common use case should be added at the same time.

2. Is the helper more readable? Is the composed equivalent obvious at a glance?

When an operation is very common, the big win with a helper method is it 
creates a readable vocabulary. If enumerated() is very common, and everyone 
sees it everywhere, it makes that code easier to read at a glance.

That said, I think that the alternative – zip(0…, sequence) – is just as 
readable once you are familiar with zip and ranges, two concepts that, IMO at 
least, it is important that every Swift programmer learn about early on. I 
would even go so far as to say that enumerated is harmful if it discourages new 
users from discovering zip.

OTOH, an example that I think is strongly justified on readability grounds is 
Sequence.all(match:), a function that checks that every element in a sequence 
matches a predicate. This is by far the most common extension for Sequence on 
GitHub. Yes, you can write this as !seq.contains(!predicate) but that far less 
readable – especially since it requires you write it with a closure that !’s 
the predicate i.e. !seq.contains { !predicate($0) }, because we don’t have a ! 
for composing with predicate functions (though maybe we should).

3. Does the helper have the flexibility to cover all common cases?

This, I think, is where enumerated() really starts to fall down.

Sometimes you want to start from not-zero, so maybe it should be 
Sequence.enumerated(startingFrom: Int = 0)
Sometimes you want non-integer indices so maybe we should add indexed().
Sometimes you want it the other way around (not for a for loop but for passing 
the elements directly into a mapping function) so now you need a flip.
Sometimes you want to enumeration to run backwards in some way.

Less of a problem if you’re already accustomed to composing your enumeration:

Enumerate starting from 1: zip(1…, c)
Enumerate indices: zip(c.indices, c)
Need the pair to be the other way around: zip(c, 0…)
Need the enumeration to run the other way: zip((0..

Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Jacob Bandes-Storch via swift-evolution
I'm still a fan of that indexed() proposal...
On Tue, Jan 31, 2017 at 8:52 AM Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 31, 2017, at 10:46 AM, Chris Eidhof  wrote:
>
> I agree that it's very useful. I use it regularly. The documentation isn't
> that unclear, imo. To me, the underlying problem isn't enumerated. I think
> the underlying cause is that collections aren't indexed with zero based
> indices.if you don't understand this (which is the case for many
> experienced programmers new to Swift) it's hard to understand, and (too)
> easy to make a mistake.
>
>
> This indicates that the underlying problem is *not* enumerated at all.
> The underlying problem is that Swift is still a relatively new language and
> it does some things differently than other languages (for very good
> reasons).
>
> You’re making a great case for the need to continue spreading knowledge
> about Swift’s collection model through the community.
>
> I don’t think it’s problematic for an experienced programmer who is new to
> the language to bump up against this when the reach for `enumerated`.
> They’re going to need to learn the collection model sooner or later.
>
>
> On Tue, 31 Jan 2017 at 17:41, Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I totally sympathize with users being confused. It's an interesting idea
> to move it to Array only.
>
> The thing is, it does make sense (and wouldn't be confusing) to enumerate
> a dictionary or set. Moreover, the behavior is _exactly_ what it says on
> the tin: when you enumerate something in real life, there is no sense in
> which the number is related to some sort of index. Can we fix this by
> documentation? Like, a big blaring "don't use this when you want the index”?
>
>
> +1.  A similar method on collection that provides indices might be useful
> but that doesn’t mean we should remove `enumerated`.  User confusion should
> be addressed by documentation.
>
> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`
> collections
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
>
> ___
> 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
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> --
> Sent from my phone
>
> ___
> 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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 10:46 AM, Chris Eidhof  wrote:
> 
> I agree that it's very useful. I use it regularly. The documentation isn't 
> that unclear, imo. To me, the underlying problem isn't enumerated. I think 
> the underlying cause is that collections aren't indexed with zero based 
> indices.if you don't understand this (which is the case for many experienced 
> programmers new to Swift) it's hard to understand, and (too) easy to make a 
> mistake.

This indicates that the underlying problem is *not* enumerated at all.  The 
underlying problem is that Swift is still a relatively new language and it does 
some things differently than other languages (for very good reasons).

You’re making a great case for the need to continue spreading knowledge about 
Swift’s collection model through the community.

I don’t think it’s problematic for an experienced programmer who is new to the 
language to bump up against this when the reach for `enumerated`.  They’re 
going to need to learn the collection model sooner or later.  

> 
> On Tue, 31 Jan 2017 at 17:41, Matthew Johnson via swift-evolution 
> > wrote:
>> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> I totally sympathize with users being confused. It's an interesting idea to 
>> move it to Array only.
>> 
>> The thing is, it does make sense (and wouldn't be confusing) to enumerate a 
>> dictionary or set. Moreover, the behavior is _exactly_ what it says on the 
>> tin: when you enumerate something in real life, there is no sense in which 
>> the number is related to some sort of index. Can we fix this by 
>> documentation? Like, a big blaring "don't use this when you want the index”?
> 
> +1.  A similar method on collection that provides indices might be useful but 
> that doesn’t mean we should remove `enumerated`.  User confusion should be 
> addressed by documentation.
> 
>> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution 
>> > wrote:
>> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
>> > Here are three previous discussion about this topic:
>> >
>> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
>> > CollectionType
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
>> >  
>> > 
>> > and
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
>> >  
>> > 
>> >
>> >
>> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
>> >  
>> > 
>> >
>> >
>> > 3) September 2016: [Proposal draft] Introducing `indexed()`collections
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>> >  
>> > 
>> 
>> To clarify, the discussions I linked to don't all propose to remove or
>> replace `enumerated()`, but they all talk about the potential confusion
>> about what `enumerated()` does and does not do.
>> 
>> ___
>> 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 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> -- 
> Sent from my phone

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Chris Eidhof via swift-evolution
I agree that it's very useful. I use it regularly. The documentation isn't
that unclear, imo. To me, the underlying problem isn't enumerated. I think
the underlying cause is that collections aren't indexed with zero based
indices.if you don't understand this (which is the case for many
experienced programmers new to Swift) it's hard to understand, and (too)
easy to make a mistake.

On Tue, 31 Jan 2017 at 17:41, Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I totally sympathize with users being confused. It's an interesting idea
> to move it to Array only.
>
> The thing is, it does make sense (and wouldn't be confusing) to enumerate
> a dictionary or set. Moreover, the behavior is _exactly_ what it says on
> the tin: when you enumerate something in real life, there is no sense in
> which the number is related to some sort of index. Can we fix this by
> documentation? Like, a big blaring "don't use this when you want the index”?
>
>
> +1.  A similar method on collection that provides indices might be useful
> but that doesn’t mean we should remove `enumerated`.  User confusion should
> be addressed by documentation.
>
> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`
> collections
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
>
> ___
> 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
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-- 
Sent from my phone
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Sean Heber via swift-evolution
In practical usage, I rarely use enumerated() - and almost every time I do use 
it, I end up refactoring 20 minutes later to not use it. Maybe that's just me, 
though. I imagine this isn’t helpful feedback. :P But perhaps we (or I) need to 
understand what it’s being used for or if there’s a different way to think 
about it.

l8r
Sean


> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I totally sympathize with users being confused. It's an interesting idea to 
> move it to Array only.
> 
> The thing is, it does make sense (and wouldn't be confusing) to enumerate a 
> dictionary or set. Moreover, the behavior is _exactly_ what it says on the 
> tin: when you enumerate something in real life, there is no sense in which 
> the number is related to some sort of index. Can we fix this by 
> documentation? Like, a big blaring "don't use this when you want the index"?
> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution 
>  wrote:
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`collections
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
> 
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
> 
> ___
> 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

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Xiaodi Wu via swift-evolution
I totally sympathize with users being confused. It's an interesting idea to
move it to Array only.

The thing is, it does make sense (and wouldn't be confusing) to enumerate a
dictionary or set. Moreover, the behavior is _exactly_ what it says on the
tin: when you enumerate something in real life, there is no sense in which
the number is related to some sort of index. Can we fix this by
documentation? Like, a big blaring "don't use this when you want the index"?
On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution <
swift-evolution@swift.org> wrote:

> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`
> collections
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
>
> ___
> 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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I totally sympathize with users being confused. It's an interesting idea to 
> move it to Array only.
> 
> The thing is, it does make sense (and wouldn't be confusing) to enumerate a 
> dictionary or set. Moreover, the behavior is _exactly_ what it says on the 
> tin: when you enumerate something in real life, there is no sense in which 
> the number is related to some sort of index. Can we fix this by 
> documentation? Like, a big blaring "don't use this when you want the index”?

+1.  A similar method on collection that provides indices might be useful but 
that doesn’t mean we should remove `enumerated`.  User confusion should be 
addressed by documentation.

> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution 
> > wrote:
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> >  
> > 
> > and
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >  
> > 
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >  
> > 
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`collections
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
> >  
> > 
> 
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
> 
> ___
> 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

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ole Begemann via swift-evolution

On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:

Here are three previous discussion about this topic:

1) December 2015: [Idea] Add an (Index,Element) sequence to
CollectionType
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
and
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html


2) April 2016: [Idea] Replace enumerate() with something more explicit
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html


3) September 2016: [Proposal draft] Introducing `indexed()`collections
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html


To clarify, the discussions I linked to don't all propose to remove or 
replace `enumerated()`, but they all talk about the potential confusion 
about what `enumerated()` does and does not do.


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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ole Begemann via swift-evolution

On 31/01/2017 15:24, Chris Eidhof via swift-evolution wrote:

There are a couple of things that keep coming up, and a couple of
mistakes that I see people making over and over again. One of them is
that in almost every workshop, there's someone who thinks that
`enumerated()` returns a list of (index, element) pairs. This is only
true for arrays. It breaks when using array slices, or any other kind of
collection. In our workshops, I sometimes see people doing something
like `x.reversed().enumerated()`, where `x` is an array, and somehow it
produces behavior they don't understand.

A few ways I think this could be improved:

- Move enumerated to Array
- Change enumerated to return `(Index, Iterator.Element)` (this would
mean we at least need to move it to collection)
- Remove enumerated
- Keep things as is


Here are three previous discussion about this topic:

1) December 2015: [Idea] Add an (Index, Element) sequence to CollectionType
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html 
and 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html


2) April 2016: [Idea] Replace enumerate() with something more explicit
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html

3) September 2016: [Proposal draft] Introducing `indexed()` collections
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Charlie Monroe via swift-evolution

> On Jan 31, 2017, at 3:24 PM, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Hey everyone,
> 
> I've organized a number of Swift workshops over the last two years. There are 
> a couple of things that keep coming up, and a couple of mistakes that I see 
> people making over and over again. One of them is that in almost every 
> workshop, there's someone who thinks that `enumerated()` returns a list of 
> (index, element) pairs. This is only true for arrays. It breaks when using 
> array slices, or any other kind of collection. In our workshops, I sometimes 
> see people doing something like `x.reversed().enumerated()`, where `x` is an 
> array, and somehow it produces behavior they don't understand.

What is the behavior that you'd like?

for x in [1, 2, 3].reversed().enumerated() {
print(x)
}

produces (first column is the index, second the element):

(0, 3)
(1, 2)
(2, 1)

- it IMHO behaves as one would expect - it returns an index into the sequence 
that you are enumerating...

> 
> A few ways I think this could be improved:
> 
> - Move enumerated to Array
> - Change enumerated to return `(Index, Iterator.Element)` (this would mean we 
> at least need to move it to collection)
> - Remove enumerated
> - Keep things as is
> 
> In any case, just wanted to share my experience (gained from teaching 
> people). 
> 
> -- 
> Chris Eidhof
> ___
> 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


[swift-evolution] Removing enumerated?

2017-01-31 Thread Chris Eidhof via swift-evolution
Hey everyone,

I've organized a number of Swift workshops over the last two years. There
are a couple of things that keep coming up, and a couple of mistakes that I
see people making over and over again. One of them is that in almost every
workshop, there's someone who thinks that `enumerated()` returns a list of
(index, element) pairs. This is only true for arrays. It breaks when using
array slices, or any other kind of collection. In our workshops, I
sometimes see people doing something like `x.reversed().enumerated()`,
where `x` is an array, and somehow it produces behavior they don't
understand.

A few ways I think this could be improved:

- Move enumerated to Array
- Change enumerated to return `(Index, Iterator.Element)` (this would mean
we at least need to move it to collection)
- Remove enumerated
- Keep things as is

In any case, just wanted to share my experience (gained from teaching
people).

-- 
Chris Eidhof
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution