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

Dave Abrahams dabrahams at apple.com
Mon Feb 15 13:16:27 CST 2016


on Mon Feb 15 2016, Xiaodi Wu <swift-evolution at swift.org> wrote:

> Agreed that "union" creates an expectation that it's non-mutating.
>
> There's no real point in pushing back on whether UIs are more or less
> important for Swift than math.
>
> Problem is, the moment you name something SetAlgebra, you've set user
> expectations that it's a 'math API'. Those ain't UI terms.

Yep.  As I mentioned in
<http://news.gmane.org/find-root.php?message_id=m2pow033r1.fsf%40eno.apple.com>,
we have a semantic muddle here.  Given where this is all headed, I am
somewhat inclined to retire the SetAlgebra protocol (it only seems to
have 3-4 uses on github), but renaming it could be another viable
option.

> On Mon, Feb 15, 2016 at 11:25 AM Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> on Mon Feb 15 2016, Maximilian Hünenberger <swift-evolution at swift.org>
>> wrote:
>>
>> > I also prefer (2). Isn't "union", "intersection", ... a "Term of Art"?
>> > See the guidelines under "Stick to the established meaning".
>> >
>> > So we should stick to the mathematical naming.
>>
>> My understanding of the rationale for the current direction is that the
>> domain of building GUI apps is more important than that of math, so the
>> look and feel of sets should match those of most other (non-math) APIs.
>>
>> > Since these terms almost always return a new instance we should have
>> > an obvious mutating version with an "inPlace" suffix.
>> >
>> > - Maximilian
>> >
>> >> Am 14.02.2016 um 22:37 schrieb Xiaodi Wu via swift-evolution
>> >> <swift-evolution at swift.org>:
>> >>
>> >> From a 10,000-ft view, I'd suggest that the noun/verb rule
>> >> consistently runs into a problem with mathematical terms.
>> >>
>> >> In general, mathematical functions don't have verb forms. You
>> >> 'compute' the reciprocal, or 'find' the reciprocal, or 'take' the
>> >> reciprocal, you don't 'reciprocate' or 'reciprocalize'. Likewise for
>> >> trigonometric functions, etc. Nor can you really 'cross produce'...
>> >>
>> >> So consistent is this trend that where two words might be noun/verb
>> >> counterparts, like intersect/intersection and
>> >> transform/transformation, common math usage treats both as
>> >> acceptable nouns.
>> >>
>> >> In colloquial usage, you might verb the noun, but then by definition
>> >> the verb and noun become the same. Then, to generate a noun
>> >> phrase/participle/etc. that looks different from the verb, you have
>> >> to noun-ify the verbed noun.
>> >>
>> >> Without an exception for mathematical function names, the only
>> >> solution to fulfill these new Swift rules are clobbering the
>> >> well-known math name or not using the math name at all. Indeed all
>> >> proposed solutions so far come down to one of four options, either
>> >> applied globally or only to sets for now, punting the rest down the
>> >> road:
>> >>
>> >> (1) Abandon the rule, making a new one (e.g.: .=)
>> >> (2) Make an exception to the rule for math function names
>> >> (3) Generate the least offensive noun-ified verbed nouns based on math
>> function names
>> >> (4) Don't use math function names
>> >>
>> >> (1) is off the table, according to the core team. My vote at this
>> >> point is for (2), and I see that a few others have voiced that
>> >> opinion. It'd be nice to get a sense from the core team if that is
>> >> even a possibility. (3) has elicited a lot of discussion and
>> >> visceral reactions. (4) might be workable for sets alone but surely
>> >> can't be a generalized solution for all mathematical concepts to be
>> >> encountered in Swift.
>> >> On Sun, Feb 14, 2016 at 3:14 PM Tyler Fleming Cloutier via
>> >> swift-evolution
>> >> <swift-evolution at swift.org> wrote:
>> >>>> On Feb 14, 2016, at 12:48 PM, Dave Abrahams
>> >>>> <dabrahams at apple.com> wrote:
>> >>>>
>> >>>>
>> >>>> on Sun Feb 14 2016, Tyler Fleming Cloutier <cloutiertyler-AT-aol.com>
>> wrote:
>> >>>>
>> >>>>>> On Feb 14, 2016, at 8:27 AM, Dave Abrahams
>> >>>>>> <dabrahams at apple.com> wrote:
>> >>>>>>
>> >>>>>>
>> >>>>>> on Sat Feb 13 2016, Tyler Fleming Cloutier
>> <cloutiertyler-AT-aol.com> wrote:
>> >>>>>>
>> >>>>>>> I would, personally, be very careful about discarding the
>> mathematical
>> >>>>>>> terms since they are so widely used and understood.
>> >>>>>>
>> >>>>>> IMO it's better to leave them aside than to use them in “creative”
>> ways
>> >>>>>> that might be misleading.
>> >>>>>
>> >>>>> Agreed. I’m all for that.
>> >>>>>
>> >>>>>>> One issue is that it’s going to be hard to search for the
>> operation I
>> >>>>>>> want considering I won’t be looking for "func
>> >>>>>>> invertingMembershipOfContentsOf(other: Self) -> Self”. I’m
>> concerned
>> >>>>>>> people are going to have to do mental gymnastics to build the map
>> from
>> >>>>>>> math term to Swift function every time they want to look for a set
>> >>>>>>> operation method. “func invertingMembershipOfContentsOf(other:
>> Self)
>> >>>>>>> -> Self” doesn’t exactly seem to fit in the commonly held Venn
>> diagram
>> >>>>>>> mental model of set operations. You could always have a
>> documentation
>> >>>>>>> comment that specifies the mathematical term so that people didn’t
>> >>>>>>> have to double check themselves every time.
>> >>>>>>>
>> >>>>>>> That being said, if the autocomplete issue is not a concern, I’m of
>> >>>>>>> the opinion that the names Ricardo proposed are short, clear, and
>> are
>> >>>>>>> not so hard to fit to my Venn diagram mental model.
>> >>>>>>
>> >>>>>> +1
>> >>>>>>
>> >>>>>>> However, I tend to think that if there has to be this much dancing
>> to
>> >>>>>>> name a set of fundamental operations, the guidelines aren’t
>> >>>>>>> accomplishing their goal.
>> >>>>>>
>> >>>>>> I can't disagree.
>> >>>>>>
>> >>>>>>> It’s going to make it that much harder for people do design their
>> own
>> >>>>>>> APIs. I'm having quite a time trying to conform Mattt’s Surge API
>> to
>> >>>>>>> the guidelines.
>> >>>>>>
>> >>>>>> Please explain in detail.  Without details we don't know what's
>> wrong
>> >>>>>> with the guidelines.
>> >>>>>
>> >>>>> Ah, I apologize. I’ve gone into detail about this API on the list
>> >>>>> before, but I should have included the details here.
>> >>>>>
>> >>>>> Here are my previous posts:
>> >>>>>
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007560.html
>> >>>>> <
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007560.html
>> >
>> >>>>>
>> >>>>> Basically the issues come down to the following. The Accelerate
>> >>>>> framework typical operates in a non-mutating way. This means that my
>> >>>>> API only has non mutating member functions and I should use the
>> ed/ing
>> >>>>> rule according to the guidelines to name my methods.
>> >>>>>
>> >>>>> This is very difficult for some methods. I’m able to frequently get
>> >>>>> around the problem for things like “sin” or “arctan” by keeping them
>> >>>>> as global functions, but I can’t do that for a number of
>> >>>>> methods. Consider:
>> >>>>>
>> >>>>> remainder
>> >>>>> dot (returns a scalar, thus there can’t be a mutating version, so
>> >>>>> should I just call it dot? Guidelines don’t really comment on this)
>> >>>>> mean (same as above)
>> >>>>> cross
>> >>>>> reciprocal
>> >>>>> threshold
>> >>>>> copysign
>> >>>>> fastFourierTransform
>> >>>>> pow (arguably the method version should be called raisedTo)
>> >>>>>
>> >>>>> I could force all these to be global functions only, but these are
>> not
>> >>>>> as cut and dry as “sin” or “arctan”. I feel like I’d be splitting my
>> >>>>> API up into two parts just based on the fact that it’s difficult to
>> >>>>> use the ed/ing rule. That makes it very difficult for users to find
>> >>>>> certain functions in my API.
>> >>>>>
>> >>>>> In this case there are no corresponding mutating operations because
>> of
>> >>>>> the way Accelerate works, but one could certainly imagine an API with
>> >>>>> mutating counterparts. The way I read the guidelines, they seem to
>> >>>>> imply I should use ed/ing regardless of whether there is a mutating
>> >>>>> counterpart. I’d love to hear your thoughts on this.
>> >>>>
>> >>>> As long as the ones without side effects read as noun phrases and the
>> >>>> ones with side-effects read as verb phrases, you're good.  No ed/ing
>> >>>> needed.
>> >>>
>> >>> Ah yes, you are very right. Still what would the mutating versions
>> >>> of remainder, fastFourierTransform, or reciprocal be? getRemainder?
>> >>> applyFastFourierTransform? reciprocate? I suppose those aren’t so
>> >>> bad.
>> >>>
>> >>> I also suppose cross could become x.crossProduct(with: y) and
>> >>> copysign, x.copyingSign(of: y). Seems a little verbose, but it does
>> >>> the job.
>> >>>
>> >>> Thanks,
>> >>>
>> >>> Tyler
>> >>>
>> >>>
>> >>>>
>> >>>>>
>> >>>>>
>> >>>>> Thanks,
>> >>>>>
>> >>>>> Tyler
>> >>>>>
>> >>>>>>
>> >>>>>>>
>> >>>>>>> Tyler
>> >>>>>>>
>> >>>>>>>> On Feb 13, 2016, at 9:09 PM, Ricardo Parada via
>> >>>>>>>> swift-evolution
>> >>>>>>>> <swift-evolution at swift.org>
>> >>>>>>>> wrote:
>> >>>>>>>>
>> >>>>>>>> Hi Dave,
>> >>>>>>>>
>> >>>>>>>> I would be okay with staying away from the mathematical terms
>> >>>>>>>> similar to what you are suggesting except that the union can still
>> >>>>>>>> be made more concise if you use merged / merge for the base name
>> and
>> >>>>>>>> shorten the labels to a bare minimum without loosing clarity.  In
>> >>>>>>>> addition, the merge can have a second parameter with a default to
>> >>>>>>>> false in order to implement the symmetric difference
>> >>>>>>>> (a.k.a. exclusive or).  Recall that symmetric difference is the
>> >>>>>>>> union of two sets and then removing the intersection (or members
>> in
>> >>>>>>>> common).  I think it looks perfect (concise and clear).  What does
>> >>>>>>>> everybody else think?
>> >>>>>>>>
>> >>>>>>>> Non-mutable
>> >>>>>>>>
>> >>>>>>>> let union =                    a.merged(with: b)
>> >>>>>>>> let intersection =             a.members(in: b)
>> >>>>>>>> let difference =               a.removingMembers(in: b)
>> >>>>>>>> let symmetricDifference =      a.merged(with: b,
>> removingMembersInCommon: true)
>> >>>>>>>>
>> >>>>>>>> Mutable (In-Place)
>> >>>>>>>>
>> >>>>>>>> a.merge(with: b)               // union in-place
>> >>>>>>>> a.removeMembers(notIn: b)      // intersect in-place
>> >>>>>>>> a.removeMembers(in: b)         // difference in-place
>> >>>>>>>> a.merge(with: b, removeMembersInCommon: true)  // symmetric
>> difference in-place
>> >>>>>>>>
>> >>>>>>>> Ricardo Parada
>> >>>>>>>>
>> >>>>>>>>
>> >>>>>>>>> On Feb 13, 2016, at 1:16 PM, Dave Abrahams via swift-evolution
>> >>>>>>>>> <swift-evolution at swift.org
>> >>>>>>>>> <mailto:swift-evolution at swift.org>>
>> >>>>>>>>> wrote:
>> >>>>>>>>>
>> >>>>>>>>>
>> >>>>>>>>> on Fri Feb 12 2016, Ricardo Parada <swift-evolution at swift.org
>> >>>>>>>>> <mailto:swift-evolution at swift.org>> wrote:
>> >>>>>>>>>
>> >>>>>>>>>> Hi all,
>> >>>>>>>>>>
>> >>>>>>>>>> I can’t make up my mind.  Let me propose two different
>> alternatives
>> >>>>>>>>>> that I’m not sure if they have been considered:
>> >>>>>>>>>>
>> >>>>>>>>>> ALTERNATIVE 1
>> >>>>>>>>>>
>> >>>>>>>>>> Non-mutable (noun-based)
>> >>>>>>>>>>
>> >>>>>>>>>> -  func union(other: Self) -> Self
>> >>>>>>>>>> +  func union(other: Self) -> Self           Assumes union is a
>> noun, i.e. not a verb
>> >>>>>>>>>>
>> >>>>>>>>>> -  func intersect(other: Self) -> Self
>> >>>>>>>>>> +  func intersection(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> -  func subtract(other: Self) -> Self
>> >>>>>>>>>> +  func subtraction(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> -  func exclusiveOr(other: Self) -> Self
>> >>>>>>>>>> +  func symmetricSubtraction(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> Mutable (verb-based)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func unionInPlace(other: Self)
>> >>>>>>>>>> +  mutating func unite(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func intersectInPlace(other: Self)
>> >>>>>>>>>> +  mutating func intersect(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func subtractInPlace(other: Self)
>> >>>>>>>>>> +  mutating func subtract(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func exclusiveOrInPlace(other: Self)
>> >>>>>>>>>> +  mutating func symmetricSubtract(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> Comments:
>> >>>>>>>>>>
>> >>>>>>>>>> With this alternative we keep the union name which I assume is
>> >>>>>>>>>> popular.  However, one has to accept unite as a verb (for the
>> mutable
>> >>>>>>>>>> version) as I wanted all the mutable methods use verbs for
>> >>>>>>>>>> consistency.  I think unite is acceptable because it can be
>> found in
>> >>>>>>>>>> the dictionary and it is a verb.
>> >>>>>>>>>>
>> >>>>>>>>>> Notice that all the non-mutable methods use nouns: union,
>> >>>>>>>>>> intersection, subtraction and symmetricSubtraction.
>> >>>>>>>>>>
>> >>>>>>>>>> I understand some may oppose to symmetricSubtraction saying that
>> >>>>>>>>>> symmetricSubraction is not as common as "exclusive or".
>> However,
>> >>>>>>>>>> using symmetricSubtraction is consistent with subtraction and
>> it hints
>> >>>>>>>>>> to a variation of the “subtraction" operation.  We will get
>> used to it
>> >>>>>>>>>> quickly / easily.
>> >>>>>>>>>>
>> >>>>>>>>>> The mutable methods all use verbs:  unite, intersect, subtract
>> and symmetricSubtract.
>> >>>>>>>>>>
>> >>>>>>>>>> ALTERNATIVE 2
>> >>>>>>>>>>
>> >>>>>>>>>> Non-mutable
>> >>>>>>>>>>
>> >>>>>>>>>> -  func union(other: Self) -> Self
>> >>>>>>>>>> +  func adding(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> -  func intersect(other: Self) -> Self
>> >>>>>>>>>> +  func intersecting(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> -  func exclusiveOr(other: Self) -> Self
>> >>>>>>>>>> +  func exclusiveOring(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> -  func subtract(other: Self) -> Self
>> >>>>>>>>>> +  func removing(other: Self) -> Self
>> >>>>>>>>>>
>> >>>>>>>>>> Mutable
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func unionInPlace(other: Self)
>> >>>>>>>>>> +  mutating func add(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func intersectInPlace(other: Self)
>> >>>>>>>>>> +  mutating func intersect(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func exclusiveOrInPlace(other: Self)
>> >>>>>>>>>> +  mutating func exclusiveOr(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> -  mutating func subtractInPlace(other: Self)
>> >>>>>>>>>> +  mutating func remove(other: Self)
>> >>>>>>>>>>
>> >>>>>>>>>> Comments: This alternative gives up on union in favor or add.
>> Many
>> >>>>>>>>>> may not like this, that is why I have it as the second
>> alternative.
>> >>>>>>>>>> It brings back exclusiveOr and treats it as a verb.  Some may
>> argue
>> >>>>>>>>>> that exclusiveOr is a noun for the "exclusive or" operation.
>> >>>>>>>>>
>> >>>>>>>>> If we are going to force Set fit the naming guidelines, I would
>> prefer
>> >>>>>>>>> to stay away from the mathematical terms altogether.
>> >>>>>>>>>
>> >>>>>>>>> func insertingContentsOf(other: Self) -> Self                 //
>> union
>> >>>>>>>>> mutating func insertContentsOf(other)
>> >>>>>>>>>
>> >>>>>>>>> func members(in other: Self) -> Self
>>  // intersection
>> >>>>>>>>> mutating func removeMembers(notIn: other)
>> >>>>>>>>>
>> >>>>>>>>> func removingMembersAndAddingNonMembers(in other: Self) -> Self
>> // symmetric difference
>> >>>>>>>>> mutating func removeMembersAndAddingNonMembers(in other: Self)
>> >>>>>>>>>
>> >>>>>>>>> func removingMembers(in other: Self) -> Self
>> // subtract
>> >>>>>>>>> mutating func removeMembers(in other: Self)
>> >>>>>>>>>
>> >>>>>>>>> If it would help with clarity, we could replace "in" with
>> "foundIn"
>> >>>>>>>>> above.
>> >>>>>>>>>
>> >>>>>>>>> --
>> >>>>>>>>> -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>
>> >>>>>>>> _______________________________________________
>> >>>>>>>> swift-evolution mailing list
>> >>>>>>>> swift-evolution at swift.org
>> >>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >>>>>>
>> >>>>>> --
>> >>>>>> -Dave
>> >>>>
>> >>>> --
>> >>>> -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
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> --
>> -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
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
-Dave



More information about the swift-evolution mailing list