||= is much needed?

# Hemanth H.M (12 years ago)

Would something like :

obj["prop"] ||= "NewProp" be useful?

# David Bruant (12 years ago)

Le 12/06/2012 15:27, Hemanth H.M a écrit :

Would something like :

|obj["prop"] ||= "NewProp"|

be useful?

ahah, I asked the same question very recently [1]. Answer by Brendan Eich [2]. I definitely agree that default arguments are a decent alternative. I can't recall examples where it wouldn't be enough. Do you have use cases where you would use ||= and default argument values couldn't be used?

David

[1] twitter.com/DavidBruant/status/210654806732324864 [2] twitter.com/BrendanEich/status/210750515808706561

# Rick Waldron (12 years ago)

On Tue, Jun 12, 2012 at 10:33 AM, David Bruant <bruant.d at gmail.com> wrote:

Le 12/06/2012 15:27, Hemanth H.M a écrit :

Would something like :

obj["prop"] ||= "NewProp" be useful?

There is currently a strawman proposal for the "Default Operator", which can be found here:

strawman:default_operator

# Hemanth H.M (12 years ago)

Kool, well was looking into use cases....well my first frustration was [1]

I'm new to this, how does one write proposals? Is it a wiki?

[1] twitter.com/GNUmanth/status/208555914733682690

# Rick Waldron (12 years ago)

On Tue, Jun 12, 2012 at 11:45 AM, Ryan Florence <rpflorence at gmail.com>wrote:

I use ||= very regularly in ruby and coffeescript, both of which have default arguments.

I definitely agree that default arguments are a decent alternative. I

can't recall examples where it wouldn't be enough. Do you have use cases where you would use ||= and default argument values couldn't be used?

Its super handy for caching and late/dynamic initialization of object properties.

var events = {

_callbacks: {},

on: function (topic, callback) { (this._callbacks[topic] ||= []).push(callback); ... }, ... };

It's also useful for settings object defaults, especially for expensive settings that you don't want to calculate in some defaults object that is merged into the settings.

function ajaxWithError (settings) { settings.method ||= 'POST';

settings.elementPosition ||= this._getElementPositions();

settings.somethingWithInitialization ||= (function(){ var thing = new Thing(); thing.foo = settings.foo; return thing; })(); ... };

The ||= (function(){})() should remind any rubyist of ||= begin ... end which is beloved by many.

So yeah, I think its really useful outside of default arguments.

  • Ryan Florence

Forgive the dogpiling, but these are really excellent real-world use cases that represent massive pain points in modern JavaScript programming. Thanks for writing these up Ryan, I've added them to strawman: strawman:default_operator

# AJ ONeal (12 years ago)

+1

I desperately want this in the language.

AJ ONeal

# Brendan Eich (12 years ago)

Rick Waldron wrote:

On Tue, Jun 12, 2012 at 11:45 AM, Ryan Florence <rpflorence at gmail.com <mailto:rpflorence at gmail.com>> wrote:

I use ||= very regularly in ruby and coffeescript, both of which
have default arguments.

I don't see Ryan's mail.

First, as we've discussed in the past, ||= in Ruby is not what we've proposed. In JS, assignment operators expand like so

A op= B; ~~> A = A op B;

with of course a temporary to hold the base of A (which must evaluate to a Reference) so side effects are not duplicated.

In Ruby IIRC, A ||= B is A = B unless A (hope I have this right).

This matters if A is an accessor. Do we always set A, even to its current value if truthy?

    I definitely agree that default arguments are a decent
    alternative. I can't recall examples where it wouldn't be
    enough. Do you have use cases where you would use ||= and
    default argument values couldn't be used?
Its super handy for caching and late/dynamic initialization of
object properties.


    var events = {

      _callbacks: {},

      on: function (topic, callback) {
        (this._callbacks[topic] ||= []).push(callback);
        ...
      },
      ...
    };

This is handy, and also idiomatic but to multiple languages.

It's worth considering, but we need to wrestle the semantics to the ground. If the left-hand side's value is truthy, I argue there should be no useless assignment of that value to the left-hand side.

IOW I favor Ruby semantics. This breaks from JS's C-inspired assignment operators, but perhaps we can live with it.

# Wes Garland (12 years ago)

This breaks from JS's C-inspired assignment operators, but perhaps we can

live with it.

FWIW -- I was confused when I first read ||=, I thought it was supposed to be some kind of Boolean-coercing variant on |=. Now I see that it is more like ?= from GNU make.

What do you think of GCC's ?: operator? It is basically a special form of the ternary operator, and while not the same as your propsal, it addresses many of the same use cases.

