Re-pitch: remove(where:)

Hi everyone,

Reviving a pitch for a feature that didn’t make it into Swift 4. This was discussed in the core team recently, and feedback was wanted regarding the naming of the method and the polarity of the where closure.

Here’s the proposal:

https://github.com/airspeedswift/swift-evolution/blob/0f4a24d6ded2ab7cb39c1a68e0f92705a7615d73/proposals/NNNN-RemoveWhere.md

To keep things simple, this version removes the Equatable version. That could be added as a separate proposal.

The issue to resolve is: should the closure have the same polarity as filter, and if not, should filter also have an in-place equivalent?
(wait, don’t reply yet, read the rest of the email first :slight_smile:

From the original proposal:

`remove(where:)` takes a closure with `true` for elements to remove. `filter` takes a closure with `true` for 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.

Assuming you accept the premise that a closure returning `true` to `remove` is the “right way around” for the argument to an in-place removal operation, this means that we have a situation where if you want to flip from in-place to out-of-place removal, you have to reverse the closure.

Alternatively, we could duplicate the functionality, and have both filter and remove operations have in- and out-of-place variants, completing this 2x2 matrix:

out-of-place, true to keep: filter(_:slight_smile:
in-place, true to remove: remove(where:)
out-of-place, true to remove: X?
in-place, true to keep: Y?

The names for X that fall easily out of the naming guidelines are removed(where:) or removing(where:)

Y is trickier. Normally, the out-of-place would be a variant (like the past participle) of the mutating operation, but with filter the out-of-place method is already named,* so options are limited. formFilter(_:slight_smile: is one suggestion.

To help guide feedback on this, here are 4 questions to answer:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?
2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?
3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?
4. If you are for completing, what should X and Y be called?

Any answers, or further thoughts on any of the above, appreciated.

Ben

* while you could argue that this can be resolved by renaming filter, renames like this have a very high bar to clear. Also, filter is a term of art, hence its previous exemption from the naming guidelines.

And here are my answers, in a separate email to maintain a shred of separation between objectivity and subjectivity :slight_smile:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes. If the closure returned false for removal a different, less readable, name would be needed for the method.

2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly that it’s more efficient than x = x.filter (in addition to reability/discoverability benefits), I think that once both an in- and out-of-place version are available, users will reach immediately for the one they want. The scenario where you were filtering, and then you realize you could do it in-place more efficiently, doesn’t seem to me like it will come up in day-to-day use.

3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we need to complete the set.

4. If you are for completing, what should X and Y be called?

One of the reasons I _don’t_ think we should complete the set is that formFilter(_:slight_smile: will take us into serious jumped-the-shark territory, naming-wise.

I think there’s an argument for never having had filter, and always having had remove/removed (or possibly select/selected), but don’t think this is important enough to clear the bar for a rename of this magnitude.

···

On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:

The main issue here is that the proposal is missing the variant which returns the elements that are removed… and that throws out a lot of very useful use cases.

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes

2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

They always have the option of just inverting the closure. I doubt people will change the function being used unless they are doing a larger refactor (or need the removed results).

3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I am on the fence. I don’t think gaps will cause an issue, but I could see the usefulness of having more options (but are they worth the upkeep?).

4. If you are for completing, what should X and Y be called?

removing(where:) and formFilter() (though I have always been a fan of filter/filtered)

As I mentioned above, I think that either returning @discardableResults or having a variant which returns the results is very important. Look at the other thread on this topic from this morning for a discussion of why.

Thanks,
Jon

···

On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:

Hi everyone,

Reviving a pitch for a feature that didn’t make it into Swift 4. This was discussed in the core team recently, and feedback was wanted regarding the naming of the method and the polarity of the where closure.

Here’s the proposal:

https://github.com/airspeedswift/swift-evolution/blob/0f4a24d6ded2ab7cb39c1a68e0f92705a7615d73/proposals/NNNN-RemoveWhere.md

To keep things simple, this version removes the Equatable version. That could be added as a separate proposal.

The issue to resolve is: should the closure have the same polarity as filter, and if not, should filter also have an in-place equivalent?
(wait, don’t reply yet, read the rest of the email first :slight_smile:

From the original proposal:

`remove(where:)` takes a closure with `true` for elements to remove. `filter` takes a closure with `true` for 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.

Assuming you accept the premise that a closure returning `true` to `remove` is the “right way around” for the argument to an in-place removal operation, this means that we have a situation where if you want to flip from in-place to out-of-place removal, you have to reverse the closure.

Alternatively, we could duplicate the functionality, and have both filter and remove operations have in- and out-of-place variants, completing this 2x2 matrix:

out-of-place, true to keep: filter(_:slight_smile:
in-place, true to remove: remove(where:)
out-of-place, true to remove: X?
in-place, true to keep: Y?

The names for X that fall easily out of the naming guidelines are removed(where:) or removing(where:)

Y is trickier. Normally, the out-of-place would be a variant (like the past participle) of the mutating operation, but with filter the out-of-place method is already named,* so options are limited. formFilter(_:slight_smile: is one suggestion.

To help guide feedback on this, here are 4 questions to answer:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?
2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?
3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?
4. If you are for completing, what should X and Y be called?

Any answers, or further thoughts on any of the above, appreciated.

Ben

* while you could argue that this can be resolved by renaming filter, renames like this have a very high bar to clear. Also, filter is a term of art, hence its previous exemption from the naming guidelines.

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

Er… sorry, by “returns results” I mean, return the removed items.

Thanks,
Jon

···

On Sep 26, 2017, at 4:59 PM, Jonathan Hull <jhull@gbis.com> wrote:

The main issue here is that the proposal is missing the variant which returns the elements that are removed… and that throws out a lot of very useful use cases.

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes

2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

They always have the option of just inverting the closure. I doubt people will change the function being used unless they are doing a larger refactor (or need the removed results).

3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I am on the fence. I don’t think gaps will cause an issue, but I could see the usefulness of having more options (but are they worth the upkeep?).

4. If you are for completing, what should X and Y be called?

removing(where:) and formFilter() (though I have always been a fan of filter/filtered)

As I mentioned above, I think that either returning @discardableResults or having a variant which returns the results is very important. Look at the other thread on this topic from this morning for a discussion of why.

Thanks,
Jon

On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:

Hi everyone,

Reviving a pitch for a feature that didn’t make it into Swift 4. This was discussed in the core team recently, and feedback was wanted regarding the naming of the method and the polarity of the where closure.

Here’s the proposal:

https://github.com/airspeedswift/swift-evolution/blob/0f4a24d6ded2ab7cb39c1a68e0f92705a7615d73/proposals/NNNN-RemoveWhere.md

To keep things simple, this version removes the Equatable version. That could be added as a separate proposal.

The issue to resolve is: should the closure have the same polarity as filter, and if not, should filter also have an in-place equivalent?
(wait, don’t reply yet, read the rest of the email first :slight_smile:

From the original proposal:

`remove(where:)` takes a closure with `true` for elements to remove. `filter` takes a closure with `true` for 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.

Assuming you accept the premise that a closure returning `true` to `remove` is the “right way around” for the argument to an in-place removal operation, this means that we have a situation where if you want to flip from in-place to out-of-place removal, you have to reverse the closure.

Alternatively, we could duplicate the functionality, and have both filter and remove operations have in- and out-of-place variants, completing this 2x2 matrix:

out-of-place, true to keep: filter(_:slight_smile:
in-place, true to remove: remove(where:)
out-of-place, true to remove: X?
in-place, true to keep: Y?

The names for X that fall easily out of the naming guidelines are removed(where:) or removing(where:)

Y is trickier. Normally, the out-of-place would be a variant (like the past participle) of the mutating operation, but with filter the out-of-place method is already named,* so options are limited. formFilter(_:slight_smile: is one suggestion.

To help guide feedback on this, here are 4 questions to answer:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?
2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?
3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?
4. If you are for completing, what should X and Y be called?

Any answers, or further thoughts on any of the above, appreciated.

Ben

* while you could argue that this can be resolved by renaming filter, renames like this have a very high bar to clear. Also, filter is a term of art, hence its previous exemption from the naming guidelines.

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

And here are my answers, in a separate email to maintain a shred of
separation between objectivity and subjectivity :slight_smile:

>
> 1. Is it right to assert that with a “removing” operation, the closure
should return `true` for removal?

Yes. If the closure returned false for removal a different, less readable,
name would be needed for the method.

Agree, yes.

2. Is it likely that users will want to switch from out-of- to in-place,
and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly that
it’s more efficient than x = x.filter (in addition to
reability/discoverability benefits), I think that once both an in- and
out-of-place version are available, users will reach immediately for the
one they want. The scenario where you were filtering, and then you realize
you could do it in-place more efficiently, doesn’t seem to me like it will
come up in day-to-day use.

Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if
the full matrix of four operations exist.

> 3. Should we “complete” the matrix of 4 operations, or is it fine for it
to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we
need to complete the set.

Based on question (2), I would argue that the answer is yes.

4. If you are for completing, what should X and Y be called?
>

One of the reasons I _don’t_ think we should complete the set is that
formFilter(_:slight_smile: will take us into serious jumped-the-shark territory,
naming-wise.

I think there’s an argument for never having had filter, and always having
had remove/removed (or possibly select/selected), but don’t think this is
important enough to clear the bar for a rename of this magnitude.

IMO, they should be called removing(where:) [removed(where:) reads weirdly
in conjunction with the preceding receiver] and formFilter(_:). Hundreds of
messages finally settled on "form" as the in-place verb of choice where the
noun can't ordinarily be verbed. No point in being shy about it now: that's
the Swift way, wear it proudly.

···

On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution < swift-evolution@swift.org> wrote:

> On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution < > swift-evolution@swift.org> wrote:

And here are my answers, in a separate email to maintain a shred of separation between objectivity and subjectivity :slight_smile:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes. If the closure returned false for removal a different, less readable, name would be needed for the method.

Yes. I think the opposite would be quite confusing.

2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly that it’s more efficient than x = x.filter (in addition to reability/discoverability benefits), I think that once both an in- and out-of-place version are available, users will reach immediately for the one they want. The scenario where you were filtering, and then you realize you could do it in-place more efficiently, doesn’t seem to me like it will come up in day-to-day use.

I don’t think so, see next answer.

3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we need to complete the set.

Not only do I think that filter(_:slight_smile: and remove(where:) are sufficient, I think completing the matrix would add more confusion: it increases the API surface area for little gain. It’s also easier to start with only remove(where:) and add more if experience shows us we need more than to start with the whole matrix and be stuck with it, despite negative experience.

···

On 27 Sep 2017, at 01:14, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:

On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:

4. If you are for completing, what should X and Y be called?

One of the reasons I _don’t_ think we should complete the set is that formFilter(_:slight_smile: will take us into serious jumped-the-shark territory, naming-wise.

I think there’s an argument for never having had filter, and always having had remove/removed (or possibly select/selected), but don’t think this is important enough to clear the bar for a rename of this magnitude.

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

formFilter reads really weirdly... the use of filter in `filter` is not as a noun, but as a verb — compare to e.g., formRemainder. Calling formFilter won’t create a filter, it will “do” a filter. Perhaps formByFiltering?

···

On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:
And here are my answers, in a separate email to maintain a shred of separation between objectivity and subjectivity :slight_smile:

> On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:
>
> 1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes. If the closure returned false for removal a different, less readable, name would be needed for the method.

Agree, yes.

> 2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly that it’s more efficient than x = x.filter (in addition to reability/discoverability benefits), I think that once both an in- and out-of-place version are available, users will reach immediately for the one they want. The scenario where you were filtering, and then you realize you could do it in-place more efficiently, doesn’t seem to me like it will come up in day-to-day use.

Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if the full matrix of four operations exist.

> 3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we need to complete the set.

Based on question (2), I would argue that the answer is yes.

> 4. If you are for completing, what should X and Y be called?
>

One of the reasons I _don’t_ think we should complete the set is that formFilter(_:slight_smile: will take us into serious jumped-the-shark territory, naming-wise.

I think there’s an argument for never having had filter, and always having had remove/removed (or possibly select/selected), but don’t think this is important enough to clear the bar for a rename of this magnitude.

IMO, they should be called removing(where:) [removed(where:) reads weirdly in conjunction with the preceding receiver] and formFilter(_:). Hundreds of messages finally settled on "form" as the in-place verb of choice where the noun can't ordinarily be verbed. No point in being shy about it now: that's the Swift way, wear it proudly.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I think it is worth considering a version which both removes items in
place, and also returns the removed items, so as to split the collection by
a predicate.

Nevin

formFilter reads really weirdly... the use of filter in `filter` is not as
a noun, but as a verb — compare to e.g., formRemainder. Calling formFilter
won’t create a filter, it will “do” a filter. Perhaps formByFiltering?

That's interesting. I worry it might be too clever by half, though.

The prototypical "form" method is "formUnion"; it's so named because the
term "union" is used in math as both noun and verb ("a union b"; "the union
of a and b") and is a term of art that doesn't lend itself to the noun/verb
rule in Swift. Here, "filter" is a term of art (otherwise, it'd be called
"filtered"); now that "filter" is the non-mutating function (i.e., what
should otherwise be a noun), there's no way to maintain the noun/verb rule
in Swift. Therefore, without overthinking it, "formFilter".

Note that it's not "formUnion(with:)", just "formUnion(_:)". As is the case
with "formUnion", no particular attempt is made here to turn this method
name into an English phrase. The phrase "by filtering" very strongly
suggests true-to-remove; that's the only way the term "filtering" is used
in English. Here, we mean true-to-keep, and there's no way to express that
with the English word "filter" between the receiver and the predicate with
any sort of conjugation of the word or concise combination of helper words.
The nearest good-English name might be something like
"formFilteredResultKeeping(where:)", which is clearly awful for other
reasons.

···

On Tue, Sep 26, 2017 at 6:48 PM, Robert Bennett <rltbennett@icloud.com> wrote:

On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution < > swift-evolution@swift.org> wrote:

And here are my answers, in a separate email to maintain a shred of
separation between objectivity and subjectivity :slight_smile:

> On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution < >> swift-evolution@swift.org> wrote:
>
> 1. Is it right to assert that with a “removing” operation, the closure
should return `true` for removal?

Yes. If the closure returned false for removal a different, less
readable, name would be needed for the method.

Agree, yes.

> 2. Is it likely that users will want to switch from out-of- to in-place,

and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly
that it’s more efficient than x = x.filter (in addition to
reability/discoverability benefits), I think that once both an in- and
out-of-place version are available, users will reach immediately for the
one they want. The scenario where you were filtering, and then you realize
you could do it in-place more efficiently, doesn’t seem to me like it will
come up in day-to-day use.

Unsure. Maybe and maybe, but I think the confusion/bugs would be limited
if the full matrix of four operations exist.

> 3. Should we “complete” the matrix of 4 operations, or is it fine for
it to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we
need to complete the set.

Based on question (2), I would argue that the answer is yes.

> 4. If you are for completing, what should X and Y be called?

>

One of the reasons I _don’t_ think we should complete the set is that
formFilter(_:slight_smile: will take us into serious jumped-the-shark territory,
naming-wise.

I think there’s an argument for never having had filter, and always
having had remove/removed (or possibly select/selected), but don’t think
this is important enough to clear the bar for a rename of this magnitude.

IMO, they should be called removing(where:) [removed(where:) reads weirdly
in conjunction with the preceding receiver] and formFilter(_:). Hundreds of
messages finally settled on "form" as the in-place verb of choice where the
noun can't ordinarily be verbed. No point in being shy about it now: that's
the Swift way, wear it proudly.

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

All very good points.

···

On Sep 26, 2017, at 10:32 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Tue, Sep 26, 2017 at 6:48 PM, Robert Bennett <rltbennett@icloud.com> wrote:
formFilter reads really weirdly... the use of filter in `filter` is not as a noun, but as a verb — compare to e.g., formRemainder. Calling formFilter won’t create a filter, it will “do” a filter. Perhaps formByFiltering?

That's interesting. I worry it might be too clever by half, though.

The prototypical "form" method is "formUnion"; it's so named because the term "union" is used in math as both noun and verb ("a union b"; "the union of a and b") and is a term of art that doesn't lend itself to the noun/verb rule in Swift. Here, "filter" is a term of art (otherwise, it'd be called "filtered"); now that "filter" is the non-mutating function (i.e., what should otherwise be a noun), there's no way to maintain the noun/verb rule in Swift. Therefore, without overthinking it, "formFilter".

Note that it's not "formUnion(with:)", just "formUnion(_:)". As is the case with "formUnion", no particular attempt is made here to turn this method name into an English phrase. The phrase "by filtering" very strongly suggests true-to-remove; that's the only way the term "filtering" is used in English. Here, we mean true-to-keep, and there's no way to express that with the English word "filter" between the receiver and the predicate with any sort of conjugation of the word or concise combination of helper words. The nearest good-English name might be something like "formFilteredResultKeeping(where:)", which is clearly awful for other reasons.

On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:
And here are my answers, in a separate email to maintain a shred of separation between objectivity and subjectivity :slight_smile:

> On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:
>
> 1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes. If the closure returned false for removal a different, less readable, name would be needed for the method.

Agree, yes.

> 2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly that it’s more efficient than x = x.filter (in addition to reability/discoverability benefits), I think that once both an in- and out-of-place version are available, users will reach immediately for the one they want. The scenario where you were filtering, and then you realize you could do it in-place more efficiently, doesn’t seem to me like it will come up in day-to-day use.

Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if the full matrix of four operations exist.

> 3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we need to complete the set.

Based on question (2), I would argue that the answer is yes.

> 4. If you are for completing, what should X and Y be called?
>

One of the reasons I _don’t_ think we should complete the set is that formFilter(_:slight_smile: will take us into serious jumped-the-shark territory, naming-wise.

I think there’s an argument for never having had filter, and always having had remove/removed (or possibly select/selected), but don’t think this is important enough to clear the bar for a rename of this magnitude.

IMO, they should be called removing(where:) [removed(where:) reads weirdly in conjunction with the preceding receiver] and formFilter(_:). Hundreds of messages finally settled on "form" as the in-place verb of choice where the noun can't ordinarily be verbed. No point in being shy about it now: that's the Swift way, wear it proudly.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

`formFilter` strongly implies that the result is a filter, so this would be a very bad choice. i do not follow the argument that it makes sense to just concatenate `form` and the non-mutating method name. The precedence set by `formUnion` is not a good one but at least there it makes sense because using union as a noun preserves the original meaning (the missing `with:` is tolerable) whereas `formFilter` conveys a completely wrong meaning.

To answer Ben's questions:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes, definitely.

2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I do not think that it is very likely and if so I do not think that having to flip the closure will cause confusion because both methods are very differently named.

3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

No, it is fine to have gaps. I would consider adding a `removing` variant but as there is no good name for the mutating variant of `filter` I would definitely not add this one.

4. If you are for completing, what should X and Y be called?

I am against completing.

-Thorsten

···

Am 27.09.2017 um 04:33 schrieb Xiaodi Wu via swift-evolution <swift-evolution@swift.org>:

On Tue, Sep 26, 2017 at 6:48 PM, Robert Bennett <rltbennett@icloud.com> wrote:
formFilter reads really weirdly... the use of filter in `filter` is not as a noun, but as a verb — compare to e.g., formRemainder. Calling formFilter won’t create a filter, it will “do” a filter. Perhaps formByFiltering?

That's interesting. I worry it might be too clever by half, though.

The prototypical "form" method is "formUnion"; it's so named because the term "union" is used in math as both noun and verb ("a union b"; "the union of a and b") and is a term of art that doesn't lend itself to the noun/verb rule in Swift. Here, "filter" is a term of art (otherwise, it'd be called "filtered"); now that "filter" is the non-mutating function (i.e., what should otherwise be a noun), there's no way to maintain the noun/verb rule in Swift. Therefore, without overthinking it, "formFilter".

Note that it's not "formUnion(with:)", just "formUnion(_:)". As is the case with "formUnion", no particular attempt is made here to turn this method name into an English phrase. The phrase "by filtering" very strongly suggests true-to-remove; that's the only way the term "filtering" is used in English. Here, we mean true-to-keep, and there's no way to express that with the English word "filter" between the receiver and the predicate with any sort of conjugation of the word or concise combination of helper words. The nearest good-English name might be something like "formFilteredResultKeeping(where:)", which is clearly awful for other reasons.

On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:
And here are my answers, in a separate email to maintain a shred of separation between objectivity and subjectivity :slight_smile:

> On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org> wrote:
>
> 1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes. If the closure returned false for removal a different, less readable, name would be needed for the method.

Agree, yes.

> 2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I don’t think so. While the argument for an in-place remove is partly that it’s more efficient than x = x.filter (in addition to reability/discoverability benefits), I think that once both an in- and out-of-place version are available, users will reach immediately for the one they want. The scenario where you were filtering, and then you realize you could do it in-place more efficiently, doesn’t seem to me like it will come up in day-to-day use.

Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if the full matrix of four operations exist.

> 3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we need to complete the set.

Based on question (2), I would argue that the answer is yes.

> 4. If you are for completing, what should X and Y be called?
>

One of the reasons I _don’t_ think we should complete the set is that formFilter(_:slight_smile: will take us into serious jumped-the-shark territory, naming-wise.

I think there’s an argument for never having had filter, and always having had remove/removed (or possibly select/selected), but don’t think this is important enough to clear the bar for a rename of this magnitude.

IMO, they should be called removing(where:) [removed(where:) reads weirdly in conjunction with the preceding receiver] and formFilter(_:). Hundreds of messages finally settled on "form" as the in-place verb of choice where the noun can't ordinarily be verbed. No point in being shy about it now: that's the Swift way, wear it proudly.
_______________________________________________
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

`formFilter` strongly implies that the result is a filter, so this would be a very bad choice. i do not follow the argument that it makes sense to just concatenate `form` and the non-mutating method name. The precedence set by `formUnion` is not a good one but at least there it makes sense because using union as a noun preserves the original meaning (the missing `with:` is tolerable) whereas `formFilter` conveys a completely wrong meaning.

FWIW Totally support Thorsten's opinion and replies to Ben's questions.

If we really also need mutating 'filter', why not 'formFiltered()'?
IMO this could be a valid name pattern for Swift in case simple noun like 'Filter' has no sense for what the method does: 'form' is a primary marker of mutating method, and 'Filtered' just clarifies what we'll have inside the instance in result of that call. Very similar to 'formUnion', but with correct meaning.
(Just thoughts... Isn't 'filterInPlace' the best variant :wink: )

I also don't think we need to fill the matrix, 2 filtering methods(one for non-mutating and one for mutating) IMO is a good minimum we need, and 'remove' is a right in-place filtering method with obvious meaning. If we'll need more filtering methods - we can add them later.

Vladimir.

···

On 01.10.2017 22:44, Thorsten Seitz via swift-evolution wrote:

To answer Ben's questions:

1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

Yes, definitely.

2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

I do not think that it is very likely and if so I do not think that having to flip the closure will cause confusion because both methods are very differently named.

3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

No, it is fine to have gaps. I would consider adding a `removing` variant but as there is no good name for the mutating variant of `filter` I would definitely not add this one.

4. If you are for completing, what should X and Y be called?

I am against completing.

-Thorsten

Am 27.09.2017 um 04:33 schrieb Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

On Tue, Sep 26, 2017 at 6:48 PM, Robert Bennett <rltbennett@icloud.com >> <mailto:rltbennett@icloud.com>> wrote:

    formFilter reads really weirdly... the use of filter in `filter` is not as a
    noun, but as a verb — compare to e.g., formRemainder. Calling formFilter won’t
    create a filter, it will “do” a filter. Perhaps formByFiltering?

That's interesting. I worry it might be too clever by half, though.

The prototypical "form" method is "formUnion"; it's so named because the term "union" is used in math as both noun and verb ("a union b"; "the union of a and b") and is a term of art that doesn't lend itself to the noun/verb rule in Swift. Here, "filter" is a term of art (otherwise, it'd be called "filtered"); now that "filter" is the non-mutating function (i.e., what should otherwise be a noun), there's no way to maintain the noun/verb rule in Swift. Therefore, without overthinking it, "formFilter".

Note that it's not "formUnion(with:)", just "formUnion(_:)". As is the case with "formUnion", no particular attempt is made here to turn this method name into an English phrase. The phrase "by filtering" very strongly suggests true-to-remove; that's the only way the term "filtering" is used in English. Here, we mean true-to-keep, and there's no way to express that with the English word "filter" between the receiver and the predicate with any sort of conjugation of the word or concise combination of helper words. The nearest good-English name might be something like "formFilteredResultKeeping(where:)", which is clearly awful for other reasons.

    On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

        And here are my answers, in a separate email to maintain a shred of
        separation between objectivity and subjectivity :slight_smile:

        > On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
        >
        > 1. Is it right to assert that with a “removing” operation, the closure should return `true` for removal?

        Yes. If the closure returned false for removal a different, less readable,
        name would be needed for the method.

    Agree, yes.

        > 2. Is it likely that users will want to switch from out-of- to in-place, and if so, will having to flip the closure cause confusion/bugs?

        I don’t think so. While the argument for an in-place remove is partly that
        it’s more efficient than x = x.filter (in addition to
        reability/discoverability benefits), I think that once both an in- and
        out-of-place version are available, users will reach immediately for the
        one they want. The scenario where you were filtering, and then you realize
        you could do it in-place more efficiently, doesn’t seem to me like it will
        come up in day-to-day use.

    Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if
    the full matrix of four operations exist.

        > 3. Should we “complete” the matrix of 4 operations, or is it fine for it to have gaps?

        I think filter(_:slight_smile: and remove(where:) are sufficient. I don’t think we
        need to complete the set.

    Based on question (2), I would argue that the answer is yes.

        > 4. If you are for completing, what should X and Y be called?
        >

        One of the reasons I _don’t_ think we should complete the set is that
        formFilter(_:slight_smile: will take us into serious jumped-the-shark territory,
        naming-wise.

        I think there’s an argument for never having had filter, and always having
        had remove/removed (or possibly select/selected), but don’t think this is
        important enough to clear the bar for a rename of this magnitude.

    IMO, they should be called removing(where:) [removed(where:) reads weirdly in
    conjunction with the preceding receiver] and formFilter(_:). Hundreds of
    messages finally settled on "form" as the in-place verb of choice where the
    noun can't ordinarily be verbed. No point in being shy about it now: that's
    the Swift way, wear it proudly.
    _______________________________________________
    swift-evolution mailing list
    swift-evolution@swift.org <mailto:swift-evolution@swift.org>
    https://lists.swift.org/mailman/listinfo/swift-evolution
    <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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