# Inverting differences

**URL:** <https://forums.swift.org/t/inverting-differences/26040>\
**Category:** Pitches\
**Created:** [June 18, 2019, 10:16pm UTC](https://forums.swift.org/t/inverting-differences/26040 "2019-06-18T22:16:37Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![numist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/numist/32/5612_2.png) [@numist](https://forums.swift.org/u/numist)\
**Post date:** [June 18, 2019, 10:16pm UTC](https://forums.swift.org/t/inverting-differences/26040/1 "2019-06-18T22:16:37Z")

</div>

Hello all!

With the passing of WWDC and the beta release of macOS Catalina and iOS 13 we've discovered a disparity between Foundation's `NSOrderedCollectionDifference` and Swift's `CollectionDifference` APIs: the latter is missing `inverse()`.

The rationale for the method's inclusion in Foundation was: after the initial version of collection diffing was feature complete it was soon obvious that a convenience for inverting a difference for use with e.g. an undo/redo stack was extremely useful.

The rationale for the method's omission from Swift was: I was busy and forgot to amend the proposal.

So, I've opened a [PR for an amended proposal](https://github.com/apple/swift-evolution/pull/1052), and wanted to float this thread for people's reactions.

Before opening up the floor, I wanted to talk about naming.

Many many possibilities were considered when naming the Foundation API. Variants on `inverse`, `undone`, `reverted`, and `reversed` were all considered.

Many thanks to @sveinhal for [pointing out](https://forums.swift.org/t/se-0240-ordered-collection-diffing/19514/11) that `reversed` is a terrible name due to its overloaded use with reversing the order of elements in a collection.

`inverted`, `reverted`, and `undone` were ultimately passed on the realization that they all can be used to describe the result of the action that the result is _used for_, and not the result itself.

`inverse` specifically wound up winning on the strength of its existing meaning in math; an inverse function produces the identity function when composed with its original. In terms of concrete diffs, composing a diff with its inverse produces an empty diff.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [June 18, 2019, 10:27pm UTC](https://forums.swift.org/t/inverting-differences/26040/2 "2019-06-18T22:27:39Z")

</div>

> [@numist](#):
>
> `inverse` specifically wound up winning on the strength of its existing meaning in math; an inverse function produces the identity function when composed with its original. In terms of concrete diffs, composing a diff with its inverse produces an empty diff.

I also think symmetry with Apple APIs is a plus as well. I plan on doing something similar for adding a `tryMap` to `Result`, since Combine's naming matches.

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [June 19, 2019, 11:02pm UTC](https://forums.swift.org/t/inverting-differences/26040/3 "2019-06-19T23:02:44Z")

</div>

Hi everyone – the core team discussed this and agreed that since it's a small amendment to the previous proposal, we'll move immediately to a short amendment review which I'll kick of later today.

---

<div class="post-metadata">

**Author:** ![bzamayo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bzamayo/32/764_2.png) [@bzamayo](https://forums.swift.org/u/bzamayo)\
**Post date:** [June 19, 2019, 11:20pm UTC](https://forums.swift.org/t/inverting-differences/26040/4 "2019-06-19T23:20:01Z")

</div>

I hate to be ‘that guy’ — but shouldn’t it be `inverted()`, rather than `inverse()`?

---

<div class="post-metadata">

**Author:** ![glessard](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/glessard/32/409_2.png) [@glessard](https://forums.swift.org/u/glessard)\
**Post date:** [June 19, 2019, 11:35pm UTC](https://forums.swift.org/t/inverting-differences/26040/5 "2019-06-19T23:35:01Z")

</div>

"inverse" is a basic mathematical term as relates to functions. And it describes well what this would do. I think it's the correct name.

---

<div class="post-metadata">

**Author:** ![chipxsd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chipxsd/32/4250_2.png) [@chipxsd](https://forums.swift.org/u/chipxsd)\
**Post date:** [June 20, 2019, 12:44am UTC](https://forums.swift.org/t/inverting-differences/26040/6 "2019-06-20T00:44:33Z")

</div>

I suppose both are valid, but different?

I'd assume one mutates an existing collection `inverse()`, and the other one returns a new collection `inverted()` and doesn't mutate original one.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [June 20, 2019, 1:16am UTC](https://forums.swift.org/t/inverting-differences/26040/7 "2019-06-20T01:16:46Z")

</div>

Given the Swift naming conventions, that's what I would expect if I saw both methods.

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [June 20, 2019, 1:49am UTC](https://forums.swift.org/t/inverting-differences/26040/8 "2019-06-20T01:49:41Z")

</div>

I think both fit for a function which returns a new value, as `inverted()` is a past tense verb, and `inverse()` is a noun, but I think `inverse()` is better.

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [June 20, 2019, 2:24am UTC](https://forums.swift.org/t/inverting-differences/26040/9 "2019-06-20T02:24:58Z")

</div>

> [@bzamayo](#):
>
> I hate to be ‘that guy’ — but shouldn’t it be `inverted()` , rather than `inverse()` ?

If you mean, per the [naming guidelines](https://swift.org/documentation/api-design-guidelines/#naming), no it shouldn't. Both verbs and nouns are permitted as names for methods. In this case, the noun option has been chosen. `inverted()` would also be a valid choice but it is not preferred by the guidelines.

The one thing in favor of the verb version is a mutating version could be called `invert()` instead of the noun equivalent which would need to be something clunky like `formInverse()`. But one isn't being proposed (and probably won't be – doing this operation in-place would be strange I think, though @numist might have an opinion).

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [June 20, 2019, 3:26am UTC](https://forums.swift.org/t/inverting-differences/26040/10 "2019-06-20T03:26:10Z")

</div>

I'm surprised that the naming guidelines don't state a preference. Even if both are allowed, there's merit in consistently making the same choice for similar situations, and I'd expect that that will usually favor a past participle (which will nearly always exist with the regular form `-ed`) over a noun (which will often not exist and (when it does) will often either be irregular or ambiguous). Nouns should be reserved for cases where the natural verb phrase would be something like "make it [foo]", or else we'll be promoting a situation where users can't remember whether we decided to call something `reversed`, `reverse`, or `reversal`.

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [June 20, 2019, 3:42am UTC](https://forums.swift.org/t/inverting-differences/26040/11 "2019-06-20T03:42:35Z")

</div>

The trouble with rules is people insist you follow them. So if the guidelines expressed a preference, then we'd probably tie ourselves in knots favoring `symmetricallyDifferenced`.

Clarity at the point of use is the most important goal, and that means choosing the name that reads best, whether it's a noun or a verb. Given most code is written with the assistance of autocompletion, I don't think the exact spelling of the suffix is all that significant in comparison to the key goal of code that it read naturally.

---

<div class="post-metadata">

**Author:** ![numist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/numist/32/5612_2.png) [@numist](https://forums.swift.org/u/numist)\
**Post date:** [June 20, 2019, 4:35am UTC](https://forums.swift.org/t/inverting-differences/26040/12 "2019-06-20T04:35:01Z")

</div>

Fun story, I originally wrote this API with the same opinion as @John_McCall. The Foundation version of this method made it through API review as `-invertedDifference`, and that selector is still implemented in `NSOrderedCollectionDifference` to maintain compatibility for early adopters (please don't use it).

After the last stage of API review, someone pointed out that the verb "invert" invites confusing the mechanism that produces the result (inverting the diff) with the result's purpose (inverting the effect of a diff on a collection). This ambiguity is even stronger in Swift where the "Difference" component of the selector is omitted. Using the noun "inverse" allows the method to unambiguously describe its result, which seemed worth the compromise in consistency.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [June 20, 2019, 5:14am UTC](https://forums.swift.org/t/inverting-differences/26040/13 "2019-06-20T05:14:46Z")

</div>

Well, I won't insist if this is what you think is best.

---

<div class="post-metadata">

**Author:** ![bzamayo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bzamayo/32/764_2.png) [@bzamayo](https://forums.swift.org/u/bzamayo)\
**Post date:** [June 20, 2019, 9:13am UTC](https://forums.swift.org/t/inverting-differences/26040/14 "2019-06-20T09:13:09Z")

</div>

Interesting, thanks for the clarification. (The `symmetricDifference` example is a really good one as to why the verb forms shouldn't always win.)
