[swift-evolution] ed/ing, InPlace, Set/SetAlgebra naming resolution

Tony Parker anthony.parker at apple.com
Mon Feb 15 19:44:27 CST 2016


Hi everyone,

First - I want to thank all of the contributors on this discussion for helping us with this obviously tricky naming problem.

Dave has already described some of the thinking that has gone into the iterations of the API for Set. You’ve seen stages of that evolution here.

We’re at the point where we need to make a decision and move on. Not because it’s impossible to come up with better ideas, but because we want to continue to work on the remaining aspects of the naming proposals that we’ve put forth on this list. 

In the future, there is always the opportunity for members of the community and members of the core team to propose ideas like newly discovered names, improvements to the language like keywords for mutation-in-place or special operators, or whatever great thing comes next. If we decide to do those, then we will be sure to consider the impact on the APIs we choose today. There are many tools in our toolbox for rolling out those improvements (deprecation and replacement being the one we’ve used countless times for framework and library API).

So: by incorporating your ideas in this thread, along with those from other members of the API naming working group, and by adhering to the proposed guidelines as closely as possible, we’re going to go with the following API changes for SetAlgebra for Swift 3:

    /// Returns the set of elements contained in `self`, in `other`, or in both `self` and `other`.
    /// EXISTING: union
    @warn_unused_result
    func insertingContentsOf(other: Self) -> Self
    
    /// Insert all elements of `other` into `self`.
    /// EXISTING: unionInPlace
    mutating func insertContentsOf(other: Self)
    
    /// Returns the set of elements contained in both `self` and `other`.
    /// EXISTING: intersect
    @warn_unused_result
    func intersection(other: Self) -> Self

    /// Removes all elements of `self` that are not also present in `other`.
    /// EXISTING: intersectInPlace
    mutating func intersect(other: Self)

    /// Returns the set of elements contained in `self` or in `other`, but not in both `self` and `other`.
    /// EXISTING: exclusiveOr
    @warn_unused_result
    func invertingIntersection(other: Self) -> Self
    
    /// Replaces `self` with a set containing all elements contained in either `self` or `other`, but not both.
    /// EXISTING: exclusiveOrInPlace
    mutating func invertIntersection(other: Self)
    
    /// Returns the set of elements contained in `self` but not in `other`.
    /// EXISTING: subtract
    @warn_unused_result
    func removingContentsOf(other: Self) -> Self
    
    /// Removes all elements of `other` from `self`.
    /// EXISTING: subtractInPlace
    mutating func removeContentsOf(other: Self)

Here is a summary of the reasons behind the decision:

1. As Dave said, it is important that we are able to apply our guidelines without an exception to such a core type. It’s not just about one particular Set type either, as these methods appear on many places in API (for example — all options are now Sets as well), thanks to Swift support for protocol-oriented-programming.

2. Using ‘insert’ instead of ‘union’ makes the method part of a family with the existing API on SetAlgebra: mutating func insert(member:). Indeed - the language of ‘insert’ has been in the markdown comment since the beginning. The same justification applies to using ‘remove’ instead of ‘subtract’.

3. The ContentsOf suffix is precedented by RangeReplaceableCollection, as a way to disambiguate inserting the contents of some collection vs the collection itself. It makes sense to reuse it here instead of using new terminology.

4. With the decision to use ‘insert’ and ‘remove’, we have built a very succinct vocabulary of operations on set: 
	operations which add content (insert)
	operations which remove content (remove). 

That leaves us with operations which both add and remove content. Intersect is straightforward enough and does not have significant naming challenges, so we keep it and apply the noun-phrase rule to the non-mutating function to distinguish it from the mutating function. exclusiveOr is trickier. However, I believe the suggestion made here of using invert leads us to a succinct name that conveys the right meaning, without putting two verbs in the base name.

We will also add additional documentation to each of these methods to describe their mathematical underpinnings. I hope that will aid developers in finding the right method, if they are not already familiar with the terminology we choose.

Again, sincere thanks for all of your input here.

- Tony

