Nullish unary operator `?`

It would be very confusing in JS for "defined" to mean anything besides "not undefined". Since the precedent here is to treat undefined and null the same, it'd need to be a term that encompassed both - which is either "non-nullish" or "object-coercible" (but that's a very uncommon term, it's what {} is in TypeScript).

4 Likes

I honestly can't think of a good word for "not nullish". The best that comes to mind is the concept of "This variable contains something (i.e. not-nullish), as opposed to nothing (i.e. nullish)", but I can't think of a good way to put that into a succinct phrase, that doesn't also allude to something completely unrelated.

Perhaps, the operator can still be called "non-nullish", but when we discuss what it does, we can use verbage such as "Checks if x has a value".

null and undefined are both values :-)

1 Like

Hmm... this terminology thing is pretty tricky :-(

1 Like

I'd suggest a name "flavored value".

To me, naming it “non-nullish” (instead of “not nullish”) is totally fine. At least “is the variable not non-nullish” does not sound painful to me.

I’m hoping this proposal to reach higher stage soon; it’s definitely useful for everyone!

1 Like

Indeed, I would love to see this proposal go to higher stage too!

Asking it again, because it's been quite a while since I first asked: is anyone interested (or knows someone who could be interested) to champion this proposal? :slightly_smiling_face:

1 Like

I think a prefix nullish operator ? a nice idea, and I wouldn’t oppose it, but I suspect that several Committee members would block it. New syntax in general has a high barrier. In this case, like @theScottyJam mentioned in February, this operation is something that’s already possible with == null or != null, which lots of people already do.

I’m reminded when I informally re-raised the idea of having a binary logical xor operator ^^ on the Matrix channel last September, after which there was pushback saying, “Why not just use !==?” I suspect that a prefix nullish operator ? would face similar pushback: “Why not just use == null or propose an isNullish function?” Not that I agree with that argument; I’m just making a prediction.

Sorry if that’s discouraging; I encourage and appreciate the thought that has gone into this, and, if another TC39 delegate decides to champion this, I would not oppose it. If I weren’t juggling five or so other proposals already, I might even consider championing it myself—maybe someday. :slightly_smiling_face:

(A related thread from three years ago in the old ESDiscuss mailing list.)

1 Like

I certainly would not be opposed to an isNullish function either. The purpose of a stage 0/1 proposal is to present a problem that needs to be solved - in this case, it's the fact JavaScript has two nullish values (undefined and null), and no standard way to check against both, so many people employ a commonly known "hack" via a widely discouraged operator != null trick. We need the language to provide an official way to check if something is nullish, so we don't continue to encourage unreadable hacks such as this.

Conversely, I'm not entirely sure what problem a "^^" operator would be solving.

At a minimum, an isNullish function would be able to solve this issue as well. Perhaps we can follow in the footsteps of the Object.pick() strawman, and start out by simply presenting an isNullish function, with a note about how this proposal could also go in the direction of a syntax addition instead. As it gets to stage one, we could get a temperature of the committee's feelings towards syntax vs API to help decide how this proposal should move forwards. But, I can't imagine there being strong opposition to at least having an isNulish function, to replace the != null idiom.

But, I don't know what other's feelings are towards an isNullish function. It certainly is more verbose than a simple "?", but it still does the job.

1 Like

I had thought that != null was the idiomatic, encouraged, and “official” way to check a value for nullishness; I had not known that anyone was discouraging it. Like you had mentioned a few months ago, it is a clear exception to the rule that many people discourage using ==/!= in general.

I do agree that teaching beginners the coercion rules is more complicated than just teaching a beginner about the concept of nullishness. I would definitely support an Object.isNullish and/or prefix-? proposal myself, though I don’t have the bandwidth to champion either right now.

I mean, this isn't really wrong either. Many people encourage its use (myself included). However, it's not like != null was intentionally designed to fulfill this purpose. Looking at the coercion rules used by double equals, it feels like the original language designers were just trying to pump as much coercion into the equality operator as they could think of, and it so happened that the only thing they let coerce to null was undefined. In an alternative universe, "null" and/or "" would have coerced to null as well.

Soon enough, people realized the dangers of loose equality and started banning it. But, some smart people picked up on the fact that "== null" could be pretty useful to achieve a commonly desired goal, so they started using it, and soon that spread like wildfire as "the exception to the rule", because it was such a common need.

But, not everyone is doing it. For example, it does not look like Airbnb's style guide allows it (unless I missed where they do). The problem with "== null" is that it's a lie. We're not trying to check if something equals null, we're trying to check if something is nullish. No reasonable person who's reading someone else's JavaScript code, and who has not yet been indoctrinated in these idioms, would expect this behavior out of "== null".

1 Like

Definitely not soon enough. It was way too late. If only someone checked with AWK or Perl, whose coercion rules are not as crazy, yet still sometimes trip people up.

Hello everyone!

I know it's been a while, but I still haven't given up on this idea! :slightly_smiling_face:

I gave a shot at writing the grammar and the runtime semantic evaluation of the ? non-nullish operator, in the spec.emu file of the github repository. I'm definitely not an expert on this, so if any of you can see anything that need to be corrected or improved, your help is very welcomed!

Once again, considering that some time have past, I'm reiterating my question about any champion being interested to support this proposal!

I strongly believe that this non-nullish operator would help making the language easier to learn and to use, for both beginners and more advanced programmers. It would help to remove the last usecase where the deprecated loose comparison == is needed, eliminating this quirk for good, and remove the need to explicitly use undefined or null, following the steps started by the nullish coalescing operator.

So if any champion is interested and would have the time to champion this proposal, please let me know!

3 Likes

I just remembered this idea now when I came across something similar, so just came in to drop a hi.

I think 'non-nullish' as its name is totally fine, unless you want to coin a new term like fullish, which would be kinda foolish :face_with_hand_over_mouth:.

I would oppose the isNullish() thing cuz I don like jamming simple operations like these which need simple operators into gross utility functions. Besides, its longer than doing ?a anyway and if we wanted, we could declare it ourselves.

Also, sheepishly, this is a kinda use case for my Unions proposal which nobody liked :pleading_face:. But I would still prefer a nullish operator for this all the same.

foo !== undefined && foo !== null

foo !== null &~ undefined // TADA

I'm very positive for this idea and would love to see this in the language. I just hope it's given the attention it deserves and championed soon :)

