||= is much needed?

Allen Wirfs-Brock allen at wirfs-brock.com
Thu Jun 14 12:39:05 PDT 2012

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.



More information about the es-discuss mailing list