(I've been happy with it for a long time).

# Brendan Eich (12 years ago)

Wes Garland wrote:

This breaks from JS's C-inspired assignment operators, but perhaps we can live with it.

FWIW -- I was confused when I first read ||=, I thought it was supposed to be some kind of Boolean-coercing variant on |=. Now I see that it is more like ?= from GNU make.

We could use ?= instead. Good point. This avoids the dual semantics for A op= B split on whether op is || (an existing operator, unlike lone ?).

What do you think of GCC's ?: operator? It is basically a special form of the ternary operator, and while not the same as your propsal, it addresses many of the same use cases.

That's ok as an alternative to ?? but would you want ?:= as the assignment form? I'd rather lose the colon.

Given ?=, people may wish for A ? B instead of A ?? B, but then we have nasty issues with respect to ternary:

A ? B ? C : D

Is this (A ? B) ? C : D or A ? (B ? C) : D. We can disambiguate in the formal grammar but readers may rebel.

It's possible ?? or however we spell it isn't worth adding, while ?= is. The conditional assignment to default or normalize is the prime use-case.

Even then, we have lingering debates over falsy vs. null-or-undefined vs. undefined only. CoffeeScript does null-or-undefined, IIRC.

# Brendan Eich (12 years ago)

Brendan Eich wrote:

Is this (A ? B) ? C : D or A ? (B ? C) : D. We can disambiguate in the formal grammar but readers may rebel.

Or A ? (B ? C : D), of course.

Just say no to lone ? as new operator. I'm warming up to ?= though!

# Tom Ellis (12 years ago)

I like the sound of ?= too.

var a;

//later on

a ?= 15;

It goes with all the other operators that are out there too (!=, =, ==, === etc).

Tom

# Russell Leggett (12 years ago)

On Tue, Jun 12, 2012 at 2:31 PM, Tom Ellis <tellishtc at gmail.com> wrote:

I like the sound of ?= too.

var a;

//later on

a ?= 15;

It goes with all the other operators that are out there too (!=, =, ==, === etc).

+1, useful and intuitive.

# Brendan Eich (12 years ago)

Russell Leggett wrote:

On Tue, Jun 12, 2012 at 2:31 PM, Tom Ellis <tellishtc at gmail.com <mailto:tellishtc at gmail.com>> wrote:

I like the sound of ?= too.

var a;

//later on

a ?= 15;

It goes with all the other operators that are out there too (!=,
=, ==, === etc).

+1, useful and intuitive.

And (to be clear) the semantics for

LeftHandSideExpression ?= AssignmentExpression

are roughly

Let lref = evaluate A. Let lval = GetValue(lref). Let rref = evaluate B. Let rval = GetValue(rref). Throw a SyntaxError exception if the following conditions are all true: • Type(lref) is Reference is true • IsStrictReference(lref) is true • Type(GetBase(lref)) is Environment Record • GetReferencedName(lref) is either "eval" or "arguments" If lval is undefined, call PutValue(lref, rval).

to assign the default value if and only if the left-hand side's current value is undefined.

# Brendan Eich (12 years ago)

Brendan Eich wrote:

LeftHandSideExpression ?= AssignmentExpression

are roughly

Let lref = evaluate A. Let lval = GetValue(lref). Let rref = evaluate B.

Of course, A should be LeftHandSideExpression and B should be AssignmentExpression.

This is pretty simple. We could even grant an exception and get it into ES6, IMHO. But first it needs a strawman and some discussion.

Absent fast objections here, I'll co-opt the

strawman:default_operator

strawman and put it on the agenda.

# Brendan Eich (12 years ago)

Updated. Sorry, no ||| instead of ??. Instead, inspired by Wes's GCC reminder, I kept the ?? operator but re-spelled it as ?: and made ??= be spelled ?=.

strawman:default_operator

The semantics match only undefined. APIs use null as no-object and do not want to trigger defaulting, here or with parameter default values.

This reminds me: IIRC we need to agree that an explicit undefined actual argument triggers defaulting for parameter default values (as it would if the pdv-based code were rewritten to use ?: or ?=).

# John Tamplin (12 years ago)

On Tue, Jun 12, 2012 at 3:09 PM, Brendan Eich <brendan at mozilla.org> wrote:

And (to be clear) the semantics for

LeftHandSideExpression ?= AssignmentExpression

are roughly

Let lref = evaluate A. Let lval = GetValue(lref). Let rref = evaluate B. Let rval = GetValue(rref). Throw a SyntaxError exception if the following conditions are all true: • Type(lref) is Reference is true • IsStrictReference(lref) is true • Type(GetBase(lref)) is Environment Record • GetReferencedName(lref) is either "eval" or "arguments" If lval is undefined, call PutValue(lref, rval).

to assign the default value if and only if the left-hand side's current value is undefined.

Wouldn't you want B to be evaluated only if A is undefined?

# Allen Wirfs-Brock (12 years ago)

On Jun 12, 2012, at 3:26 PM, John Tamplin wrote:

On Tue, Jun 12, 2012 at 3:09 PM, Brendan Eich <brendan at mozilla.org> wrote: And (to be clear) the semantics for

LeftHandSideExpression ?= AssignmentExpression

are roughly

Let lref = evaluate A. Let lval = GetValue(lref). Let rref = evaluate B. Let rval = GetValue(rref). Throw a SyntaxError exception if the following conditions are all true: • Type(lref) is Reference is true • IsStrictReference(lref) is true • Type(GetBase(lref)) is Environment Record • GetReferencedName(lref) is either "eval" or "arguments" If lval is undefined, call PutValue(lref, rval).

to assign the default value if and only if the left-hand side's current value is undefined.

Wouldn't you want B to be evaluated only if A is undefined?

Yes, that makes it consistent with the semantics of ? :

# Brendan Eich (12 years ago)

Heh, I did write roughly :-P.

Let lref = evaluate LeftHandSideExpression. Let lval = GetValue(lref). Throw a SyntaxError exception if the following conditions are all true: • Type(lref) is Reference is true • IsStrictReference(lref) is true • Type(GetBase(lref)) is Environment Record • GetReferencedName(lref) is either "eval" or "arguments" If lval is undefined, then: Let rref = evaluate AssignmentExpression. Let rval = GetValue(rref). Call PutValue(lref, rval).

Thanks, fixing and transcribing into

strawman:default_operator

# Brendan Eich (12 years ago)

Ok, that (cited below) was wrong too.

This should be right: strawman:default_operator#semantics

Comments welcome. Thanks again, I needed some caffeine!

# David Herman (12 years ago)

On Jun 12, 2012, at 11:02 AM, Brendan Eich wrote:

It's possible ?? or however we spell it isn't worth adding, while ?= is. The conditional assignment to default or normalize is the prime use-case.

I'm skeptical. You don't foresee

f(obj.x ?? defVal)

happening a lot? I do.

# Rick Waldron (12 years ago)

This message seems to have disappeared from the archive and since I referred to it in strawman:default_operator I wanted to make sure a record existed.

Rick

---------- Forwarded message ---------- From: Ryan Florence <rpflorence at gmail.com>

Date: Tue, Jun 12, 2012 at 11:45 AM Subject: Re: ||= is much needed? To: Rick Waldron <waldron.rick at gmail.com>

Cc: David Bruant <bruant.d at gmail.com>, es-discuss at mozilla.org

I use ||= very regularly in ruby and coffeescript, both of which have default arguments.

I definitely agree that default arguments are a decent alternative. I

can't recall examples where it wouldn't be enough. Do you have use cases where you would use ||= and default argument values couldn't be used?

Its super handy for caching and late/dynamic initialization of object properties.

var events = {

_callbacks: {},

on: function (topic, callback) { (this._callbacks[topic] ||= []).push(callback); ... }, ... };

It's also useful for settings object defaults, especially for expensive settings that you don't want to calculate in some defaults object that is merged into the settings.

function ajaxWithError (settings) { settings.method ||= 'POST';

settings.elementPosition ||= this._getElementPositions();

settings.somethingWithInitialization ||= (function(){ var thing = new Thing(); thing.foo = settings.foo; return thing; })(); ... };

The ||= (function(){})() should remind any rubyist of ||= begin ... end which is beloved by many.

So yeah, I think its really useful outside of default arguments.

  • Ryan Florence

On Jun 12, 2012, at 9:06 AM, Rick Waldron wrote:

ahah, I asked the same question very recently [1]. Answer by Brendan Eich

# Ryan Florence (12 years ago)

Strawman looks great.

In CoffeeScript you've got both ||= and ?=.

||= is a falsey check, where ?= doesn't allow 0, '', etc.

While both are useful, if I had to pick one its ?=.

coffeescript example: bit.ly/OvKHZ8

Additionally, Ruby's ||= acts like CoffeeScript's ?=.

But if we're adding ?= because we're adding ?: maybe its okay to add ||= while we're at it? That said, I would hate to see ?= get derailed because ||= is "dumb".

# Brendan Eich (12 years ago)

On Jun 12, 2012, at 5:57 PM, David Herman <dherman at mozilla.com> wrote:

On Jun 12, 2012, at 11:02 AM, Brendan Eich wrote:

It's possible ?? or however we spell it isn't worth adding, while ?= is. The conditional assignment to default or normalize is the prime use-case.

I'm skeptical. You don't foresee

f(obj.x ?? defVal)

happening a lot? I do.

Dave

No need to foresee. We have Ruby precedent along with CoffeeScript in sight. We also have JS as it is used today, where || is used almost exclusively on the callee side to supply default values.

# Brendan Eich (12 years ago)

Ryan Florence wrote:

But if we're adding ?= because we're adding ?: maybe its okay to add ||= while we're at it? That said, I would hate to see ?= get derailed because ||= is "dumb".

"Dumb" is too strong. How about YAGNI? Every use-case of || I've seen in JS (almost all with the result of || the RHS of an = op) really wants ?=.

# Ryan Florence (12 years ago)

I'm skeptical. You don't foresee

f(obj.x ?? defVal)

happening a lot? I do.

I can't speak for the world but I've never seen anybody do f(val ||= defVal) in Ruby or CoffeeScript.

# David Herman (12 years ago)

On Jun 12, 2012, at 7:41 PM, Ryan Florence wrote:

I'm skeptical. You don't foresee

f(obj.x ?? defVal)

happening a lot? I do.

I can't speak for the world but I've never seen anybody do f(val ||= defVal) in Ruby or CoffeeScript.

But I'm not talking about ||=. I'm talking about the analog of ||.

# Ryan Florence (12 years ago)

Sorry, I misunderstood.

CoffeeScript has ? (no ternary, so its doable there) but I haven't seen it used much.

# Brendan Eich (12 years ago)

People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see

foo(arg1 || callers_idea_of_default_arg1_value);

whereas we all see

function foo(a, b, c) { a = a || default_a; b.x = b.x || default_b_x; b.y = b.y || default_b_y; c.z = function (w) { // long body here } ... }

Plain and destructuring parameter default values help with a and b (provided the default_* expressions are small and don't require other locals that are computed based on complex conditions, etc.). c.z is harder to fit in the parameter list neatly.

It may be that ?= won't see much use, once p.d.v.s are in. Hence the strawman status while p.d.v.s are in ES6.

# Axel Rauschmayer (12 years ago)

I think it’d be handy when you are taking apart objects (e.g. JSON data). However, you do have the option of merging in default values (e.g. via documentcloud.github.com/underscore/#defaults ).

# T.J. Crowder (12 years ago)

On 13 June 2012 06:52, Brendan Eich <brendan at mozilla.org> wrote:

People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see

I'm with Dave on this, I do it fairly regularly, usually when a function turns around and calls another one with the arg and has no other use for the arg:

function doSomethingNifty(a, b) { return doSomethingVerbose({ x: 1, y: a, z: b ?: 5 // ... }); }

?= looks great, and Wes' point about confusion re ||= (or even |||=) and boolean logical operators definitely kills my preferred ||| for the non-assignment form if there's going to be an assignment form -- and we all want an assignment form.

Is the reason for using ?: rather than ?? because we may want it for my desired second ternary? E.g., from my other message:

a = b ?? c : d;

meaning

a = b !== undefined ? c : d;

Or that we want it (now, or in reserve) for something else? Because if not, I'd prefer to see ?? rather than ?:. It's easier to type and the double ??calls back to the related ||. But again, only if we don't want ?? (now, or in reserve) for something else.

Very much looking forward to ?: (however we spell it) and ?=.

-- T.J.

# Aymeric Vitte (12 years ago)

Indeed, maybe both should be included.

What about this case :

if (typeof(api)=="undefined") {try later} else if (!api.a) {try later} else if (!api.a.b)) {try later} else if (etc...)

which can be written : if (!(((typeof(api)!="undefined"?api.a:undefined)?api.a.b:undefined)?api.a.b.c:undefined)) {try later}

but can't be written with ?:

The best in that case would be to be able to do : if (!api.a.b.c) {try later}

Why in accessors the attempt to access a property of |undefined| could not return |undefined| itself ?

Le 13/06/2012 09:45, T.J. Crowder a écrit :

# Wes Garland (12 years ago)

On 13 June 2012 03:45, T.J. Crowder <tj at crowdersoftware.com> wrote:

Is the reason for using ?: rather than ?? because we may want it for my desired second ternary? E.g., from my other message:

Something else to consider; if we use (a ?: b), it would have to be equivalent to (a ? a : b) with the exception that a is only evaluated once, just as it is in gcc. Any other meaning would be confusing to end users, due to the strong resemblance to the ternary operator.

The use-case here seems to be that it would have the value a whenever a is undefined, not when a is truey. This is a tricky enough difference that I think it mandates a different operator, like ??.

That said, I don't think I have ever seen code like that in the field, where the caller sorts out the "default values" instead of the callee.*

  • later edit: I thought this was true, but see that I have been unwittingly using this idiom myself for years, see examples below.

Very much looking forward to ?: (however we spell it) and ?=.

Me too. They are all over my C code and Makefiles.

Random usage (food for thought): memcpy(newHnd->buffer, thisHnd->buffer, min(length, newHnd->length ?:

length)); const char *filename = gpsee_programRelativeFilename(cx, report->filename) ?: "<unknown filename>";

JS_SetGCParameter(rt, JSGC_MAX_BYTES, (size_t)strtol(rc_default_value(rc, "gpsee_gc_maxbytes", "0"), NULL, 0) ?: (size_t)-1);

So, as you can see above, I tend to use ?: to supply default behaviour to functions when necessary, particularly when they are library functions out of my control.

GPSEE_SRC_DIR ?= $(shell pwd) GREP ?= grep EGREP ?= egrep MAKEDEPEND ?= gcc -E -MM -MG NCURSES_LIB_NAME ?= ncurses BIN_DIR ?= $(GPSEE_PREFIX_DIR)/bin

I use the ?= idiom quite heavily in my Makefiles as we don't use autoconf. We simply have a configure script which generates an include file of "stuff that's different for this platform", which gets included before the stuff that's assigned with the ?=. Also, the ?= allows the developer to override particular variables from environment variables passed to make, i.e. to install into a different target directory, use a different version of gcc, etc. This is idiom is especially powerful with Make's late evaluation of variables, but I don't think we should go there in ES.

# Aymeric Vitte (12 years ago)

Typo below, I meant "which can be written : if (!(((typeof(api)!="undefined"??api.a:undefined)??api.a.b:undefined)??api.a.b.c:undefined)) {try later}"

Le 13/06/2012 12:12, Aymeric Vitte a écrit :

# David Herman (12 years ago)

On Jun 12, 2012, at 10:52 PM, Brendan Eich wrote:

People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see

foo(arg1 || callers_idea_of_default_arg1_value);

I'm sure it's more rare than the assignment form, but that's partly because the assignment form is needed to make up for lack of pdv's.

whereas we all see

function foo(a, b, c) { a = a || default_a; b.x = b.x || default_b_x; b.y = b.y || default_b_y; c.z = function (w) { // long body here } ... }

Well, you wouldn't argue against having || in the language. Yes, I know it serves other roles as well. But only providing the assignment form strikes me as over-specialization. Operators are a straightforward generalization of assignments. When you specialize the syntax to provide an assignment form only, you force people to create temporary variables when they aren't needed. Compound expressions are good things!

And why break the pattern of compound assignments being based on binary operators? Why should ?= or ??= be different from +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, |=, ^=? It just seems like a pointless restriction.

# Brendan Eich (12 years ago)

Confusion: at no point has the

strawman:default_operator

strawman removed the infix operator originally proposed as ?? and currently spelled ?: -- everyone agrees on having both OP and OP=, whatever the spelling of OP.

I agree on reflection with Wes and others who've objected that A ?: B has the simplest interpretation as A ? A : B and therefore should not be used for anything like (A !== undefined) ? A : B or (A != null) ? A : B. I noted this as an open issue but I'm almost ready to flip the strawman back to ?? and ??=. Comments on syntax?

On semantics: CoffeeScript's use of != null to equate null and undefined matches some users' habits, and helps to conceal the awkward fact of two bottom-types in JS (@jashkenas just averred that was the goal). But such concealment can never be perfect and other users will either want to distinguish, or (what is more worrisome) will accidentally distinguish (e.g. with !==) null from undefined.

If only we didn't have both null and undefined! I blame Java (after myself, of course). But we're stuck with both and we have to make the best of this situation.

I still don't see a lot of intentional use of null to mean undefined, e.g. as a "no argument, please default" value passed into APIs. But null or any falsy value would work fine for APIs whose implementations default using ||, so it is possible null is used widely by convention, and I just haven't seen it.

Whatever we do, we should do the same for parameter default values. CoffeeScript is consistent in equating null and undefined and triggering parameter defaulting as if by its ?= assignment op:

f = (x, y=1, z=2) -> console.log(x, y, z)

f(0, null, undefined)

generates

f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); };

f(0, null, void 0);

We could certainly do worse than to pave this cowpath.

# T.J. Crowder (12 years ago)

On 14 June 2012 18:10, Brendan Eich <brendan at mozilla.com> wrote:

I agree on reflection with Wes and others who've objected that A ?: B has the simplest interpretation as A ? A : B and therefore should not be used for anything like (A !== undefined) ? A : B or (A != null) ? A : B. I noted this as an open issue but I'm almost ready to flip the strawman back to ?? and ??=. Comments on syntax?

Do people see sufficient value in a second ternary operator that uses the same semantics for what's a non-value? E.g.:

a = b ?? c : d;

meaning

a = b !== undefined ? c : d;

If people don't see sufficient value in the second ternary (and the use cases are pretty limited), ?? and ??= are great. Ship 'em.

If people do see sufficient value there, ?? is probably better suited to that than then the infix operator we're talking about, and the infix version will want a new name. ??: perhaps, which is easy to type and harkens to the second ternary. That would give us:

a = b ?? c : d; a ??= b; a = b ??: c;

I quite like the full set, but if it's just me, that's a non-argument.

On semantics: CoffeeScript's use of != null to equate null and undefined

matches some users' habits, and helps to conceal the awkward fact of two bottom-types in JS (@jashkenas just averred that was the goal). But such concealment can never be perfect and other users will either want to distinguish, or (what is more worrisome) will accidentally distinguish (e.g. with !==) null from undefined.

FWIW: I never use null to mean "default me" in JS, and have never seen anyone do so. That's just my anecdotal experience. A couple of people have posted that they do, which is their anecdotal experience.

I would rather the new operators just considered undefined as the non-value, not both undefined and null. But it wouldn't impact my code if it did (because I never use null in this way). It's just a preference.

-- T.J.

# Allen Wirfs-Brock (12 years ago)

On Jun 14, 2012, at 10:10 AM, Brendan Eich wrote:

On semantics: CoffeeScript's use of != null to equate null and undefined matches some users' habits, and helps to conceal the awkward fact of two bottom-types in JS (@jashkenas just averred that was the goal). But such concealment can never be perfect and other users will either want to distinguish, or (what is more worrisome) will accidentally distinguish (e.g. with !==) null from undefined.

If only we didn't have both null and undefined! I blame Java (after myself, of course). But we're stuck with both and we have to make the best of this situation.

+1 (except Java doesn't have the equivalent of undefined as a manifest value)

I still don't see a lot of intentional use of null to mean undefined, e.g. as a "no argument, please default" value passed into APIs. But null or any falsy value would work fine for APIs whose implementations default using ||, so it is possible null is used widely by convention, and I just haven't seen it.

Whatever we do, we should do the same for parameter default values. CoffeeScript is consistent in equating null and undefined and triggering parameter defaulting as if by its ?= assignment op:

I think treating null as "not provided, use the default" in parameters is a bad thing that would be going down the path of concealment that is rejected above. While some (many??) people use null and undefined interchangeably, other are no doubt using them closer to the original intention (uninitialized/missing value vs. no object). To cause null to trigger parameter (and destructuring) default values wound break that current valid usage pattern.

While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be.

f = (x, y=1, z=2) -> console.log(x, y, z) f(0, null, undefined)

generates

f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); };

f(0, null, void 0);

We could certainly do worse than to pave this cowpath.

sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea.

# Brendan Eich (12 years ago)

T.J. Crowder wrote:

On 14 June 2012 18:10, Brendan Eich <brendan at mozilla.com <mailto:brendan at mozilla.com>> wrote:

I agree on reflection with Wes and others who've objected that A
?: B has the simplest interpretation as A ? A : B and therefore
should not be used for anything like (A !== undefined) ? A : B or
(A != null) ? A : B. I noted this as an open issue but I'm almost
ready to flip the strawman back to ?? and ??=. Comments on syntax?

Do people see sufficient value in a second ternary operator that uses the same semantics for what's a non-value? E.g.:

a = b ?? c : d;

meaning

a = b !== undefined ? c : d;

No, too thin.

Also preempts ?? as an infix operator, which has been proposed for quite a while as the default operator.

If people don't see sufficient value in the second ternary (and the use cases are pretty limited), ?? and ??= are great. Ship 'em.

Not in ES6, but I'm working on the strawman to get them into Harmony, so they can be prototyped, user-tested, and standardized in due course.

# Brendan Eich (12 years ago)

Allen Wirfs-Brock wrote:

While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be.

Noted, but you have not responded to the argument, made by Sam Tobin-Hochstadt based on Racket experience, Tab Atkins in Common Lisp, and others, that failing to treat explicit undefined as a defaulting trigger creates an anti-modular, combinatorial explosion when wrapping and delegating. This is the sole reason undefined (or undefined and null, separate issue) as defaulting trigger is proposed. Please respond to it directly.

f = (x, y=1, z=2) -> console.log(x, y, z) f(0, null, undefined)

generates

f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); };

f(0, null, void 0);

We could certainly do worse than to pave this cowpath.

sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea.

That's a reductio ad absurdum, nothing to do with why I wrote what I wrote.

We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience).

What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger?

# Herby Vojčík (12 years ago)

Brendan Eich wrote:

Allen Wirfs-Brock wrote:

While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be.

Noted, but you have not responded to the argument, made by Sam Tobin-Hochstadt based on Racket experience, Tab Atkins in Common Lisp, and others, that failing to treat explicit undefined as a defaulting trigger creates an anti-modular, combinatorial explosion when wrapping and delegating. This is the sole reason undefined (or undefined and null, separate issue) as defaulting trigger is proposed. Please respond to it directly.

f = (x, y=1, z=2) -> console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath.

sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea. That's a reductio ad absurdum, nothing to do with why I wrote what I wrote.

We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience).

What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger?

If I can add my own, I use || (because it's short, and if (foo) pattern desensitivised me), but if there would be an operator for undefined, I'll switch to use it immediately (I always see it as undefined, knowing I do sin when using ||).

Btw, |if(foo)| also needs replacement in that case, though if ?? will be there, |if (foo??true)| (or |if (foo??1)|) would serve the case well.

# Herby Vojčík (12 years ago)

Herby Vojčík wrote:

Brendan Eich wrote:

Allen Wirfs-Brock wrote:

While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be.

Noted, but you have not responded to the argument, made by Sam Tobin-Hochstadt based on Racket experience, Tab Atkins in Common Lisp, and others, that failing to treat explicit undefined as a defaulting trigger creates an anti-modular, combinatorial explosion when wrapping and delegating. This is the sole reason undefined (or undefined and null, separate issue) as defaulting trigger is proposed. Please respond to it directly.

f = (x, y=1, z=2) -> console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath.

sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea. That's a reductio ad absurdum, nothing to do with why I wrote what I wrote.

We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience).

What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger?

If I can add my own, I use || (because it's short, and if (foo) pattern desensitivised me), but if there would be an operator for undefined, I'll switch to use it immediately (I always see it as undefined, knowing I do sin when using ||).

Btw, |if(foo)| also needs replacement in that case, though if ?? will be there, |if (foo??true)| (or |if (foo??1)|) would serve the case well.

Well, sorry, not. This is wrong. ?? can't help. |foo ?? 1 : 0| would, but it's different matter. "=== undefined" is too long, though.

# T.J. Crowder (12 years ago)

On 14 June 2012 19:01, Brendan Eich <brendan at mozilla.com> wrote:

The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test.

Not quite. I use || whenever I can in my defaulting code, and I can use it a lot (e.g., when the optional item must be an object). I only use the long-winded version if I have to because 0, "", false, or null is a valid possible value -- which is surprisingly rare. Hugely looking forward to using ?? uniformly instead, but it's not accurate to say that we who don't want undefined and null equated in this context are therefore not using ||.

-- T.J.

# Tab Atkins Jr. (12 years ago)

On Thu, Jun 14, 2012 at 11:01 AM, Brendan Eich <brendan at mozilla.com> wrote:

We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience).

What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger?

I don't claim to be typical in cases like this, but my experience is similar to Herby's - I use || most of the time just because it's short and easy, but switch to "x === undefined" with a trinary if x might be falsey.

# Herby Vojčík (12 years ago)

Tab Atkins Jr. wrote:

On Thu, Jun 14, 2012 at 11:01 AM, Brendan Eich<brendan at mozilla.com> wrote:

We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience).

What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger?

I don't claim to be typical in cases like this, but my experience is similar to Herby's - I use || most of the time just because it's short and easy, but switch to "x === undefined" with a trinary if x might be falsey.

Yeah, I switch, too. If I see it is needed, and don't forget it. That is why || is uneasy, ?? would remove the fear (in Kent-and-Ward TDD sense).

# Brendan Eich (12 years ago)

T.J. Crowder wrote:

On 14 June 2012 19:01, Brendan Eich <brendan at mozilla.com <mailto:brendan at mozilla.com>> wrote:

The users who want null to be distinct from undefined are neither
CoffeeScript users, nor || users (in their defaulting code). They
must be doing === undefined test.

Not quite. I use || whenever I can in my defaulting code, and I can use it a lot (e.g., when the optional item must be an object). I only use the long-winded version if I have to because 0, "", false, or null is a valid possible value -- which is surprisingly rare. Hugely looking forward to using ?? uniformly instead, but it's not accurate to say that we who don't want undefined and null equated in this context are therefore not using ||.

Good point, when you are dealing with an object or variable that you "know" will be either undefined or a well-typed value, you can use ||. But how do you know what is a "possible value"?

Wes testified elsewhere that he had latent bugs. I suspect many APIs whose impls use || do.

# Allen Wirfs-Brock (12 years ago)

On Jun 14, 2012, at 11:01 AM, Brendan Eich wrote:

...

We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience).