1 Like

I originally was supportive of this idea. Over time, the way I've handled null and undefined in my codebases have changed. I was just looking through a more recent project of mine, and was surprised to find out that I never once used the == null shorthand in there. Instead, whenever I needed to let a value have a nothingnness state, I just picked between using undefined or null for its nothingness state, and then stayed consistent to that choice, then whenever I needed to check if it was in its nothingness state, I would either use === null or === undefined, depending on which one I chose. If I was smart, I would simply always pick undefined, instead of randomly deciding between the two - maybe I'll improve on that in my next project.

I treated my public APIs in a similar manner - if you pass in undefined, it works as intended, and if you pass in null, I'd throw an error, as that is not one of the allowed types that the API expects.

The point is, there's ways to program in JavaScript which makes it so the == null trick isn't needed at all. There's a handful of other, minor advantages to programming in this alternate format - I won't go over it all here, but I did leave an in-depth comment in another thread where I exposed it in a lot of more detail.

So, guess I'm just saying that, while adding some sort of "? XXX" syntax would help a good number of people, I now believe that an even better solution is to introduce people to patterns that cause this sort of syntax to not be needed. (And to be clear - the purpose of using those patterns isn't to avoid the need of that syntax, the purpose is to benefit from the other stuff that the patterns provide, it's just a nice bonus that following these patterns means you won't feel a need for some sort of "? XXX" syntax).

I really love this idea and it's practical for me. What about "a?!" ?

const a: { b?: string | null } = { b: null }

if (a.b?.length > 0) {
  console.log("a.b is a string")
}

if (a.b?!) {
  console.log("a.b is not null or undefined")
}

// a.b! means that  b is not null or undefined;

// a.b?! means that b is possible null or undefined, and ! try to assert  b is
// not null or undefined, if success (b is not null or undefined), this expression is true,
// otherwise, it's false