Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-11 Thread Guillaume Lessard via swift-evolution

> On Apr 10, 2017, at 13:30, Kevin Nattinger via swift-evolution 
>  wrote:
> 
> array.remove(where: { $0 > 3 })
> array.remove { $0 > 3 }

`where` is the best label for this.

`filter` doesn’t have an overload for Comparable, this doesn’t need one either.

Cheers,
Guillaume Lessard

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


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-10 Thread Kevin Nattinger via swift-evolution
array.remove(where: { $0 > 3 })
array.remove { $0 > 3 }

> On Apr 10, 2017, at 12:25 PM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
> On 10 Apr 2017, at 17:17, Maximilian Hünenberger via swift-evolution 
> > wrote:
> 
>> How about this:
>> 
>> array.removeEvery(3)
>> array.removeEvery{ $0 > 3 }
>> 
>> I think it preserves the meaning while it reads nicely. However "every" has 
>> no precedent in other functions, as far as I know.
> 
> Every has a very ambiguous meaning in English. It could be understood as 
> "every 3 values" as in 0, 3, 6, 9, etc...
> 
>> Am 10.04.2017 um 04:32 schrieb Ben Cohen via swift-evolution 
>> >:
>> 
>>> 
 On Apr 8, 2017, at 5:41 PM, Brent Royal-Gordon > wrote:
 
> On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
> > wrote:
> 
> +1. Perfect. Let's not bikeshed this and get it done!
 
 
 Sorry, I'm going to have to insist on bikeshedding.
 
 `equalTo:` is kind of ugly and has no precedent in the standard library. 
 Similar APIs seem to either leave the parameter unlabeled or use `of:` (as 
 in `index(of:)`). I think unlabeled is probably the right answer here.
 
>>> 
>>> I think removeAll(of:) works well for the equatable value version.
>>> 
>>> FWIW of all the ideas from the all thread, containsOnly(_:) for the 
>>> equatable value version works for me. It has a nice symmetry: contains(3) 
>>> vs containsOnly(3).
>>> 
 The main shortcoming I can see is that if you see:
 
array.removeAll(3)
 
>>> 
>>> Personally don’t feel good about an unlabelled version. It doesn’t read 
>>> right. Remove all three what?
>>> 
 You might think `3` is either an index or a count. But neither of those 
 actually make sense:
 
 * It can't be an index because then `All` would have no meaning. There's 
 only ever one thing at a given index. Besides, indices are almost always 
 marked with `at:` or another parameter label.
 * It can't be a count because `All` is already a count. What could "remove 
 all 3" possibly mean if the array doesn't happen to have three elements?
 
 And this is only a problem if the value happens to be an integer. If it's 
 anything else, the type makes clear that this can't possibly be an index 
 or count; it must be an element.
 
 (But if you really do think this is insurmountable, `removeAll(of: 3)` 
 *is* impossible to misinterpret and fits in better than 
 `removeAll(equalTo:)`.)
 
 (P.S. The existing oddness of `removeFirst(_:)` compared to 
 `removeFirst()` and `removeAll()` is why I proposed last year that it be 
 renamed to `removePrefix(_:)`, which matches the count-taking `prefix(_:)` 
 method.)
 
 -- 
 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 
>> 
> ___
> 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] [pitch] Adding in-place removeAll to the std lib

2017-04-10 Thread David Hart via swift-evolution


> On 10 Apr 2017, at 17:17, Maximilian Hünenberger via swift-evolution 
>  wrote:
> 
> How about this:
> 
> array.removeEvery(3)
> array.removeEvery{ $0 > 3 }
> 
> I think it preserves the meaning while it reads nicely. However "every" has 
> no precedent in other functions, as far as I know.

Every has a very ambiguous meaning in English. It could be understood as "every 
3 values" as in 0, 3, 6, 9, etc...

>> Am 10.04.2017 um 04:32 schrieb Ben Cohen via swift-evolution 
>> :
>> 
>> 
 On Apr 8, 2017, at 5:41 PM, Brent Royal-Gordon  
 wrote:
 
 On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
  wrote:
 
 +1. Perfect. Let's not bikeshed this and get it done!