What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger?

I guess my concern is that there are significant existing subsystems where null is distinguished from undefined or where null has a specifically defined meaning that does not apply to undefined. For example:

 [[Prototype]] manipulation (Object.create, Object.getPrototypeOf, __proto__)
 RegExp exec and derived APIs
 JSON stringify/parse
 the DOM (WebIDL, provides lots of options vis [TreatUndefinedAs]] to explicitly control the mapping of undefined)

Any of these might yield null values that downstream might want to be distinguished from an unintentional undefined (result of a bogus property access) or explicitly empty parameter slot. My sense is that equating undefined and null for the purpose of supplying default values is going to preclude default value usage in any context where null has a specific meaning. Equating null and undefined in the sole form of default seems value assignment seems to be a bigger commitment to the path of generally trying to conceal the distinction between null and undefined. If we want to commit to that path, then we probably should be explicit about it and make sure that we generally try to avoid new use cases that distinguish them.

For example, for class definitions I have a draft spec. such that (class extends undefined { }) means the same things as (class {}) which means something different from than (class extends null { }. If our goal is generally to conceal the difference between undefined and null, I would probably change that equivalence. Note that this all would probably also have implications for reflective APIs that someone might build in support of classes.

One way to have it both ways is to have multiple syntactic forms for default value initializers. EG:

function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy

I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical.

# Rick Waldron (12 years ago)

On Thu, Jun 14, 2012 at 2:39 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

snip

I guess my concern is that there are significant existing subsystems where null is distinguished from undefined or where null has a specifically defined meaning that does not apply to undefined. For example:

[[Prototype]] manipulation (Object.create, Object.getPrototypeOf,

proto) RegExp exec and derived APIs JSON stringify/parse the DOM (WebIDL, provides lots of options vis [TreatUndefinedAs]] to explicitly control the mapping of undefined)

