Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

Symmetric operator? #4

Closed
hax opened this issue Jul 25, 2017 · 9 comments
Closed

Symmetric operator? #4

hax opened this issue Jul 25, 2017 · 9 comments

Comments

@hax
Copy link
Member

hax commented Jul 25, 2017

?? op: a ?? b => a != null ? a : b

We may also introduce a symmetric operator:

?! op: a ?! b => a == null ? a : b

Sometimes I saw code like that: a && f(a), f1() && f2() && f3() which seems fit ?! op. But I'm not sure whether it is useful enough.

@ljharb
Copy link
Member

ljharb commented Jul 25, 2017

That code seems to be using short-circuiting, and not the return value - can you elaborate more on the use case of it, besides simply being a negated form?

@hax
Copy link
Member Author

hax commented Jul 25, 2017

@ljharb Yes the negated form is just drop the non-null value, that's why I'm not sure whether it's useful. I just list it here for others can check the idea :-)

@claudepache
Copy link

Useless. Just use optional bind on identity. (Except your nulls will become undefined, but well):

a?::(_=>_)(b)

=>[]

@tvald
Copy link

tvald commented Aug 8, 2017

x && foo is a guard pattern. There could be a use for this symmetric operator when you want to distinguish a falsy value (eg, 0) from a nullish value.

function foo(x: int) { }
function bar(y?: int) {
  y != null && foo(y)
  // vs
  y ?! foo(y)
}

@ljharb
Copy link
Member

ljharb commented Aug 10, 2017

@tvald can you provide some more concrete code (without non-JavaScript notation) that explains this use case?

If we can all only think of "there might be a use case" then that means there probably isn't yet a use case we need to worry about.

@tvald
Copy link

tvald commented Aug 11, 2017

NB: I'm not advocating for the implementation of a nullish-guard operator. I do think understanding what nullish-guard is clarifies the space in which optional-chaining and nullish-coalesce exist. (And helps future-proof them.)

function foo(options) {
const maybeCallback = options.callback;

// if statement
if (maybeCallback != null) maybeCallback();

// nullish-guard
maybeCallback ?& maybeCallback();

// optional-chaining
maybeCallback??()


const maybeParameter = options.param;

// if statement
if (maybeParameter != null) doSomething(maybeParameter);

// nullish-guard
maybeParameter ?& doSomething(maybeParameter);

// nullish-coalesce
doSomething(maybeParameter ?| defaultValue);


const maybeValue = options.value;

// if statement
if (maybeValue != null) this.value = maybeValue;

// nullish-guard
maybeValue ?& this.value = maybeValue;
}

Just as ?| parallels the usage of || to provide a default when the left-hand side is nullish rather than falsy, ?& allows you to guard the right-hand side when the left-hand side is nullish rather than falsy.

It just so happens that the most common usage of the guard pattern is for optional-chaining, but there are other cases where it can crop up.

@claudepache
Copy link

When you want to use a “nullish-guard”, you can just write:

a != null && b

or, if you insist to get another value than false when a is null, you could write:

a == null ? undefined : b

That doesn’t seem to mandate yet another operator.

An important difference with nullish-coalescing:

a ?? b
a != null ? a : b

and optional chaining:

a?.b
a == null ? undefined : a.b

is that, in absence of such operators, you need either to repeat the expression a (against DRY, especially if a is lengthy) or to assign it to a temporary variable (adding additional noise). For “nullish guard”, there is not such an issue, but it resembles more to just a shorter way to write “== null”.

@thw0rted
Copy link

I made the point in #61 and I think it's valid here: a lot of people consider loose equality operators (== / !=) to be One Of The Bad Parts and flag their use as an error. If you can't rely on == null then your guards become a lot more verbose, and frankly any argument that you can "just" use a test against null in combination with existing operators could also have been applied to the nullish coalescing operator we already have.

I would argue that if we're going to have an OR-like nullish operator, it only makes sense to pair it with an AND-like operator. The point in both cases is to best convey intent, right?

@ljharb
Copy link
Member

ljharb commented Jan 28, 2023

Closing, since this proposal is at stage 4.

@ljharb ljharb closed this as completed Jan 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants