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

Jarod Long swift at lng.la
Thu Feb 11 16:13:19 CST 2016

Here are some thoughts after having quietly pondered the mutating method naming discussion for a while.

My view is that an "ed/ing" mutation rule is fraught with undesirable compromises. It's tempting because it works so well in the majority of cases, but it seems that cases where it doesn't work are not uncommon, even when the scope of the discussion is narrowed to a small set of operations such as this. We're trying to play nice with English, but we're butting up against its fundamental lack of clarity.

As far as I see it, these are the options (forgive me for repeating much of what others have said -- I'd like to accurately convey my perception of the situation as a whole):

1. Move forward with ed/ing-based guidelines that work well in many cases. For the cases which don't work well, we can either:

Have explicit exceptions, likely leading to overly-complicated guidelines that people may not be bothered to follow.
Leave it up to the developer to decide what's best on a case-by-case basis, likely leading to inconsistencies and lots of time spent on discussions of this magnitude.

There's also a worrying amount of uncertainty and subjectivity involved in identifying the situations where the base guidelines don't work well, particularly for developers who aren't experts in English.

2. Use "inPlace" or some other simple adornment that can be universally applied to a method without exceptions.

An inPlace suffix would be a significant eyesore for such a common pattern. There doesn't seem to be another less obtrusive suffix that properly conveys mutation, so we're either stuck with inPlace, or we could try to find a more terse symbolic pattern (the same idea as Ruby's postfix ! to indicate mutation). Nothing desirable comes to mind, though.

3. Add a language-level feature that allows a method on a type which returns a value of that same type to be called in a way that mutates the callee.

Even when naming isn't an issue, defining mutating / non-mutating versions of method is somewhat tedious and inflates the type's interface. Any method that returns a value of the callee's type is a valid candidate for a mutating version of that API, but defining the mutating version is 100% boilerplate.

Support from the compiler would eliminate this boilerplate as well as this seemingly-unsolvable naming problem at the cost of some additional complexity in the compiler.

I can see two options off the top of my head. First, a method that returns the same type as the callee mutates when its return value is unused instead of producing a warning:

let c = a.union(with: b) // Doesn't mutate.
a.union(with: b)         // Mutates.

This is somewhat subtle and has some potential for confusion, but I think Swift's strong immutability features would make it extremely rare for this pattern to create bugs.

Or, we can create a special syntax for mutating a callee with the return value of its method:

a .= union(with: b) // First thing that comes to mind. It's conceptually similar to += and friends and makes assignment explicit.
a = .union(with: b) // Similar idea, looks less like you're calling a global method called union.

My personal preference lies strongly in option 3 with roughly equal preference for either sub-option, but I'd really like to hear what others think.


> On Feb 11, 2016, at 11:43, Jacob Bandes-Storch via swift-evolution <swift-evolution at swift.org> wrote:
> Just thinking out loud here:
> "x's intersection with y" makes sense. So "x.intersection(with: y)" makes sense.  That's already in Dave's diff.
> Unfortunately the same doesn't work well for "x's union with y" — should "x.union(with: y)" be a mutating or nonmutating operation? Hard to tell.
> How about we just move to ∪ and ∪= operators and call it a day? :-)
> On Thu, Feb 11, 2016 at 11:36 AM, Erica Sadun <erica at ericasadun.com <mailto:erica at ericasadun.com>> wrote:
> Assuming one would want to avoid the -ed suffix (and also -ing), one might consider:
> * intersectionOf(), orOf(), unionOf() (or "With" over "Of")
> * setIntersection(), setOr(), setUnion(),
> * intersectionResult(), orResult(), unionResult(),
> etc
> -- E
>> On Feb 11, 2016, at 12:28 PM, Jacob Bandes-Storch <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> wrote:
>> "intersected" sounds okay to me. "unioned" is borderline, and "ored" is not something I'd want in the standard library. Neither is "oring".
>> On Thu, Feb 11, 2016 at 11:25 AM, Erica Sadun <erica at ericasadun.com <mailto:erica at ericasadun.com>> wrote:
>> I see the -ed versions as short for -edSet, with the Set being implied. Under this reasoning, unioned == unionedSet, intersected == intersectedSet, thus acting as nouns not verbs, and used for non-mutating application.
>> inPlace is only for mutating application. I mildly prefer the shorter union to unionInPlace, although I could argue both sides. (The latter is clearer but longer, the former is the short verb action that the whole guideline thing is supposed to endorse.)
>> -- E
>>> On Feb 11, 2016, at 12:19 PM, Jacob Bandes-Storch <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> wrote:
>>> On Thu, Feb 11, 2016 at 11:09 AM, Erica Sadun via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> Non-Mutating, returning new value: unioned(with), intersected(with), exclusiveOred(with)
>>> Reasoning:
>>> * I think the -ing endings sound unnatural, stilted, and unmathematical. They make me wince.
>>> So do the -ed versions, IMO. That's why -InPlace is such a convenient suffix.
>>> Jacob
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160211/16ebb308/attachment.html>

More information about the swift-evolution mailing list