More examples... event objects created by DOM APIs use null as the initial value of any data property whose value won't be known until an actual event has occurred.

See: www.w3.org/TR/webmessaging, www.w3.org/TR/2012/WD-DOM-Level-3-Events-20120614

snip

One way to have it both ways is to have multiple syntactic forms for default value initializers. EG:

function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy

I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical.

I agree with this entirely.

||= is complementary to || and makes sense - developers will embrace this as is.

?? and ??= seem like "something is unknown" and unknown things can otherwise be described as "undefined". Definitively, |null| is intentional -- which implies something "known" and therefore cannot qualify as "undefined". I think sticking to undefined will help to fix the abused "== null" patterns in extant code (I'm thinking in the long term of course)

If null testing is needed:

a = a != null ? a : default;

I realize that the strawman currently spells it "?:", consider this message an opposition to that.

# John Tamplin (12 years ago)

On Thu, Jun 14, 2012 at 4:04 PM, Rick Waldron <waldron.rick at gmail.com>wrote:

I realize that the strawman currently spells it "?:", consider this message an opposition to that.

This has been an extension to C for quite some time, and it means specifically to use the condition value if it is truthy (and is itself derived from the behavior of a ? a : b). I think it would be a mistake to change that behavior from what is expected.

# Brendan Eich (12 years ago)

Yes, I'm about to bail back to ??.

Issue of undefined vs. undefined-or-null is separate but I'm still favoring undefined only.

# Brendan Eich (12 years ago)

Rick Waldron wrote:

One way to have it both ways is to have multiple syntactic forms
for default value initializers.  EG:

function f(a = 1, b ??= 2, c ||= 3) { }  //assuming ??= is
undefined or null defaulting guard and ||= is falsy

I'm not particularly convinced that the additional complexity is
warranted but it would place the choice into ES programmers hands
rather us trying to anticipate the typical intent and
disadvantaging the untypical.

I agree with this entirely.

Including the part where Allen is not convinced to add all these forms?

I can see adding ?? and ??= (undefined-only, not undefined-or-null).

Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind.

Given ||= is there any oxygen left in the room for ??=?

# Rick Waldron (12 years ago)

On Thu, Jun 14, 2012 at 3:45 PM, Brendan Eich <brendan at mozilla.com> wrote:

Rick Waldron wrote:

One way to have it both ways is to have multiple syntactic forms for default value initializers. EG:

function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy

I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical.

I agree with this entirely.

Including the part where Allen is not convinced to add all these forms?

Yes.

...But it felt useful to note that ||= would compliment || and immediately understood by devs

I can see adding ?? and ??= (undefined-only, not undefined-or-null).

Yes, absolutely.

Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind.

That makes complete sense to me, but again - it might not be worth adding, because a = b || c isn't that painful.

Given ||= is there any oxygen left in the room for ??=?

Right now, I believe the whole set compliment the current language and its operators nicely - but if it came down to one or the other, I would prefer seeing the new addition of ?? and ??=

# T.J. Crowder (12 years ago)

On 14 June 2012 21:45, Brendan Eich <brendan at mozilla.com> wrote:

I can see adding ?? and ??= (undefined-only, not undefined-or-null).

Excellent.

Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind.

Nice-to-have. The fact it doesn't assign if the left side is truthy is the only reason for having it, surely?

Given ||= is there any oxygen left in the room for ??=?

??= regardless. ||= is a nice to have in addition if there's really enough impetus for it. In my code, I'd be using ??= a lot more often than ||=.

-- T.J.

# John Tamplin (12 years ago)

On Thu, Jun 14, 2012 at 5:32 PM, T.J. Crowder <tj at crowdersoftware.com>wrote:

Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind.

Nice-to-have. The fact it doesn't assign if the left side is truthy is the only reason for having it, surely?

Plus not even evaluating the RHS if the LHS is truthy -- useful if the default is an expensive calculation.

# T.J. Crowder (12 years ago)

On 14 June 2012 22:38, John Tamplin <jat at google.com> wrote:

On Thu, Jun 14, 2012 at 5:32 PM, T.J. Crowder <tj at crowdersoftware.com>wrote:

Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind.

Nice-to-have. The fact it doesn't assign if the left side is truthy is the only reason for having it, surely?

Plus not even evaluating the RHS if the LHS is truthy -- useful if the default is an expensive calculation.

Right, but a = a || b doesn't evaluate b if a is truthy, either. What I meant was, if we have a ??= b, and of course we already have a = a || b, the only reason for having a ||= b is that it doesn't assign if a is truthy.

-- T.J.

# Aymeric Vitte (12 years ago)

This discussion I think is going into a useless complexity.

Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here

Le 14/06/2012 23:16, Rick Waldron a écrit :

# Rick Waldron (12 years ago)

On Thu, Jun 14, 2012 at 6:06 PM, Aymeric Vitte <vitteaymeric at gmail.com>wrote:

This discussion I think is going into a useless complexity.

Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here

There doesn't need to be an explicit check for undefined - anytime null is used as an intentional place holder and its value would be otherwise undefined counts as well.

And for your information, I am not w3c and I use null frequently (the same way w3c uses it).

# Tab Atkins Jr. (12 years ago)

On Thu, Jun 14, 2012 at 4:06 PM, Aymeric Vitte <vitteaymeric at gmail.com> wrote:

Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here

Your experience isn't necessarily universal. I've used null before to mean something different than undefined.

# Mark S. Miller (12 years ago)

Just clarifying -- we all agree that any such thing is too late for ES6, right? On this assumption, I'm postponing engaging in this thread until I have time.

# Aymeric Vitte (12 years ago)

"Before"...

I put Rick's answer below too, in strict/correct code it can be used but what examples (except yours) ?

Maybe I missed it, never saw the use of null since a long time, but I can be wrong

Do you think it does worth the complexity for the operators we are talking about ? w3c is forced to define something as null, would look strange and not serious to define it as undefined in specs, but in reality this is let to the appreciation of developers (who usually don't care), and for comparisons/default, null will, I think, never be used, then it should probably behave the same as undefined

Le 15/06/2012 01:12, Tab Atkins Jr. a écrit :

On Thu, Jun 14, 2012 at 4:06 PM, Aymeric Vitte<vitteaymeric at gmail.com> wrote:

Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here Your experience isn't necessarily universal. I've used null before to mean something different than undefined.

~TJ

There doesn't need to be an explicit check for undefined - anytime null is used as an intentional place holder and its value would be otherwise undefined counts as well.

And for your information, I am not w3c and I use null frequently (the same way w3c uses it).

# Aymeric Vitte (12 years ago)

Just to be clear I am talking about the use of null in the scope of the current discussion (ie operators/default) only

Le 15/06/2012 01:37, Aymeric Vitte a écrit :

# Brendan Eich (12 years ago)

I don't think it matters yet, this is fair game for es-discuss as a harmony strawman.

But it does connect to parameter default values, where we have open issues that come up here too. Worth skimming IMHO.

# Brendan Eich (12 years ago)

On Jun 14, 2012, at 6:38 PM, Aymeric Vitte <vitteaymeric at gmail.com> wrote:

Maybe I missed it, never saw the use of null since a long time, but I can be wrong

As Allen pointed out, null is specified in ECMA-262, e.g. Object.getPrototypeOf.

# Aymeric Vitte (12 years ago)

Yes, what I mean is that I did not see since a long time something like a===null?b:c or if (a===null)||b, and except for specific use like Object.create(null) I don't see a lot of null being used, then making the distinction for ??, ?: and others looks too subtle

Le 15/06/2012 04:20, Brendan Eich a écrit :

# David Herman (12 years ago)

On Jun 14, 2012, at 1:45 PM, Brendan Eich wrote:

I can see adding ?? and ??= (undefined-only, not undefined-or-null).

I think ?? is the highest priority.

Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind.

Given ||= is there any oxygen left in the room for ??=?

??= is strictly less error-prone than ||= so I can't see why we would favor ||= if we were choosing just one.

As I see it, the biggest issue with ??= and ||= is that -- unlike other compound assignment forms -- they are short-circuiting. All the existing compound assignment forms evaluate both sides no matter what. IIRC, back in the ES4 days, this is why we rejected ||=.

I'm still not against it, though. It's obvious what it means. It's obviously useful.

So I favor ?? as well as both ||= and ??=.

As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. But I think by sticking to the simpler semantics it will help clarify the distinction. The JS semantics currently treats only undefined as "no value" and it would continue to do so.

# Brendan Eich (12 years ago)

David Herman wrote:

So I favor ?? as well as both ||= and ??=.

As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. But I think by sticking to the simpler semantics it will help clarify the distinction. The JS semantics currently treats only undefined as "no value" and it would continue to do so.

I agree on all this.

I'll update the strawman soon.

# satyr (12 years ago)

On Sat, Jun 16, 2012 at 4:33 AM, David Herman <dherman at mozilla.com> wrote:

As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them.

Not just for blurring. Rejecting null is essential for CoffeeScript's "existence" due to ?., the soak/safe access operator.

# Gavin Barraclough (12 years ago)

On Jun 15, 2012, at 12:33 PM, David Herman wrote:

So I favor ?? as well as both ||= and ??=.

Adding ||= and ??= without &&= will cause my symmetry-reflex to twitch, despite not seeing a purpose for it I may find it hard to resist supporting that too. ;-)

G.

# Brendan Eich (12 years ago)

AS3 (fed into ES4, RIP) has &&= and it sees little use. Not none, of course, because it's there and people use stuff, even seemingly useless stuff.

Any Flash/Flex AS3 hackers willing to self-identify and say more?

# Brendan Eich (12 years ago)

satyr wrote:

On Sat, Jun 16, 2012 at 4:33 AM, David Herman <dherman at mozilla.com <mailto:dherman at mozilla.com>> wrote:

As for null, I can see how there's confusion about whether to use
null vs undefined, and so I can see why CoffeeScript would just
try to blur the distinction between them.

Not just for blurring. Rejecting null is essential for CoffeeScript's "existence" due to ?., the soak/safe access operator.

Can you give a real-world example where null rather than undefined is soaked up? I'm guessing DOM but guessing is bad (cf. Sherlock Holmes).

# John Tamplin (12 years ago)

On Fri, Jun 15, 2012 at 6:00 PM, Brendan Eich <brendan at mozilla.com> wrote:

Can you give a real-world example where null rather than undefined is soaked up? I'm guessing DOM but guessing is bad (cf. Sherlock Holmes).

Wouldn't any case where you return null to mean explicitly no object be such a case? Ie:

var bar = lookupFoo(key)?.bar();

# Brendan Eich (12 years ago)

Maybe, probably, of course ;-).

