Existential operator (was: ||= is much needed?)
Herby Vojčík
herby at mailbox.sk
Wed Jun 20 15:01:03 PDT 2012
Brendan Eich wrote:
> Herby Vojčík wrote:
>> Let's allow foo.? to denote "soft foo", so you get:
>>
>> foo.?.bar // foo == null ? undefined : foo.bar
>> foo.?(bar) // foo == null ? undefined : foo(bar)
>> foo.?[bar] // foo == null ? undefined : foo[bar]
>
> ?. works as well for these and the main (by use-frequency, so far) form
> matches CS. If we must have extra dots in the lesser-used forms, I'd put
> the dot in the middle to keep the question-mark on the left.
>
>> but maybe also more esoteric uses, like:
>>
>> for (let key in foo.?) // for (let key in (foo == null ? {} : foo))
>
> That is even more of an abuse of dot, and it does not play well with ?:
> ternaries and the proposed ?? operator.
This is usable case. It is not nice to test whether I can use for-in.
> foo.??bar:baz
>
> would be legal by maximal munch, parsed as
>
> (foo.?)?bar:baz.
C'est la vie. :-)
Well, this is something that can be though of, later.
I would not put it away because of this edge case (which is just
strange, but not incorrect).
> Beyond this objection, the need for foo.? instead of foo != null is not
> strong.
>
> Worse, you show magic defaulting to {} in the for-in case, but the
Well, I though of Object.keys(foo.?) and saw the {} case (or something
similar) is in fact a very good case. It can be used for foo.? uniformly
(I'll denote the object [[NPO]] as the short for [[NullPatternObject]]:
foo.?.bar // (foo == null ? [[NPO]] : foo).bar
// [[NPO]] returns [[NPO]] from [[Get]]
foo.?(bar) // (foo == null ? [[NPO]] : foo)(bar)
// [[NPO]] does nothing when [[Call]],
// returns [[NPO]]
foo.?[bar] // (foo == null ? [[NPO]] : foo)[bar]
// [[NPO]] returns [[NPO]] from [[Get]]
for (let key in foo.?)
// for (let key in (foo == null ? [[NPO]] : foo))
// [[NPO]] enumerates no keys
Object.keys(foo.?)
// Object.keys(foo == null ? [[NPO]] : foo)
// [[NPO]] has empty key list
foo.? // foo == null ? [[NPO]] : foo
// [[NPO]] if false if ToBoolean, == null,
// == undefined, === [[NPO]], !== undefined,
// !== null
foo.?.baz = bar // (foo == null ? [[NPO]] : foo).baz = bar
// [[NPO]] does nothing when [[Put]]
I feel there is objection to introduce magical [[NullPatternObject]]
into language, but all of CS-style soft-accesses could be solved very
cleanly and consistently.
> default result for anything like a suffix-? expression in CS is a
> boolean boolean result:
>
> $ cat /tmp/w.coffee
> lhs = foo?
>
> $ ./bin/coffee -p /tmp/w.coffee
> (function() {
> var lhs;
>
> lhs = typeof foo !== "undefined" && foo !== null;
>
> }).call(this);
>
>> foo.? // foo == null ? undefined : foo // sort-of clearing
>
> See above.
>
>> foo.? = bar // foo == null ? undefined : (foo = bar)
>> // this semantics is logical, just don't know
>> // what would be the use case...
>> foo.?.baz = bar // foo == null ? undefined : (foo.baz = bar)
>> // this is usable
>>
>
> These don't win over ?. in the proposal.
>
> /be
Herby
More information about the es-discuss
mailing list