# Operators: ||==, ||===

**URL:** <https://es.discourse.group/t/operators/1577>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [January 1, 2023, 7:59pm UTC](https://es.discourse.group/t/operators/1577 "2023-01-01T19:59:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 1, 2023, 8:00pm UTC](https://es.discourse.group/t/operators/1577/1 "2023-01-01T20:00:00Z")

</div>

Could we use chaining comparison operators?

Multiple comparisons:

```plaintext
if( a === "first-comparison" || a === "second-comparison" || a === "third-comparison )
    ...

```

Chained comparisons:

```plaintext
if( a ||=== "first-comparison ||=== "second-comparison" ||=== "third-comparison" )
    ...

```

The same syntax would work for &&.

This is such a common issue that I assume it has already been proposed and rejected, but I couldn't find the conversation.

The stack overflow question is 10 years old with 100k views.

> <https://stackoverflow.com/questions/9121395/whats-the-prettiest-way-to-compare-one-value-against-multiple-values>

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [January 1, 2023, 9:40pm UTC](https://es.discourse.group/t/operators/1577/2 "2023-01-01T21:40:57Z")

</div>

Could this syntax be confusing with how it is different to the existing `||=` operator?

> **[Logical OR assignment (||=) - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment)**
>
> The logical OR assignment (x ||= y) operator only assigns if x is falsy.

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 1, 2023, 9:52pm UTC](https://es.discourse.group/t/operators/1577/3 "2023-01-01T21:52:34Z")

</div>

It is a different operator. I don't confuse + with ++, so personally, I don't expect any issues with confusion.

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [January 1, 2023, 11:38pm UTC](https://es.discourse.group/t/operators/1577/4 "2023-01-01T23:38:25Z")

</div>

I found some related threads:

> [@Comparison to multiple values syntactic sugar](https://es.discourse.group/t/comparison-to-multiple-values-syntactic-sugar/357):
>
> In ECMA I would use (variable === val1 || variable === val2 ...) to attempt to compare a variable to multiple values. I think it would be a lot more elegant to run variable === | val1, val 2 | and have it automatically expand.

[Chained comparison syntax](https://es.discourse.group/t/chained-comparison-syntax/148) (No replies)

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 2, 2023, 12:27am UTC](https://es.discourse.group/t/operators/1577/5 "2023-01-02T00:27:34Z")

</div>

That was (rightly) rejected because:

- The syntax: `| val1, val2 |` is ambiguous. It makes |'s interpretation dependent on its context. (Chained comparisons in Python are similarly ambiguous; hard to read.)
- By grouping comparison targets into a list, `| val1, val2 |` , you are forced to do 1 operation on the entire list.

Chained comparisons like `||===` are lexically unambiguous. Presently, every single one will generate a syntax error. They can chain any sequence of logical comparisons.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [January 2, 2023, 4:26am UTC](https://es.discourse.group/t/operators/1577/6 "2023-01-02T04:26:24Z")

</div>

Would you also suggest to make

```javascript
if (a !== "first-comparison" && a !== "second-comparison" && a !== "third-comparison) …

```

into

```javascript
if (a &&!== "first-comparison" &&!== "second-comparison" &&!== "third-comparison") …

```

?

Btw the first operand should not need `||`/`&&`, if anything I'd want to read

```javascript
if (a === "first-comparison" ||=== "second-comparison" ||=== "third-comparison") …
if (a !== "first-comparison" &&!== "second-comparison" &&!== "third-comparison") …

```

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 2, 2023, 9:43pm UTC](https://es.discourse.group/t/operators/1577/7 "2023-01-02T21:43:46Z")

</div>

> Would you also suggest to make...

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?

```javascript
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 all is not lost! Look at this. :-)

```javascript
if( valueToCompare
    ||=== condition1
    ||=== condition2
    ||=== condition3 )

```

I like it, anyway.

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.

---

<div class="post-metadata">

**Author:** ![yukulele](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yukulele/32/1519_2.png) [@yukulele](https://es.discourse.group/u/yukulele)\
**Post date:** [January 15, 2023, 6:37pm UTC](https://es.discourse.group/t/operators/1577/8 "2023-01-15T18:37:23Z")

</div>

Is `array.includes()` an option?

```javascript
if (["first-comparison", "second-comparison", "third-comparison"].includes(a)) {
  // ...
}
```

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 15, 2023, 8:04pm UTC](https://es.discourse.group/t/operators/1577/9 "2023-01-15T20:04:32Z")

</div>

No, for the same reason the |...| syntax is useless.  
`a ||=== b ||=== c &&=== d` cannot be computed using any array functions like `find()` `includes()` or `reduce()`.

```javascript
if( a ||=== b ||=== c &&=== d )
if( ( ( a === b ) || ( a === c ) ) && ( a === d ) )

```

---

<div class="post-metadata">

**Author:** ![yukulele](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yukulele/32/1519_2.png) [@yukulele](https://es.discourse.group/u/yukulele)\
**Post date:** [January 15, 2023, 8:39pm UTC](https://es.discourse.group/t/operators/1577/10 "2023-01-15T20:39:38Z")

</div>

I'm not sure I understand the purpose of `&&===`,

```javascript
a &&=== b &&=== c

```

in which case `a` can be both equal to `b` and `c`?

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 15, 2023, 8:51pm UTC](https://es.discourse.group/t/operators/1577/11 "2023-01-15T20:51:04Z")

</div>

Yes. It's the same as the purpose of &&. Without it, you can't write logical statements.

---

<div class="post-metadata">

**Author:** ![yukulele](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yukulele/32/1519_2.png) [@yukulele](https://es.discourse.group/u/yukulele)\
**Post date:** [January 15, 2023, 9:09pm UTC](https://es.discourse.group/t/operators/1577/12 "2023-01-15T21:09:54Z")

</div>

in which case `a` can be both equal to `b` and `c`?

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 15, 2023, 9:15pm UTC](https://es.discourse.group/t/operators/1577/13 "2023-01-15T21:15:10Z")

</div>

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.)

---

<div class="post-metadata">

**Author:** ![yukulele](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yukulele/32/1519_2.png) [@yukulele](https://es.discourse.group/u/yukulele)\
**Post date:** [January 15, 2023, 9:21pm UTC](https://es.discourse.group/t/operators/1577/14 "2023-01-15T21:21:10Z")

</div>

I understand

- `||===` and
- `&&!===`

but

- `&&===` and
- `||!===`

seem usless

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [January 15, 2023, 9:57pm UTC](https://es.discourse.group/t/operators/1577/15 "2023-01-15T21:57:29Z")

</div>

You assert that one needs the complete set - can you share examples of prior art? other languages that have added a more "complete set" of equality syntax and how that works?

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 15, 2023, 10:11pm UTC](https://es.discourse.group/t/operators/1577/16 "2023-01-15T22:11:15Z")

</div>

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?

By which I mean: If chaining operators are to be added at all, they should be a complete set. I do not mean to imply that logic operators in JavaScript are incomplete and could be "more" complete. (I would have very serious programming problems if they were incomplete.)

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 15, 2023, 10:23pm UTC](https://es.discourse.group/t/operators/1577/17 "2023-01-15T22:23:10Z")

</div>

Here are examples.

&&===

```javascript
if( targetIndex &&=== currentIndex &&=== 0 )
if( ( targetIndex === currentIndex ) && ( targetIndex === 0 ) )
    //do not re-seek current index, already there
    //do not decrement, at beginning of memory

```

||!===

```javascript
if( color ||=== transparent ||!=== clipColor )
if( ( color === transparent ) || ( color !== clipColor ) )
    //do not blit, color clipped or NOOP

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [January 15, 2023, 11:37pm UTC](https://es.discourse.group/t/operators/1577/18 "2023-01-15T23:37:33Z")

</div>

I'm referring to chaining operators, yes. `||=` and `&&=` aren't "chaining operators", they're a combination of a single operator, and assignment.

---

<div class="post-metadata">

**Author:** ![daniel.rentz](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/daniel.rentz/32/1946_2.png) [@daniel.rentz](https://es.discourse.group/u/daniel.rentz)\
**Post date:** [January 16, 2023, 5:23am UTC](https://es.discourse.group/t/operators/1577/19 "2023-01-16T05:23:37Z")

</div>

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.

```plaintext
x === "a" || x === "b" || x === c"

```

becomes

```plaintext
x ||=== ["a", "b", "c"]

```

which then could also be used to check for a _value_ in native maps:

```plaintext
x ||=== map.values()

```

Of course, this seems to make the operator quite useless once we have iterator helpers

```plaintext
["a", "b", "c"].includes(x)
map.values().some(v => v === x)

```

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [January 16, 2023, 9:57pm UTC](https://es.discourse.group/t/operators/1577/20 "2023-01-16T21:57:42Z")

</div>

As I and others have repeatedly said, that syntax forces you to use a single operator.

The simple comparison:

```javascript
if( value ||=== allowed1 ||=== allowed2 &&!=== forbidden )

```

Is impossible with a syntax that uses a list. (This kind of comparison is also impossible using any of the existing boolean-capable array functions like `includes()`, `reduce()`, and `find()`.)

[Next page](https://es.discourse.group/t/operators/1577.md?page=2)
