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

Howard Lovatt howard.lovatt at gmail.com
Sun Feb 14 18:53:20 CST 2016


I think the reason why the mathematical names look strange is that in
mathematics they are used differently; either they are functions instead of
methods or they are operators, e.g.:

    sin(x)

not:

    x.sin()

Similarly:

    both = first ∪ second

Not:

    both = first.union(second)

Therefore I think mathematical names require either special treatment or
just getting used to a different convention. I would suggest getting use to
a different convention; i.e.using the same naming convention as sort etc.,
e.g.:

    first.union(second) // In place replacement of first with the union of
first and second
    both = first.unioned(second) // both = the union of first and second

  -- Howard.

On 15 February 2016 at 08:37, Xiaodi Wu via swift-evolution <
swift-evolution at swift.org> wrote:

> 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
>> <http://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
>> <http://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
>> <swift-evolution at swift.org>>>
>> wrote:
>>
>>
>> on Fri Feb 12 2016, Ricardo Parada <swift-evolution at swift.org
>> <mailto:swift-evolution at swift.org <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
>> <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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160215/4843fc64/attachment.html>


More information about the swift-evolution mailing list