tc39 / proposal-set-methods

Proposal for new Set methods in JS
https://tc39.github.io/proposal-set-methods/
Other
659 stars 15 forks source link

Method names should pick a theme #24

Closed domenic closed 5 years ago

domenic commented 6 years ago

This is a continuation of https://github.com/tc39/proposal-set-methods/issues/20#issuecomment-368317865.

Currently, according to the recently closed issues (but not according to the readme??) we have the following "themes" chosen for method names:

I think we shouldn't mix and match:

bakkot commented 6 years ago

Some prior art:

Edit, 2018-05-03: adding some less common languages for completeness. Note that I'm only including languages which have a built-in way of performing symmetric difference which doesn't need to be composed from parts.

c69 commented 6 years ago

I think the pattern is pretty clear 🤓 "Be like everyone else, or be like Java".

Clojure and Scala also follow the same pattern:

gsathya commented 6 years ago

I agree that it'd be nice to pick a theme and stick to it.

I think there's a lot of value in aligning with mainstream languages as it's easier for a developer to transition between languages. I'd be +1 on just going with the set theoretic names, even though the names aren't quite ergonomic.

tabatkins commented 6 years ago

Sigh. In my ten years of spec-dev, I've learned that precedent is extremely important; it's often much better to go with a familiar solution over a slightly more optimal but brand-new one. I've also been pretty consistent in JS with my "just do it like Python does" position. ^_^ But this is the rare case where I think following those principles gives a bad enough result that it's worth violating them.

union and intersection are okay; intersection is a bit long, but it's fine. difference doesn't communicate the directionality well enough; its use in English doesn't carry a directionality. symmetricDifference is both incredibly long (19 characters!) and contains a hard-to-spell word; its only benefit is that we no longer care about the directionality of the operation.

Sure, Python used these names (and with an _, making it 20 characters!), but in my experience using sets, I have never written out a.symmetric_difference(b), because a ^ set(b) is so much easier to write. In other words, Python is cheating, by having everything use single-char ops; the only reason to use the named methods is if you want the second argument to be an arbitrary iterable, and don't feel like manually casting it. Thus the ergonomics of the names don't have much of an effect actually.


I agree that having a consistent naming theme is useful, tho, so I suggest we just go with the bitwise names. Python is also precedent for this; they just spell them as operators rather than as names. and/or/minus/xor are all short and easy to understand, and minus in particular has the correct directionality built in from the English meaning.

(I personally occasionally stumble with and, thinking it means "the elements of A and B", aka or, but then just remember how the & operator works. Nothing's perfect, shrug.)

zloirock commented 6 years ago

In other words, Python is cheating, by having everything use single-char ops

Maybe makes sense add availability to override binary math ops? For example, add Symbol.xor (or Symbol.symmetricDifference), on binary bitwise operators evalation, before converting the left arg to int32 check is this object or not, if it's an object try to get @@xor property and it's exists convert a ^ b to a[Symbol.xor].call(a, b)?

tabatkins commented 6 years ago

Note: I am absolutely not suggesting that we do anything like add new operator semantics. My point is just that Python gives the operations two names - a long logical-operation name as a method, and a very short bitwise-op name as an operator. So saying that Python only provides logical-op as a precedent is incorrect; it also provides a bitwise-op precedent for naming the operations. In JS we'd just use the names of the bitwise ops, rather than their operator forms, precisely because we don't have operator overloading.

gsathya commented 6 years ago

Operator overloading is definitely out of scope for this proposal. I'd like to keep this discussion focused on picking a good name for the set methods.

zloirock commented 6 years ago

It's just a thought out loud -)

thlorenz commented 6 years ago

I knew immediately what union, intersection, difference meant in context of a set (not sure about symmetricDifference).

However or, and, minus, xor I'd have to look up (or at least think about) every time I'd use them since those are not terms I'm familiar with (in context with a set) even though they make sense if you think on set item level.

So I'd go with union, intersection, difference (or slight naming variations on those).

jhonnymoreira commented 6 years ago

union, intersection, difference, symmetricDifference.

mariusGundersen commented 6 years ago

union, intersection and symmetricDifference are all symmetric, in that changing the order of the operands doesn't change the result. For difference it does, yet the common English usage of the word 'difference' is the symmetrical one. Therefore I don't think difference is the right method name for this non-symmetrical operation, and I think a non-symmetrical word like except, while not in a clear theme, would be better. It clearly indicates that the result will depend on the order of the operands.

victusfate commented 6 years ago

I'd follow Python and ruby conventions

c69 commented 6 years ago

Maybe offtopic, but if you use TypeScript and IDE with sensible autocomplete - the length of method name matters a lot less.

union, intersection, difference, symmetricDifference are thus easily distinguishable one from each other (as even their first letter is different). Plus such naming has precedence in both Python and C++.

As for Python (and Ruby, and Scala) "cheating" - well one more reason to consider operator overloading (outside of this proposal, of course). So that JS will learn to cheat too ;)

mathiasbynens commented 6 years ago

.and() is ambiguous: it could be interpreted to mean either union (“all the elements in A and all the elements in B”) or intersection (“elements in A and in B”), depending on how you look at it.

symmetricDifference is not the easiest method name to type, but it has precedent in set theory and other programming languages. I don’t think this one unfortunate name is a good reason to switch to bitwise names.

Ginden commented 6 years ago

Well, union and intersection are pretty obvious. or and and are rarely used in this context.

Arguments raised against symmetricDifference is its length, though, majority agrees on it, so I will change proposal today.

I'm still concerned with difference (it lacks directionality, is long name for common operation) and I'm in favor of following .NET here - .except is obvious in it's meaning and directionality.

tabatkins commented 6 years ago

Proposal for another theme: inEither, inBoth, notIn, notInBoth

Short, simple, English meaning immediately accords with technical meaning, the one directional operation reads properly (A.notIn(B)). No precedent, but I've already argued for the badness of the existing precedent. ^_^


(I'm fine with union and intersect; if paired with subtract and symDiff my concerns are mollified.)

gsathya commented 6 years ago

I'm still concerned with difference (it lacks directionality, is long name for common operation) and I'm in favor of following .NET here - .except is obvious in it's meaning and directionality.

If we're going with symmetricDifference, it seems surprisingly inconsistent to not use difference.

SeregPie commented 6 years ago

All js functions already follow a theme. Look at the array functions. They are all verbs. So it makes more sense to use union, intersect and diff.

tabatkins commented 6 years ago

"union" can be either a verb or noun, and "intersect" (the verb) is shorter than "intersection"; this suggests that using verbs might be a win.

gsathya commented 5 years ago

We discussed this in length at the TC39 meeting in [May]. While we acknowledge that symmetricDifference is a terrible name, there is substantial amount of precedence in other languages helping consistency across languages. There's also significant community feedback (based on this thread) that this sort of set theoretic naming is preferred.

We considered the alternatives proposed here and didn't find them to be better than the set theoretic names (for reasons listed in this thread, for example, and is too ambiguous).

I'm going to close this out as I think we've discussed most of the alternatives and haven't been convinced that these are better. Please comment if you have an alternative that's better than the ones discussed.

Rudxain commented 3 months ago

length of method name matters a lot less.

We shouldn't forget about minification. Although one might argue "just use Wasm", which is a fair (and maybe even solid) point, as all run-times that will support these methods will already support Wasm