>>> 
>>> 
>>> Sorry, I'm going to have to insist on bikeshedding.
>>> 
>>> `equalTo:` is kind of ugly and has no precedent in the standard library. 
>>> Similar APIs seem to either leave the parameter unlabeled or use `of:` (as 
>>> in `index(of:)`). I think unlabeled is probably the right answer here.
>>> 
>> 
>> I think removeAll(of:) works well for the equatable value version.
>> 
>> FWIW of all the ideas from the all thread, containsOnly(_:) for the 
>> equatable value version works for me. It has a nice symmetry: contains(3) vs 
>> containsOnly(3).
>> 
>>> The main shortcoming I can see is that if you see:
>>> 
>>> array.removeAll(3)
>>> 
>> 
>> Personally don’t feel good about an unlabelled version. It doesn’t read 
>> right. Remove all three what?
>> 
>>> You might think `3` is either an index or a count. But neither of those 
>>> actually make sense:
>>> 
>>> * It can't be an index because then `All` would have no meaning. There's 
>>> only ever one thing at a given index. Besides, indices are almost always 
>>> marked with `at:` or another parameter label.
>>> * It can't be a count because `All` is already a count. What could "remove 
>>> all 3" possibly mean if the array doesn't happen to have three elements?
>>> 
>>> And this is only a problem if the value happens to be an integer. If it's 
>>> anything else, the type makes clear that this can't possibly be an index or 
>>> count; it must be an element.
>>> 
>>> (But if you really do think this is insurmountable, `removeAll(of: 3)` *is* 
>>> impossible to misinterpret and fits in better than `removeAll(equalTo:)`.)
>>> 
>>> (P.S. The existing oddness of `removeFirst(_:)` compared to `removeFirst()` 
>>> and `removeAll()` is why I proposed last year that it be renamed to 
>>> `removePrefix(_:)`, which matches the count-taking `prefix(_:)` method.)
>>> 
>>> -- 
>>> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-10 Thread Maximilian Hünenberger via swift-evolution
How about this:

array.removeEvery(3)
array.removeEvery{ $0 > 3 }

I think it preserves the meaning while it reads nicely. However "every" has no 
precedent in other functions, as far as I know.

> Am 10.04.2017 um 04:32 schrieb Ben Cohen via swift-evolution 
> :
> 
> 
>>> On Apr 8, 2017, at 5:41 PM, Brent Royal-Gordon  
>>> wrote:
>>> 
>>> On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> +1. Perfect. Let's not bikeshed this and get it done!
>> 
>> 
>> Sorry, I'm going to have to insist on bikeshedding.
>> 
>> `equalTo:` is kind of ugly and has no precedent in the standard library. 
>> Similar APIs seem to either leave the parameter unlabeled or use `of:` (as 
>> in `index(of:)`). I think unlabeled is probably the right answer here.
>> 
> 
> I think removeAll(of:) works well for the equatable value version.
> 
> FWIW of all the ideas from the all thread, containsOnly(_:) for the equatable 
> value version works for me. It has a nice symmetry: contains(3) vs 
> containsOnly(3).
> 
>> The main shortcoming I can see is that if you see:
>> 
>>  array.removeAll(3)
>> 
> 
> Personally don’t feel good about an unlabelled version. It doesn’t read 
> right. Remove all three what?
> 
>> You might think `3` is either an index or a count. But neither of those 
>> actually make sense:
>> 
>> * It can't be an index because then `All` would have no meaning. There's 
>> only ever one thing at a given index. Besides, indices are almost always 
>> marked with `at:` or another parameter label.
>> * It can't be a count because `All` is already a count. What could "remove 
>> all 3" possibly mean if the array doesn't happen to have three elements?
>> 
>> And this is only a problem if the value happens to be an integer. If it's 
>> anything else, the type makes clear that this can't possibly be an index or 
>> count; it must be an element.
>> 
>> (But if you really do think this is insurmountable, `removeAll(of: 3)` *is* 
>> impossible to misinterpret and fits in better than `removeAll(equalTo:)`.)
>> 
>> (P.S. The existing oddness of `removeFirst(_:)` compared to `removeFirst()` 
>> and `removeAll()` is why I proposed last year that it be renamed to 
>> `removePrefix(_:)`, which matches the count-taking `prefix(_:)` method.)
>> 
>> -- 
>> 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


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-09 Thread David Hart via swift-evolution


