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

Allen Wirfs-Brock allen at wirfs-brock.com
Tue Jun 19 12:10:16 PDT 2012


On Jun 19, 2012, at 10:31 AM, Brendan Eich wrote:

> Brendan Eich wrote:
>> Allen Wirfs-Brock wrote:
>>> I still stand by my alternative semantics as being a way to address the more important use case without have ?()
>> No, the basis cases differ and that is a bug in your alternative.
>> 
>> foo?.bar means take bar from foo or undefined if foo == null.
>> 
>> foo?.bar() means take bar from foo and throw if foo == null else try to invoke the result if typeof "function", else undefined.
>> 
>> This is an off-by-one bug.
> 
> It also uses ?. to mean . and magically applies the ? to the later ().
> 
> Or if the semantics suppresses a TypeError both for the "take bar" and "invoke it" parts, then it's mixing two things in one under syntax located in the wrong place for the second suppression. Mainly, suppression should be precise and at the point of application -- where the dot goes if getting or setting, where the left paren goes if invoking.

I don't agree, probably because I'm look at ?. as an operator that evaluates to a special kind of  Reference.  Like with References in general, it is the ultimate consumer (usually via GetValue/SetValue, but not always) of the Reference that actually access the value or throws an error if appropriate. 

If we say that the value Missing represents a Reference to a known to be non-existant value, then the semantics of LHS?.prop can be summarized as:

LHS                    ==>        Result
-------------------------------------------
Unresolvable  Ref             Missing
undefined/null                   Missing
Missing                               Missing
other non-Ref                    ConditionalRef(GetValue(LHS),prop)
Reference                          Missing   or ConditionalRef(GetValue(LHS),prop)
     (both  normal and Conditional)

This differs from LHS.prop whose corresponding table would be                        

LHS                    ==>        Result
-------------------------------------------
Unresolvable                     throw
undefined/null                   throw
Missing                               throw
other non-Ref                    Reference(GetValue(LHS),prop)
Reference                         throw   or Reference(GetValue(LHS),prop)
     (both  normal and Conditional)

In addition, GetValue(V) is extended with these cases:
V                    ==>        Result
-------------------------------------------
Missing                         undefined
ConditionalRef            undefined if referenced property doesn't exist, otherwise same as normal Reference

Just like with all References, it is the consumer of a Missing/ConditionalReference value that determines what to do with. Most consumers unconditionally call GetValue however, some like typeof and delete explicitly deal with the Reference in some other manner. 

All I have done is add function call to the list of operators that have some Reference sensitive semantics.  It would have special handling for Missing/ConditionalRefs.  I could also add "Missing" semantics to delete, but it really isn't very important there.

> 
> Also, if you agree that the ?( case in CS is less significant, then we shouldn't add it in haste or mangle ?. semantics to try to cover it.

No, I didn't say that.  I said that I suspect that
    f?()
is less significant than
    foo?.bar?()

I suspect that (if you could say them in JS) we would find that
    g(foo?.bar)
and
    g(foo?.baz?())
are about equally significant and that people will write (or typo)
    foo?.bar()
with the expectation that it means
    foo?.bar?()

The risk is in adding precisely CoffeeScript ?. in haste without thinking through implications of not also having ?().  It may mean a different variant of ?. semantics would work better in our case.  

Allen








> 
> /be
> 



More information about the es-discuss mailing list