> On Feb 14, 2016, at 12:56 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> on Sun Feb 14 2016, plx <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>>> On Feb 13, 2016, at 1:32 PM, Dave Abrahams via swift-evolution
>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> 
>>> on Sat Feb 13 2016, plx
>> 
>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>> wrote:
>>> 
>>>> On a skim, if there’s a specific explanation as to *why* `inPlace` is
>>>> a now a no-go, I don’t see it. 
>>> 
>>> Several justifications were given:
>>> 
>>> * Several people have an “ick” reaction when they see it.
>>> 
>>> * It's not in the guidelines.
>>> 
>>> * If we add it to the guidelines, it will only be as fallback
>>> last-resort alternative.
>>> 
>>> * If one of the three main collection types can't conform to the
>>> recommendations of the non-last-resort guidelines, the guidelines are
>>> a failure.
>> 
>> As a devil’s advocate, why wouldn’t the existing names be justifiable
>> under “Use terminology well” guideline?
> 
> I'm afraid you'll have to ask someone who understands the decision :-).
> I've asked someone else to explain it; hopefully that will happen soon.
> 
>> I’d consider making up new terminology for a well-established domain
>> much worse than simply not following the naming conventions.
>> 
>>> 
>>>> I can’t say I like the proposed changes
>>>> very much, and I definitely don’t like some of the more-creative
>>>> suggestions.
>>>> 
>>>> It’s hard to offer help when it’s not clear what was deemed
>>>> problematic about the existing (and “perfectly fine with me”!) names.
>>>> 
>>>> Separately, can I ask here why SetAlgebra protocol doesn’t contain an
>>>> *overridable* method like `func intersects(other: Self) -> Bool`?
>>>> 
>>>> (Note: I am *well-aware* that `a intersects b <=> !(a and b are disjoint)`).
>>> 
>>> There's no point in providing an override if there's no chance of it
>>> being better than the default implementation.
>> 
>> But again, cf `isSupersetOf` and `isSubsetOf`...which are both
>> overridable unless I’m misunderstanding. (Especially as there’s risk
>> of a performance “gotcha” if you only override “the wrong one”).
>> 
>>> 
>>>> That absence has been puzzling me ever whichever release of Swift
>>>> first introduced this protocol, particularly since e.g. both
>>>> `isSubsetOf` and `isSupersetOf` are individually-overridable.
>>>> 
>>>> (Likewise, but less so, I do wonder why the protocol doesn’t contain
>>>> *overridable* `isStrictSubset` and `isStrictSuperset` functions,
>>>> either...).
>>> 
>>> Same reasoning, but we may have mistakenly decided there was no chance
>>> of optimization.  If so, please open a ticket.
>> 
>> There are definitely examples of such; https://bugs.swift.org/browse/SR-735 . 
>> 
>> After looking at what’s in github, there really ought to be a few more
>> families of default implementations, e.g. `extension SetAlgebraType
>> where Self:CollectionType` and `extension SetAlgebraType where
>> Self:CollectionType, Index: RandomAccessIndexType` (where we can
>> assume O(1) count).
>> 
>> Is that better as just a ticket or as a discussion on one of the
>> lists?
> 
> On the surface they seem like clear bugs/missed optimizations to me, so
> I think tickets are the right medium.
> 
>> 
>> 
>>> 
>>>>> On Feb 11, 2016, at 10:52 AM, Dave Abrahams via swift-evolution
>>>>> <swift-evolution at swift.org> wrote:
>>>>> 
>>>>> 
>>>>> Hi All,
>>>>> 
>>>>> The API guidelines working group took up the issue of the InPlace suffix
>>>>> yesterday, and decided that it was not to be used anywhere in the
>>>>> standard library.  We are planning to apply the changes shown here
>>>>> <https://gist.github.com/dabrahams/d872556291a3cb797bd5> to the API of
>>>>> SetAlgebra (and consequently Set) to make it conform to the guidelines
>>>>> under development.
>>>>> 
>>>>> Comments welcome as usual,
>>>>> 
>>>>> -- 
>>>>> -Dave
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>> 
>>> -- 
>>> -Dave
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> -- 
> -Dave
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160215/e09052fc/attachment.html>


More information about the swift-evolution mailing list