> On 10 Apr 2017, at 04:46, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Well, if we're going to bikeshed:
> 
> I think removeAll(3) reads fine, while removeAll(of: 3) does not. I do not 
> think that reads right at all--what is "all of three"? Do we mean to contrast 
> it to "some of three"--like, maybe, two of three?
> 
> By comparison, index(of: 3) works because the element equal to three has a 
> corresponding index. However, neither the element equal to three, nor three 
> itself, has a corresponding "allness."
> 
> Put another way, "of" is not a preposition that can substitute for "equal 
> to." This becomes obvious if you consider that, while removeAll(equalTo:) 
> makes perfect sense, index(equalTo:) is not an appropriate alternative 
> (aesthetically pleasing or not) name for index(of:). If verbosity were not an 
> issue, the full names might be:
> 
> removeAllElements(equalTo:)
> index(ofFirstElementEqualTo:)
> 
> From these hypothetical forms (I'm not suggesting we rename!), one can see 
> how "of" does not really fit with the sense of "removeAll" proposed here.

Agree with Xiaodi on all the previous points. removeAll(equalTo:) is still the 
best version for me.

> Finally--if it's to be called "removeAll" and we want to use the word 
> "contains" for the equatable version, it would be more consistent to call it 
> "containsAll" and not "containsOnly".

Have to disagree here. containsAll(3) has the same readability problems as 
removeAll(3).

> On Sun, Apr 9, 2017 at 21:32 Ben Cohen  wrote:
 On Apr 8, 2017, at 5:41 PM, Brent Royal-Gordon  
 wrote:
 
 On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
  wrote:
 
 +1. Perfect. Let's not bikeshed this and get it done!
>>> 
>>> 
>>> Sorry, I'm going to have to insist on bikeshedding.
>>> 
>>> `equalTo:` is kind of ugly and has no precedent in the standard library. 
>>> Similar APIs seem to either leave the parameter unlabeled or use `of:` (as 
>>> in `index(of:)`). I think unlabeled is probably the right answer here.
>>> 
>> 
>> I think removeAll(of:) works well for the equatable value version.
>> 
>> FWIW of all the ideas from the all thread, containsOnly(_:) for the 
>> equatable value version works for me. It has a nice symmetry: contains(3) vs 
>> containsOnly(3).
>> 
>>> The main shortcoming I can see is that if you see:
>>> 
>>> array.removeAll(3)
>>> 
>> 
>> Personally don’t feel good about an unlabelled version. It doesn’t read 
>> right. Remove all three what?
>> 
>>> You might think `3` is either an index or a count. But neither of those 
>>> actually make sense:
>>> 
>>> * It can't be an index because then `All` would have no meaning. There's 
>>> only ever one thing at a given index. Besides, indices are almost always 
>>> marked with `at:` or another parameter label.
>>> * It can't be a count because `All` is already a count. What could "remove 
>>> all 3" possibly mean if the array doesn't happen to have three elements?
>>> 
>>> And this is only a problem if the value happens to be an integer. If it's 
>>> anything else, the type makes clear that this can't possibly be an index or 
>>> count; it must be an element.
>>> 
>>> (But if you really do think this is insurmountable, `removeAll(of: 3)` *is* 
>>> impossible to misinterpret and fits in better than `removeAll(equalTo:)`.)
>>> 
>>> (P.S. The existing oddness of `removeFirst(_:)` compared to `removeFirst()` 
>>> and `removeAll()` is why I proposed last year that it be renamed to 
>>> `removePrefix(_:)`, which matches the count-taking `prefix(_:)` method.)
>>> 
>>> -- 
>>> 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


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-09 Thread Xiaodi Wu via swift-evolution
Well, if we're going to bikeshed:

I think removeAll(3) reads fine, while removeAll(of: 3) does not. I do not
think that reads right at all--what is "all of three"? Do we mean to
contrast it to "some of three"--like, maybe, two of three?

By comparison, index(of: 3) works because the element equal to three has a
corresponding index. However, neither the element equal to three, nor three
itself, has a corresponding "allness."

Put another way, "of" is not a preposition that can substitute for "equal
to." This becomes obvious if you consider that, while removeAll(equalTo:)
makes perfect sense, index(equalTo:) is not an appropriate alternative
(aesthetically pleasing or not) name for index(of:). If verbosity were not
an issue, the full names might be:

removeAllElements(equalTo:)
index(ofFirstElementEqualTo:)

>From these hypothetical forms (I'm not suggesting we rename!), one can see
how "of" does not really fit with the sense of "removeAll" proposed here.

Finally--if it's to be called "removeAll" and we want to use the word
"contains" for the equatable version, it would be more consistent to call
it "containsAll" and not "containsOnly".
On Sun, Apr 9, 2017 at 21:32 Ben Cohen  wrote:

> On Apr 8, 2017, at 5:41 PM, Brent Royal-Gordon 
> wrote:
>
> On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> +1. Perfect. Let's not bikeshed this and get it done!
>
>
> Sorry, I'm going to have to insist on bikeshedding.
>
> `equalTo:` is kind of ugly and has no precedent in the standard library.
> Similar APIs seem to either leave the parameter unlabeled or use `of:` (as
> in `index(of:)`). I think unlabeled is probably the right answer here.
>
>
> I think removeAll(of:) works well for the equatable value version.
>
> FWIW of all the ideas from the all thread, containsOnly(_:) for the
> equatable value version works for me. It has a nice symmetry: contains(3)
> vs containsOnly(3).
>
> The main shortcoming I can see is that if you see:
>
> array.removeAll(3)
>
>
> Personally don’t feel good about an unlabelled version. It doesn’t read
> right. Remove all three what?
>
> You might think `3` is either an index or a count. But neither of those
> actually make sense:
>
> * It can't be an index because then `All` would have no meaning. There's
> only ever one thing at a given index. Besides, indices are almost always
> marked with `at:` or another parameter label.
> * It can't be a count because `All` is already a count. What could "remove
> all 3" possibly mean if the array doesn't happen to have three elements?
>
> And this is only a problem if the value happens to be an integer. If it's
> anything else, the type makes clear that this can't possibly be an index or
> count; it must be an element.
>
> (But if you really do think this is insurmountable, `removeAll(of: 3)`
> *is* impossible to misinterpret and fits in better than
> `removeAll(equalTo:)`.)
>
> (P.S. The existing oddness of `removeFirst(_:)` compared to
> `removeFirst()` and `removeAll()` is why I proposed last year that it be
> renamed to `removePrefix(_:)`, which matches the count-taking `prefix(_:)`
> method.)
>
> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-09 Thread David Sweeris via swift-evolution

> On Apr 8, 2017, at 12:03, Ben Cohen via swift-evolution 
>  wrote:
> 
> 
> 
> Hi swift-evolution,
> 
> Another short proposal related to the Collection algorithms theme, this time 
> for removing elements in-place from a collection.
> 
> Online copy here: 
> https://github.com/airspeedswift/swift-evolution/blob/1aac5593828941431d1805503865e7a2913d538b/proposals/-RemoveWhere.md

I don't think the `foo.removeAll(equalTo: 3)` is sufficiently better than 
`foo.removeAll { $0 == 3}` to justify the alternate spelling.

+1, regardless, though.

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


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-09 Thread Ben Cohen via swift-evolution

> On Apr 8, 2017, at 5:41 PM, Brent Royal-Gordon  wrote:
> 
>> On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> +1. Perfect. Let's not bikeshed this and get it done!
> 
> 
> Sorry, I'm going to have to insist on bikeshedding.
> 
> `equalTo:` is kind of ugly and has no precedent in the standard library. 
> Similar APIs seem to either leave the parameter unlabeled or use `of:` (as in 
> `index(of:)`). I think unlabeled is probably the right answer here.
> 

I think removeAll(of:) works well for the equatable value version.

FWIW of all the ideas from the all thread, containsOnly(_:) for the equatable 
value version works for me. It has a nice symmetry: contains(3) vs 
containsOnly(3).

> The main shortcoming I can see is that if you see:
> 
>   array.removeAll(3)
> 

Personally don’t feel good about an unlabelled version. It doesn’t read right. 
Remove all three what?

> You might think `3` is either an index or a count. But neither of those 
> actually make sense:
> 
> * It can't be an index because then `All` would have no meaning. There's only 
> ever one thing at a given index. Besides, indices are almost always marked 
> with `at:` or another parameter label.
> * It can't be a count because `All` is already a count. What could "remove 
> all 3" possibly mean if the array doesn't happen to have three elements?
> 
> And this is only a problem if the value happens to be an integer. If it's 
> anything else, the type makes clear that this can't possibly be an index or 
> count; it must be an element.
> 
> (But if you really do think this is insurmountable, `removeAll(of: 3)` *is* 
> impossible to misinterpret and fits in better than `removeAll(equalTo:)`.)
> 
> (P.S. The existing oddness of `removeFirst(_:)` compared to `removeFirst()` 
> and `removeAll()` is why I proposed last year that it be renamed to 
> `removePrefix(_:)`, which matches the count-taking `prefix(_:)` method.)
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-08 Thread Richard Wei via swift-evolution
+1. We better make sure `equalTo:` is consistent with the label in the 
`Sequence.all` proposal.

-Richard

> On Apr 8, 2017, at 19:41, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> +1. Perfect. Let's not bikeshed this and get it done!
> 
> 
> Sorry, I'm going to have to insist on bikeshedding.
> 
> `equalTo:` is kind of ugly and has no precedent in the standard library. 
> Similar APIs seem to either leave the parameter unlabeled or use `of:` (as in 
> `index(of:)`). I think unlabeled is probably the right answer here.
> 
> The main shortcoming I can see is that if you see:
> 
>   array.removeAll(3)
> 
> You might think `3` is either an index or a count. But neither of those 
> actually make sense:
> 
> * It can't be an index because then `All` would have no meaning. There's only 
> ever one thing at a given index. Besides, indices are almost always marked 
> with `at:` or another parameter label.
> * It can't be a count because `All` is already a count. What could "remove 
> all 3" possibly mean if the array doesn't happen to have three elements?
> 
> And this is only a problem if the value happens to be an integer. If it's 
> anything else, the type makes clear that this can't possibly be an index or 
> count; it must be an element.
> 
> (But if you really do think this is insurmountable, `removeAll(of: 3)` *is* 
> impossible to misinterpret and fits in better than `removeAll(equalTo:)`.)
> 
> (P.S. The existing oddness of `removeFirst(_:)` compared to `removeFirst()` 
> and `removeAll()` is why I proposed last year that it be renamed to 
> `removePrefix(_:)`, which matches the count-taking `prefix(_:)` method.)
> 
> --
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



signature.asc
Description: Message signed with OpenPGP
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-08 Thread Brent Royal-Gordon via swift-evolution
> On Apr 8, 2017, at 12:44 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> +1. Perfect. Let's not bikeshed this and get it done!


Sorry, I'm going to have to insist on bikeshedding.

`equalTo:` is kind of ugly and has no precedent in the standard library. 
Similar APIs seem to either leave the parameter unlabeled or use `of:` (as in 
`index(of:)`). I think unlabeled is probably the right answer here.

The main shortcoming I can see is that if you see:

array.removeAll(3)

You might think `3` is either an index or a count. But neither of those 
actually make sense:

* It can't be an index because then `All` would have no meaning. There's only 
ever one thing at a given index. Besides, indices are almost always marked with 
`at:` or another parameter label.
* It can't be a count because `All` is already a count. What could "remove all 
3" possibly mean if the array doesn't happen to have three elements?

And this is only a problem if the value happens to be an integer. If it's 
anything else, the type makes clear that this can't possibly be an index or 
count; it must be an element.

(But if you really do think this is insurmountable, `removeAll(of: 3)` *is* 
impossible to misinterpret and fits in better than `removeAll(equalTo:)`.)

(P.S. The existing oddness of `removeFirst(_:)` compared to `removeFirst()` and 
`removeAll()` is why I proposed last year that it be renamed to 
`removePrefix(_:)`, which matches the count-taking `prefix(_:)` method.)

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-08 Thread Xiaodi Wu via swift-evolution
+1. Perfect. Let's not bikeshed this and get it done!
On Sat, Apr 8, 2017 at 14:04 Ben Cohen via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> Hi swift-evolution,
>
> Another short proposal related to the Collection algorithms theme, this
> time for removing elements in-place from a collection.
>
> Online copy here:
> https://github.com/airspeedswift/swift-evolution/blob/1aac5593828941431d1805503865e7a2913d538b/proposals/-RemoveWhere.md
>
>
> Adding in-place removeAll to the Standard Library
>
>- Proposal: SE-
>- Authors: Ben Cohen 
>- Review Manager: TBD
>- Status: *Awaiting review*
>
> Introduction
>
> It is common to want to remove all occurrences of a certain element from a
> collection. This proposal is to add two in-place remove algorithms to the
> standard library, which will remove all entries in a collection in-place
> matching either an Equatable value, or match that a certain criteria.
> Motivation
>
> Removing all elements matching some criteria is a very common operation.
> However, it can be tricky to implement correctly and efficiently.
>
> The easiest way to achieve this effect in Swift 3 is to use filter and
> assign back, negating the thing you want to remove (because filter takes
> a closure of items to “keep”):
>
> var nums = [1,2,3,4,5]// remove odd elements
> nums = nums.filter { !isOdd($0) }
>
> In addition to readability concerns, this has two performance problems:
> fresh memory allocation, and a copy of all the elements in full even if
> none need to be removed.
>
> The alternative is to open-code a for loop. The simplest performant
> solution is the “shuffle-down” approach. While not especially complex, it
> is certainly non-trivial:
>
> if var i = nums.index(where: isOdd) {
>   var j = i + 1
>   while j != nums.endIndex {
> let e = nums[j]
> if !isOdd(nums[j]) {
>   nums[i] = nums[j]
>   i += 1
> }
> j += 1
>   }
>   nums.removeSubrange(i.. }
>
> Possibilities for logic and performance errors abound. There are probably
> some in the above code.
>
> Additionally, this approach does not work for range-replaceable
> collections that are *not* mutable i.e. collections that can replace
> subranges, but can’t guarantee replacing a single element in constant time.
> String is the most important example of this, because its elements
> (graphemes) are variable width.
> Proposed solution
>
> Add the following methods to RangeReplaceableCollection:
>
> nums.removeAll(equalTo: 9)
> nums.removeAll(where: isOdd)
>
> The default implementation will use the protocol’s init() and append(_:) 
> operations
> to implement a copy-based version. Collections which also conform to
> MutableCollection will get the more efficient “shuffle-down”
> implementation, but still require RangeReplaceableCollection as well
> because of the need to trim at the end.
>
> Collections which are range replaceable but *not* mutable (like String)
> will be able to implement their own version which makes use of their
> internal layout. Collections like Array may also implement more efficient
> versions using memory copying operations.
>
> Since Dictionary and Set would benefit from this functionality as well,
> but are not range-replaceable, they should be given concrete
> implementations for consistency.
> Detailed design
>
> Add the following to RangeReplaceableCollection:
>
> protocol RangeReplaceableCollection {
>   /// Removes every element satisfying the given predicate from the 
> collection.
>   mutating func removeAll(where: (Iterator.Element) throws -> Bool) rethrows
> }
> extension RangeReplaceableCollection where Iterator.Element: Equatable {
>   /// Removes every element equal to the given element from the collection.
>   mutating func removeAll(equalTo element: Iterator.Element)
> }
>
> Source compatibility
>
> This change is purely additive so has no source compatibility consequences.
> Effect on ABI stability
>
> This change is purely additive so has no ABI stability consequences.
> Effect on API resilience
>
> This change is purely additive so has no API resilience consequences.
> Alternatives considered
>
> Regarding the name: remove instead of removeAll was considered. 
> removeAll(equalTo:
> 5) seems clearer when seen alongside similar methods removeFirst(5) and 
> remove(at:
> 5). In the case of remove(where:), the All in the basename is preserved
> for trailing closures.
> removeAll(where:) takes a closure with true for elements to remove. filter 
> takes
> a closure with elements to keep. In both cases, true is the “active”
> case, so likely to be what the user wants without having to apply a
> negation. The naming of filter is unfortunately ambiguous as to whether
> it’s a removing or keeping operation, but re-considering that is outside
> the scope of this proposal.
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> 

[swift-evolution] [pitch] Adding in-place removeAll to the std lib

2017-04-08 Thread Ben Cohen via swift-evolution


Hi swift-evolution,

Another short proposal related to the Collection algorithms theme, this time 
for removing elements in-place from a collection.

Online copy here: 
https://github.com/airspeedswift/swift-evolution/blob/1aac5593828941431d1805503865e7a2913d538b/proposals/-RemoveWhere.md


Adding in-place removeAll to the Standard Library

Proposal: SE- 

Authors: Ben Cohen 
Review Manager: TBD
Status: Awaiting review
Introduction

It is common to want to remove all occurrences of a certain element from a 
collection. This proposal is to add two in-place remove algorithms to the 
standard library, which will remove all entries in a collection in-place 
matching either an Equatable value, or match that a certain criteria.

Motivation

Removing all elements matching some criteria is a very common operation. 
However, it can be tricky to implement correctly and efficiently.

The easiest way to achieve this effect in Swift 3 is to use filter and assign 
back, negating the thing you want to remove (because filter takes a closure of 
items to “keep”):

var nums = [1,2,3,4,5]
// remove odd elements
nums = nums.filter { !isOdd($0) }
In addition to readability concerns, this has two performance problems: fresh 
memory allocation, and a copy of all the elements in full even if none need to 
be removed.

The alternative is to open-code a for loop. The simplest performant solution is 
the “shuffle-down” approach. While not especially complex, it is certainly 
non-trivial:

if var i = nums.index(where: isOdd) {
  var j = i + 1
  while j != nums.endIndex {
let e = nums[j]
if !isOdd(nums[j]) {
  nums[i] = nums[j]
  i += 1
}
j += 1
  }
  nums.removeSubrange(i.. Bool) rethrows
}

extension RangeReplaceableCollection where Iterator.Element: Equatable {
  /// Removes every element equal to the given element from the collection.
  mutating func removeAll(equalTo element: Iterator.Element)
}
Source compatibility

This change is purely additive so has no source compatibility consequences.

Effect on ABI stability

This change is purely additive so has no ABI stability consequences.

Effect on API resilience

This change is purely additive so has no API resilience consequences.

Alternatives considered

Regarding the name: remove instead of removeAll was considered. 
removeAll(equalTo: 5) seems clearer when seen alongside similar methods 
removeFirst(5) and remove(at: 5). In the case of remove(where:), the All in the 
basename is preserved for trailing closures.

removeAll(where:) takes a closure with true for elements to remove. filter 
takes a closure with elements to keep. In both cases, true is the “active” 
case, so likely to be what the user wants without having to apply a negation. 
The naming of filter is unfortunately ambiguous as to whether it’s a removing 
or keeping operation, but re-considering that is outside the scope of this 
proposal.



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