Existential operator (was: ||= is much needed?)

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Jun 18 16:41:21 PDT 2012

"This proposal augments the default operator by adding syntax to avoid accessing a missing property, specifically ?. for getting and setting a property from a reference base that might be undefined or null:" [1]

The specified semantics of proposal actually does more than "avoid accessing a missing property".  It also avoids accessing a property of a missing object.  For example,

function f() {
   var foo;                   //oops, I forgot to write the initializer expression
   return foo?.bar;    //returns undefined because foo evaluates to undefined.  foo.bar  would throw

This seems slightly and possibly significantly different from a situation like:

function f(foo={ }) {
   return foo?.bar;    //returns value of foo.bar or undefined if property bar does not exist, just like foo.bar

In particular, it has the affect of possibly propagating the detection of a simple editorial error like a forgotten initializer further from its place of occurrence.

At the least, this behavior probably should be clarified in the description

The inability to use  ?.  meaningfully in a function call context would seem to make this a only half useful feature.  I suspect many people will initially try to write something like
with the expectation that the call will be skipped if  bar doesn't exist.

These may be an alternative semantics that might address both of the above issues.  Consider:

The semantics of ?. could be defined in terms of a new Reference variant (a Conditiional Reference):
Let baseReference be the result of evaluating MemberExpression.
If Type(baseReference) is Reference and IsConditionalReference(baseReference) is true, then let baseValue be GetUnconditionalValueOrMissing(baseReference)
Else let baseValue be GetValue(baseReference).
If baseValue is null or undefined, then throw a TypeError exception.
Let propertyName be the result of evaluating IdentifierName.
If the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
Return a value of type Conditional Reference whose base value is baseValue and whose referenced name is propertyName, and whose strict mode flag is strict.
Missing is an internal value that designates an attempt to access a missing value.

GetUnconditionalValueOrMissing(R) where R is a Reference is defined as
Let value be GetValue(R).
If value is null or undefined then if IsConditionalReference(R) is true hen return Missing.
Return value.

and GetValue would get the following new steps:

2.5 If IsConditionalReference(V) is true then If base is Missing then  then return undefined.

Function call semantics  (11.2.3) could then be modified with the existing step 2 replaced with

2.1 Let func be GetUnconditionalValueorMIssing(ref).
2.2 If func is MIssing, then return undefined.

With these changes, the following would evaluate to undefined:
    var foo ={},  foo2;
would throw.

But note that both
would throw reference error exceptions because of line 4 of the ?. semantics n (and the existing .). In other words, a variable reference that resolves to undefined or null when used as a base of ?. doesn't be a pass.

However, the two above changes a separable with want one, but not the other. 


[1]: http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120618/e75d6ae9/attachment.html>

More information about the es-discuss mailing list