Yes. Logical completeness is definitely necessary for operators to be useful.
the first operand should not need ||/&&, if anything I'd want to read...
I definitely understand the appeal, but grammar needs to be consistent, not contextual.
What do these mean?
if( ( a === b ) ||=== c ||== d === e || === f ) ...
// ^Syntax error? Compare to a?
if( a === b ||=== c ||=== d === e ||=== f ) ...
// ^What is this? d===e? Does d compare to f?
// Or does ( a === ... ||=== d ) compare to f???
You could arbitrarily decide in the spec that they mean one thing or another. That would be bad.
Inconsistent grammar makes hard-to-read situations.
But the point is: The moment you encounter your first ||===, you know that the fully evaluated value immediately to its left is the subject being compared in the list to follow. No glancing back further to the left or glancing up a line while realizing you misinterpreted the operator you looked at a second ago.
A chaining comparison operator takes the result of evaluating its left-hand-side expression and compares it to the result of evaluating every chaining-operator-delimited expression in the subsequent list.
That's also the most straight-forward way to code an algorithm for it, so it makes the most sense to me, at least.
Yes. And the fact that you can't imagine a particular scenario in which you would need it is meaningless. In order for a logical processor to be useful, it must be complete.
(In this case, &&!=== is much more obviously useful. But you need the complete set.)
I don't understand the question. Chaining operators are rare, but equality operators are always complete. Why would you add an incomplete set of chaining operators. Can you give me an example of a language that, for example, allows OR operators, but not AND operators?
Just an idea to make this more generic, and to prevent the confusion with chained operators: These operators could work like the for-of loop, i.e. they are binary operators expecting an iterable at the right side.
x === "a" || x === "b" || x === c"
x ||=== ["a", "b", "c"]
which then could also be used to check for a value in native maps:
x ||=== map.values()
Of course, this seems to make the operator quite useless once we have iterator helpers
["a", "b", "c"].includes(x)
map.values().some(v => v === x)