I'm still looking for real-world use-cases, code that actually exists (in CoffeeScript or JS) that needs to soak up null-or-undefined, not just undefined.

# David Herman (12 years ago)

On Jun 15, 2012, at 5:57 PM, satyr wrote:

On Sat, Jun 16, 2012 at 4:33 AM, David Herman <dherman at mozilla.com> wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them.

Not just for blurring. Rejecting null is essential for CoffeeScript's "existence" due to ?., the soak/safe access operator.

I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this:

  • The purpose of ?? is to provide a default value when no value was provided. The way to say "no value" in JavaScript is undefined.

  • The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup.

# Brendan Eich (12 years ago)

David Herman wrote:

On Jun 15, 2012, at 5:57 PM, satyr wrote:

On Sat, Jun 16, 2012 at 4:33 AM, David Herman <dherman at mozilla.com <mailto:dherman at mozilla.com>> wrote:

As for null, I can see how there's confusion about whether to use
null vs undefined, and so I can see why CoffeeScript would just
try to blur the distinction between them.

Not just for blurring. Rejecting null is essential for CoffeeScript's "existence" due to ?., the soak/safe access operator.

I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this:

  • The purpose of ?? is to provide a default value when no value was provided. The way to say "no value" in JavaScript is undefined.

  • The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup.

Agreed. This is one choice, it's plausible because of the distinction between defaulting (which requires intentional passing of a "please default" sentinel value, or not passing a trailing actual argument) and soaking up null-or-undefined.

Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. For foo.bar?.baz, though, the clearer choice is to avoid throwing, which means evaluating to undefined if foo.bar is missing (evaluates to undefined) or has a value not coercible to object type (null or undefined). See

strawman:existential_operator

# Wes Garland (12 years ago)

Yes, we could make ?? and ??= do the same for null as for undefined. I'm

not sure that's

the right choice, but it's a choice.

Introducing yet another way to think about values in ES is not going to help most programmers. We already have to think about thinks like undefined and falsey -- what's been proposed here is an operator that mysterious works on something halfway between the two.

Some folks may not see the need to differentiate between the two, but as somebody who talks to databases with ES -- there is a world of difference between null and undefined.