# Unions

**URL:** <https://es.discourse.group/t/unions/993>\
**Category:** 💡 Ideas\
**Created:** [September 23, 2021, 2:40pm UTC](https://es.discourse.group/t/unions/993 "2021-09-23T14:40:45Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [September 23, 2021, 2:40pm UTC](https://es.discourse.group/t/unions/993/1 "2021-09-23T14:40:46Z")

</div>

Hi,

When I started programming this made a lot of sense to me...

```javascript
if (foo && bar && baz === 1) {
  // ...
}

```

At first glance, we read it as "if `foo` and `bar` and `baz` are `1` then do this". Unfortunately, that's not how things work.

To implement this logic we need to do...

```javascript
if (foo === 1 && bar === 1 && baz === 1) {
  // ...
}

```

I propose a way to do something like the first example using what I call "unions".

## Logical AND Union

```javascript
foo ~& bar ~& baz === 1

```

## Logical OR Union

```javascript
foo ~| bar ~| baz === 1

```

## Side Notes

- Unions can't be used as stand-alone expressions, they can only get along with comparison operators.

- Unions are just syntactic sugars over my second example.

- I used `~&` instead of just `&` because who-knows-why they're valid JS.

Let me know what you think 😊

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [September 23, 2021, 3:58pm UTC](https://es.discourse.group/t/unions/993/2 "2021-09-23T15:58:02Z")

</div>

I agree - that's certainly an easy place for beginners to trip up on.

I'll point out another possible solution.

For the "~|" syntax, the python language does this instead, which I know some people like:

```python
1 in [foo, bar, baz]

```

Currently, in JavaScript, you can do `[foo, bar, baz].includes(1)` to get similar behavior.

I remember seeing another thread floating around, proposing to add an "of" operator that's pretty much a shorthand for `.includes()` - but I can't remember where it is.

None of this really helps to solve the "~&" case. For that scenario, it might feel more natural to be able to write something like `a === b === c` - this is also a syntax with python supports - it's too late to support that in Javascript though, because it already has a different meaning.

---

<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:** [September 23, 2021, 4:37pm UTC](https://es.discourse.group/t/unions/993/3 "2021-09-23T16:37:51Z")

</div>

Is there another language where comparisons work this way that informed your expectation?

The similar behavior would be `[foo, bar, baz].every(x => x === 1)`, to ensure that all three of them were 1.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [September 23, 2021, 5:02pm UTC](https://es.discourse.group/t/unions/993/4 "2021-09-23T17:02:39Z")

</div>

> [@ljharb](#):
>
> Is there another language where comparisons work this way that informed your expectation?

English :)

From my experience tutoring people who are just starting out, this is actually a common source of confusion. I've seen many people try to do exactly what the O.P. described to check if a specific element is X or Y.

When they try to do that, they just need to be taught to decompose their condition - instead of doing "a === b || c", they need to do "a === b || a === c". I'm not sure how much it would help to add a new ~| operator - it's still very possible that we go through the same process. They try to do "a === b || c", and they've got to learn to switch to the "~|" operator in this specific case.

---

<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:** [September 23, 2021, 5:14pm UTC](https://es.discourse.group/t/unions/993/5 "2021-09-23T17:14:46Z")

</div>

ha, fair, but i meant programming language :-p

In other words, I agree this is an assumption from natural language, but if it's one that every programmer has had to learn, then it'd be great to look into whether other languages have tried to mitigate this specific issue or not. If not, it's a strong argument that such mitigation isn't needed; if so, that might help inform what to consider for JS.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [September 23, 2021, 5:33pm UTC](https://es.discourse.group/t/unions/993/6 "2021-09-23T17:33:29Z")

</div>

Well, I don't know of any programming languages that try to solve this.

I also think it's not an easy problem to solve (unless you do introduce two separate operators). This is simply because in English, "or" can really mean two different things, and what it means depends on context. Programming language can't be sensitive to context the same way (or, at least they shouldn't try to magically understand context).

So, perhaps that's why no languages (that I know of) have tried to hard to resolve this. The closet thing I can think of is the python "in" operator and the fact that you're allowed to do "x == y == z". Both of those features provide syntax to use the other form of "and" and "or" that languages don't directly support, without literally creating a second "and" and "or" operator.

It's too late to do the equal thing in JavaScript, but we certainly could add `x of ['a', 'b']` if we wanted to (I don't have strong feelings for or against syntax like that). That sort of syntax provides a more natural outlet to express one's self, in a way that's closer to English. But, it's not like `['a', 'b'].includes('x')` doesn't read like English either.

---

<div class="post-metadata">

**Author:** ![jmdyck](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jmdyck/32/796_2.png) [@jmdyck](https://es.discourse.group/u/jmdyck)\
**Post date:** [September 23, 2021, 5:37pm UTC](https://es.discourse.group/t/unions/993/7 "2021-09-23T17:37:27Z")

</div>

Perl 6 has "junctions", which (if I've got this right) allow you to say (e.g.)

```javascript
if all($foo, $bar, $baz) == 1 {...}

```

or maybe even

```javascript
if $foo & $bar & $baz == 1 {...}

```

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [September 23, 2021, 5:41pm UTC](https://es.discourse.group/t/unions/993/8 "2021-09-23T17:41:08Z")

</div>

Huh. Interesting.

I think that first scenario might actually be possible to recreate in userland with the operator overloading proposal. Provide an all() function that returns a special object that has `===` overloaded on it.

---

<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:** [September 23, 2021, 5:52pm UTC](https://es.discourse.group/t/unions/993/9 "2021-09-23T17:52:08Z")

</div>

Pretty sure equality can’t ever be overrideable, even in that proposal.

However, you could return a distinct symbol or object whenever all three weren’t equivalent, ensuring that comparing to it would always fail unless all three were the same.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [September 23, 2021, 6:17pm UTC](https://es.discourse.group/t/unions/993/10 "2021-09-23T18:17:39Z")

</div>

Ah, you're right. `===` can't be overloaded, but `==` can.

> **[GitHub - tc39/proposal-operator-overloading](https://github.com/tc39/proposal-operator-overloading#using-operators)**
>
> Contribute to tc39/proposal-operator-overloading development by creating an account on GitHub.

---

<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:** [September 23, 2021, 7:42pm UTC](https://es.discourse.group/t/unions/993/11 "2021-09-23T19:42:03Z")

</div>

I like Python’s approach a lot.

> **[Chaining comparison operators in Python - GeeksforGeeks](https://www.geeksforgeeks.org/chaining-comparison-operators-python/amp/)**
>
> A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

`a == b == c`

Means they all equal each other, it’s not 2 binary expressions that return booleans

---

<div class="post-metadata">

**Author:** ![DiriectorDoc](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/diriectordoc/32/987_2.png) [@DiriectorDoc](https://es.discourse.group/u/DiriectorDoc)\
**Post date:** [September 27, 2021, 9:09pm UTC](https://es.discourse.group/t/unions/993/12 "2021-09-27T21:09:12Z")

</div>

Could this also be expanded to less-than/greater than? Perhaps something along the lines of:

```javascript
if ( 0 ~< 1 ~< 2 ) // true

```

In Python, you can just do `0 < 1 < 2` and it just works. I was thinking about something similar that would work with JS.

---

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [October 6, 2021, 3:33pm UTC](https://es.discourse.group/t/unions/993/13 "2021-10-06T15:33:06Z")

</div>

> [@aclaymore](#):
>
> I like Python’s approach a lot.

Me too.

@theScottyJam, I didn't mean this just for beginners. I feel there are real use cases for this, where we can introduce this syntax to improve readability.

We can use the logical `OR` when we need to...

- validate multiple choice fields in a form,
- do union type checking

And logical `AND` when we need to...

- to check if a participant has a reserved name in a meeting (if we know the reserved name ahead of time, of course)

> [@theScottyJam](#):
>
> None of this really helps to solve the "~&" case.

Actually, I've found that we can achieve the same thing as my first example using this.

```javascript
(foo & bar & baz) === 1

```

> [@theScottyJam](#):
>
> I remember seeing another thread floating around, proposing to add an "of" operator that's pretty much a shorthand for `.includes()` - but I can't remember where it is.

I like the "`of`" thingy. But I feel unions are more powerful, as we are not limited to using just `===`. We can use absolutely any comparison operator. Like here...

```javascript
foo ~| bar > 18

```

We could use `some` instead of this (`every` for `~&`). But I find them more verbose.

```javascript
[foo, bar].some((i) => i > 5)

```

There are places where we can only use "`of`", like...

```javascript
if (username of usernames) print("Reserved :(")

```

So I think both proposals can co-exist, and serve different purposes :)

> [@DiriectorDoc](#):
>
> Could this also be expanded to less-than/greater than?

It looks like a good idea, but that would be a totally different syntax. Also, if we were to allow that, we'll need to do the same for all the other comparison operators. Besides unions can only be used for logical operators. They are used in combo with comparison operators.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [October 6, 2021, 4:16pm UTC](https://es.discourse.group/t/unions/993/14 "2021-10-06T16:16:43Z")

</div>

> [@ethanlal04](#):
>
> I like the "`of`" thingy. But I feel unions are more powerful, as we are not limited to using just `===`. We can use absolutely any comparison operator. Like here...
> 
> `foo ~| bar > 18`

I find the examples with `~|` and `~&` a bit confusing. It's subjective, but the `~|` evokes some kind of operation/relation between `foo` and `bar`, which is not the case, you're treating them independently.  
I'd be more comfortable with a wordy syntax, like

```javascript
if (all of (foo, bar) > 18) ...
if (any of (foo, bar) < 21) ...

```

(this imo better conveys the values are independent, and that the whole thing can short-circuit)

---

<div class="post-metadata">

**Author:** ![jithujoshyjy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jithujoshyjy/32/399_2.png) [@jithujoshyjy](https://es.discourse.group/u/jithujoshyjy)\
**Post date:** [October 7, 2021, 10:00am UTC](https://es.discourse.group/t/unions/993/15 "2021-10-07T10:00:19Z")

</div>

How about a syntax like in Julia:  
[foo, bar, baz] .=== 1

---

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [October 7, 2021, 2:25pm UTC](https://es.discourse.group/t/unions/993/16 "2021-10-07T14:25:50Z")

</div>

@jithujoshyjy, I don't know Julia much, so, does it behave like `~|` or `~&`?

---

<div class="post-metadata">

**Author:** ![jithujoshyjy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jithujoshyjy/32/399_2.png) [@jithujoshyjy](https://es.discourse.group/u/jithujoshyjy)\
**Post date:** [October 7, 2021, 2:56pm UTC](https://es.discourse.group/t/unions/993/17 "2021-10-07T14:56:04Z")

</div>

There are these really interesting things called vectorized operators in Julia:  
syntax:  
.`<operator>`  
eg:  
.+  
.-  
.\*  
.etc  
They apply the operation on every element of an array.  
so [foo, bar, baz] .=== 1  
[foo === 1, bar === 1, baz === 1]  
might not be what you've asked for; I just wanted to drop this in.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [October 7, 2021, 7:25pm UTC](https://es.discourse.group/t/unions/993/18 "2021-10-07T19:25:44Z")

</div>

That could work, but then we'd be left with an array of booleans, which we would still need to consolidate into a single boolean by doing `.every()` or `.some()` afterwards.

e.g. it would look like this:

```javascript
([foo, bar, baz] .=== 1).every(x => x)

```

Which isn't really better from this:

```javascript
[foo, bar, baz].every(x => x === 1)

```
