Existential Operator / Null Propagation Operator

classic Classic list List threaded Threaded
44 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Existential Operator / Null Propagation Operator

Christoph Pojer
Tim Yung and I have hacked on a reference implementation for the
"Existential Operator" using esprima-fb and jstransform: "a?.b"

Example:

`a?.b` => `(a == null ? void 0 : a.b)`
`a?.b.c` => `(a == null ? void 0 : a.b.c)`

This must also make sure that `a` only gets evaluated a single time.

Based on previous discussions on es-discuss and TC39, it seems that
this was tabled for ES6. I think now is a good time to bring it up for
ES7. There is precendence for this feature in other languages - it was
recently added to C# and Hack and has always been in CoffeeScript.
TypeScript is waiting for TC39:
https://github.com/Microsoft/TypeScript/issues/16

In the past, this topic has invited a lot of bikeshedding, but I'd
like us to look past this. Several communities within and outside the
JS community have identified the need for this operator. My
understanding is that a decision needs to be made about whether the
operator should short-circuit additional invocations in the call chain
if the operand is null (aka. null propagation).

For example, if `a` is null, should `a?.b.c`:

1) evaluate to `(void 0).c` and throw a TypeError?
2) short-circuit at `a` and return `void 0`?

It appears that C# chose option #2 whereas Hack and CoffeeScript chose
option #1. Our current implementation chose option #1 but we'd be
happy to build a reference implementation for option #2.

I recall that another issue was that of transitivity. Right now,
(a.b).c and a.b.c are equivalent. (a?.b).c and a?.b.c would not be
equivalent expressions. I think we need some input from the people on
this list about whether this is okay or why we value transitivity for
this operator.

If we can come to an agreement on the existential operator for member
expressions, we would also be setting a precedent for other features
of the same family. For example, existential call expressions: `fn?()`
which would conditionally invoke `fn`.

esprima-fb change: https://github.com/cpojer/esprima/tree/existential-operator
jstransform change:
https://github.com/yungsters/jstransform/tree/existential-operator

Previous discussions on es-discuss:
* https://esdiscuss.org/topic/the-existential-operator
* https://esdiscuss.org/topic/specifying-the-existential-operator-using-abrupt-completion
* https://esdiscuss.org/topic/sept-18-tc39-meeting-notes

--
Christoph Pojer
http://cpojer.net
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Herby Vojčík


Christoph Pojer wrote:

> Tim Yung and I have hacked on a reference implementation for the
> "Existential Operator" using esprima-fb and jstransform: "a?.b"
>
> Example:
>
> `a?.b` =>  `(a == null ? void 0 : a.b)`
> `a?.b.c` =>  `(a == null ? void 0 : a.b.c)`
>
> This must also make sure that `a` only gets evaluated a single time.
>
> Based on previous discussions on es-discuss and TC39, it seems that
> this was tabled for ES6. I think now is a good time to bring it up for
> ES7. There is precendence for this feature in other languages - it was
> recently added to C# and Hack and has always been in CoffeeScript.
> TypeScript is waiting for TC39:
> https://github.com/Microsoft/TypeScript/issues/16
>
> In the past, this topic has invited a lot of bikeshedding, but I'd
> like us to look past this. Several communities within and outside the
> JS community have identified the need for this operator. My
> understanding is that a decision needs to be made about whether the
> operator should short-circuit additional invocations in the call chain
> if the operand is null (aka. null propagation).
>
> For example, if `a` is null, should `a?.b.c`:
>
> 1) evaluate to `(void 0).c` and throw a TypeError?
> 2) short-circuit at `a` and return `void 0`?

I liked the result of using a Null Pattern inside and materializing it
outside, which once seemed to be plausible, with that `a?.b.c` would be
`void 0` of course. I don't remember on what it all died back then (yes,
I have a bias, I wanted a true null pattern, AWB than said it is good
inside but not really good as first class person).

> It appears that C# chose option #2 whereas Hack and CoffeeScript chose
> option #1. Our current implementation chose option #1 but we'd be
> happy to build a reference implementation for option #2.
>
> I recall that another issue was that of transitivity. Right now,
> (a.b).c and a.b.c are equivalent. (a?.b).c and a?.b.c would not be
> equivalent expressions. I think we need some input from the people on
> this list about whether this is okay or why we value transitivity for
> this operator.
>
> If we can come to an agreement on the existential operator for member
> expressions, we would also be setting a precedent for other features
> of the same family. For example, existential call expressions: `fn?()`
> which would conditionally invoke `fn`.
>
> esprima-fb change: https://github.com/cpojer/esprima/tree/existential-operator
> jstransform change:
> https://github.com/yungsters/jstransform/tree/existential-operator
>
> Previous discussions on es-discuss:
> * https://esdiscuss.org/topic/the-existential-operator
> * https://esdiscuss.org/topic/specifying-the-existential-operator-using-abrupt-completion
> * https://esdiscuss.org/topic/sept-18-tc39-meeting-notes
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Jordan Harband
Wouldn't option 1 provide the transitivity you're discussing? If `a?.b.c` calls `(void 0).c` then `(a?.b).c` and `a?.b.c` would be identical, and both throw a TypeError.

From my reading, it seems like option 2 is the one that does not provide transitivity, and tbh would surprise me greatly in the context of JS. If I want the short circuit in option 1, I'd do `a?.b?.c` to indicate that, whereas in option 2 if I don't want the short circuit, I'm forced to use separate variables.

On Mon, Apr 6, 2015 at 11:40 AM, Herby Vojčík <[hidden email]> wrote:


Christoph Pojer wrote:
Tim Yung and I have hacked on a reference implementation for the
"Existential Operator" using esprima-fb and jstransform: "a?.b"

Example:

`a?.b` =>  `(a == null ? void 0 : a.b)`
`a?.b.c` =>  `(a == null ? void 0 : a.b.c)`

This must also make sure that `a` only gets evaluated a single time.

Based on previous discussions on es-discuss and TC39, it seems that
this was tabled for ES6. I think now is a good time to bring it up for
ES7. There is precendence for this feature in other languages - it was
recently added to C# and Hack and has always been in CoffeeScript.
TypeScript is waiting for TC39:
https://github.com/Microsoft/TypeScript/issues/16

In the past, this topic has invited a lot of bikeshedding, but I'd
like us to look past this. Several communities within and outside the
JS community have identified the need for this operator. My
understanding is that a decision needs to be made about whether the
operator should short-circuit additional invocations in the call chain
if the operand is null (aka. null propagation).

For example, if `a` is null, should `a?.b.c`:

1) evaluate to `(void 0).c` and throw a TypeError?
2) short-circuit at `a` and return `void 0`?

I liked the result of using a Null Pattern inside and materializing it outside, which once seemed to be plausible, with that `a?.b.c` would be `void 0` of course. I don't remember on what it all died back then (yes, I have a bias, I wanted a true null pattern, AWB than said it is good inside but not really good as first class person).

It appears that C# chose option #2 whereas Hack and CoffeeScript chose
option #1. Our current implementation chose option #1 but we'd be
happy to build a reference implementation for option #2.

I recall that another issue was that of transitivity. Right now,
(a.b).c and a.b.c are equivalent. (a?.b).c and a?.b.c would not be
equivalent expressions. I think we need some input from the people on
this list about whether this is okay or why we value transitivity for
this operator.

If we can come to an agreement on the existential operator for member
expressions, we would also be setting a precedent for other features
of the same family. For example, existential call expressions: `fn?()`
which would conditionally invoke `fn`.

esprima-fb change: https://github.com/cpojer/esprima/tree/existential-operator
jstransform change:
https://github.com/yungsters/jstransform/tree/existential-operator

Previous discussions on es-discuss:
* https://esdiscuss.org/topic/the-existential-operator
* https://esdiscuss.org/topic/specifying-the-existential-operator-using-abrupt-completion
* https://esdiscuss.org/topic/sept-18-tc39-meeting-notes

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Kevin Smith
In reply to this post by Christoph Pojer
 
If we can come to an agreement on the existential operator for member
expressions, we would also be setting a precedent for other features
of the same family. For example, existential call expressions: `fn?()`
which would conditionally invoke `fn`.

In the meeting notes you linked to, Waldemar (WH) noted that some of these variations may have grammar issues.

Although not strictly ambiguous with conditional expressions, `fn ? ()` would require the use of YACG (yet another cover grammar).

Also, what about computed property names?  For example:  `obj ? [Symbol.iterator]`.  I'm not sure that even YACG will help here.

(Thanks for compiling the list of previous threads BTW).


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
joe
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

joe
I hacked together something similar myself.  IIRC, this particular transformation has issues with nested operators (e.g. a.b?.c.d?.e.f?.h).  Of course that's an implementation detail, but the problem (if I'm remembering it right) is that people couldn't figure out what the implementation constraints are (I think there was consensus that the trinary transformation was unworkable), and without knowing those constraints it wasn't possible to write a spec for it.

I could be remembering all this wrong, but that's my recollection of how that conversation went.  I think the consensus was to wait for the ? operator to become more mature in other languages.

On Mon, Apr 6, 2015 at 12:19 PM, Kevin Smith <[hidden email]> wrote:
 
If we can come to an agreement on the existential operator for member
expressions, we would also be setting a precedent for other features
of the same family. For example, existential call expressions: `fn?()`
which would conditionally invoke `fn`.

In the meeting notes you linked to, Waldemar (WH) noted that some of these variations may have grammar issues.

Although not strictly ambiguous with conditional expressions, `fn ? ()` would require the use of YACG (yet another cover grammar).

Also, what about computed property names?  For example:  `obj ? [Symbol.iterator]`.  I'm not sure that even YACG will help here.

(Thanks for compiling the list of previous threads BTW).


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Matthew Robb
In reply to this post by Kevin Smith

On Mon, Apr 6, 2015 at 3:19 PM, Kevin Smith <[hidden email]> wrote:
Although not strictly ambiguous with conditional expressions, `fn ? ()` would require the use of YACG (yet another cover grammar).

Also, what about computed property names?  For example:  `obj ? [Symbol.iterator]`.  I'm not sure that even YACG will help here.

I have two thoughts:

1. Could the language allow for a prefix operator instead (AKA 'The Maybe Operator'):
        `?a.b` and `?obj()` and `?obj[Symbol.iterator]`

2. ​You could make the postfix operator `?.` which would be ugly but dodge the above issues:
        `obj?.()` and `obj?.[Symbol.iterator]`



- Matthew Robb

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
joe
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

joe
In reply to this post by joe
By the way, I don't remember having grammar issues (I use a LALR compiler-compiler).  Looking at my code, it looked like I handled it in the tokenizer stage; I added a COND_DOT token:

COND_DOT : \?\.

COND_DOT then became simply another binary operator in the Expression production.

However, this is a very simple use case.  Supporting e.g. function calls would require more tokens (which raises the question: why stop at '.'?  Should we have arithmetic versions too?).  Given the proliferation of binary operator tokens in JS, I'm not sure if this is a good thing.

Joe



On Mon, Apr 6, 2015 at 12:45 PM, joe <[hidden email]> wrote:
I hacked together something similar myself.  IIRC, this particular transformation has issues with nested operators (e.g. a.b?.c.d?.e.f?.h).  Of course that's an implementation detail, but the problem (if I'm remembering it right) is that people couldn't figure out what the implementation constraints are (I think there was consensus that the trinary transformation was unworkable), and without knowing those constraints it wasn't possible to write a spec for it.

I could be remembering all this wrong, but that's my recollection of how that conversation went.  I think the consensus was to wait for the ? operator to become more mature in other languages.

On Mon, Apr 6, 2015 at 12:19 PM, Kevin Smith <[hidden email]> wrote:
 
If we can come to an agreement on the existential operator for member
expressions, we would also be setting a precedent for other features
of the same family. For example, existential call expressions: `fn?()`
which would conditionally invoke `fn`.

In the meeting notes you linked to, Waldemar (WH) noted that some of these variations may have grammar issues.

Although not strictly ambiguous with conditional expressions, `fn ? ()` would require the use of YACG (yet another cover grammar).

Also, what about computed property names?  For example:  `obj ? [Symbol.iterator]`.  I'm not sure that even YACG will help here.

(Thanks for compiling the list of previous threads BTW).


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Brendan Eich-2
joe wrote:
> By the way, I don't remember having grammar issues (I use a LALR
> compiler-compiler).  Looking at my code, it looked like I handled it
> in the tokenizer stage; I added a COND_DOT token:
>
> COND_DOT : \?\.

Did you keep backward compatibility? `x?.1:y` must continue to work.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Matthew Robb

On Mon, Apr 6, 2015 at 5:42 PM, Brendan Eich <[hidden email]> wrote:
Did you keep backward compatibility? `x?.1:y` must continue to work.

​This is why I suggested a leading operator (`?a.?b()`) because it seems like it would have the least potential for conflict with existing valid syntax​



- Matthew Robb

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Brendan Eich-2
Yeah, and it would line up with cover grammar needed for
refutable-by-default patterns.

/be

Matthew Robb wrote:

>
> On Mon, Apr 6, 2015 at 5:42 PM, Brendan Eich <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Did you keep backward compatibility? `x?.1:y` must continue to work.
>
>
> ​This is why I suggested a leading operator (`?a.?b()`) because it
> seems like it would have the least potential for conflict with
> existing valid syntax​
>
>
>
> - Matthew Robb
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Christoph Pojer
So I take it most would prefer this as a prefix operator. What would
be the next steps involved to iterate on this idea?

On Mon, Apr 6, 2015 at 3:35 PM, Brendan Eich <[hidden email]> wrote:

> Yeah, and it would line up with cover grammar needed for
> refutable-by-default patterns.
>
> /be
>
> Matthew Robb wrote:
>>
>>
>> On Mon, Apr 6, 2015 at 5:42 PM, Brendan Eich <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>     Did you keep backward compatibility? `x?.1:y` must continue to work.
>>
>>
>> This is why I suggested a leading operator (`?a.?b()`) because it seems
>> like it would have the least potential for conflict with existing valid
>> syntax
>>
>>
>>
>> - Matthew Robb
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss



--
Christoph Pojer
http://cpojer.net
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Existential Operator / Null Propagation Operator

Ron Buckton
In reply to this post by Brendan Eich-2
Wouldn't `.?` as an infix operator be unambiguous, compared to `?.`? There's no place other than decimal literals where this would be legal today, and decimal literals already require either parenthesis or an extra dot to perform a property access in any event. With that lexeme, `x.?1:y` would be unambiguously an error. `1.?x:y` is unambiguously a conditional, while `1..?x:y` is unambiguously a null-propagating property access on the numeric literal `1.`.

Ron


-----Original Message-----
From: es-discuss [mailto:[hidden email]] On Behalf Of Brendan Eich
Sent: Monday, April 6, 2015 3:35 PM
To: Matthew Robb
Cc: es-discuss
Subject: Re: Existential Operator / Null Propagation Operator

Yeah, and it would line up with cover grammar needed for refutable-by-default patterns.

/be

Matthew Robb wrote:

>
> On Mon, Apr 6, 2015 at 5:42 PM, Brendan Eich <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Did you keep backward compatibility? `x?.1:y` must continue to work.
>
>
> ​This is why I suggested a leading operator (`?a.?b()`) because it
> seems like it would have the least potential for conflict with
> existing valid syntax​
>
>
>
> - Matthew Robb
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Brendan Eich-2
In reply to this post by Christoph Pojer
Implement it; user-test it; auto-check the grammar for ambiguity and
other problems.

/be

Christoph Pojer wrote:

> So I take it most would prefer this as a prefix operator. What would
> be the next steps involved to iterate on this idea?
>
> On Mon, Apr 6, 2015 at 3:35 PM, Brendan Eich<[hidden email]>  wrote:
>> Yeah, and it would line up with cover grammar needed for
>> refutable-by-default patterns.
>>
>> /be
>>
>> Matthew Robb wrote:
>>> On Mon, Apr 6, 2015 at 5:42 PM, Brendan Eich<[hidden email]
>>> <mailto:[hidden email]>>  wrote:
>>>
>>>      Did you keep backward compatibility? `x?.1:y` must continue to work.
>>>
>>>
>>> This is why I suggested a leading operator (`?a.?b()`) because it seems
>>> like it would have the least potential for conflict with existing valid
>>> syntax
>>>
>>>
>>>
>>> - Matthew Robb
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Dmitry Soshnikov
In reply to this post by Christoph Pojer
On Mon, Apr 6, 2015 at 11:33 AM, Christoph Pojer <[hidden email]> wrote:
Tim Yung and I have hacked on a reference implementation for the
"Existential Operator" using esprima-fb and jstransform: "a?.b"

Example:

`a?.b` => `(a == null ? void 0 : a.b)`
`a?.b.c` => `(a == null ? void 0 : a.b.c)`

This must also make sure that `a` only gets evaluated a single time.

Based on previous discussions on es-discuss and TC39, it seems that
this was tabled for ES6. I think now is a good time to bring it up for
ES7. There is precendence for this feature in other languages - it was
recently added to C# and Hack and has always been in CoffeeScript.
TypeScript is waiting for TC39:
https://github.com/Microsoft/TypeScript/issues/16

In the past, this topic has invited a lot of bikeshedding, but I'd
like us to look past this. Several communities within and outside the
JS community have identified the need for this operator. My
understanding is that a decision needs to be made about whether the
operator should short-circuit additional invocations in the call chain
if the operand is null (aka. null propagation).

For example, if `a` is null, should `a?.b.c`:

1) evaluate to `(void 0).c` and throw a TypeError?
2) short-circuit at `a` and return `void 0`?

It appears that C# chose option #2 whereas Hack and CoffeeScript chose
option #1. Our current implementation chose option #1

Hold on, I guess it's a typo, since as discussed in the internal conversation, and based on the implementation, your current prototype transform implements option (2). I.e. it's not yet compositional. CoffeeScript also has option (2), and is not compositional, since:

`a?.b.c` and `(a?.b).c` have different semantics in case if `a` is `null`.
 
but we'd be
happy to build a reference implementation for option #2.


Yeah, (2) will make it compositional.
 
I recall that another issue was that of transitivity. Right now,
(a.b).c and a.b.c are equivalent. (a?.b).c and a?.b.c would not be
equivalent expressions. I think we need some input from the people on
this list about whether this is okay or why we value transitivity for
this operator.


Yeah, potentially we could agree it's being non-compositional. Otherwise, it will be full-chain "verbose" version. I.e. to get a null-safe `d` property, you should write `?` after each property access:

```
var v = a?.b?.c?.d
```

In other words, it's the same as:

```
var v = (((a?.b)?.c)?.d)
```

and in this case it becomes compositional (the semantics doesn't change whether you apply grouping operator or not).

But again, as was mentioned in [1], probably it's "too verbose", and hence may not hit standardization. I'd say it's fine -- it works in most of the case, and usually should not be that verbose. OTOH, we still may have a non-compositional (short-circuiting) version.

FWIW, in Hack programming language I also implemented the "verbose" version, hence it's compositional. The details of the implementation can be found in [2] (we've just recently added it to Hack).

On the topic whether it should be prefix or postfix: I'd personally prefer postfix, since it will be intuitive from other languages. However, if we won't be able to solve all grammar challenges, prefix version could be fined as well.

 
Dmitry

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Dmitry Soshnikov
On Mon, Apr 6, 2015 at 6:35 PM, Dmitry Soshnikov <[hidden email]> wrote:
On Mon, Apr 6, 2015 at 11:33 AM, Christoph Pojer <[hidden email]> wrote:
Tim Yung and I have hacked on a reference implementation for the
"Existential Operator" using esprima-fb and jstransform: "a?.b"

Example:

`a?.b` => `(a == null ? void 0 : a.b)`
`a?.b.c` => `(a == null ? void 0 : a.b.c)`

This must also make sure that `a` only gets evaluated a single time.

Based on previous discussions on es-discuss and TC39, it seems that
this was tabled for ES6. I think now is a good time to bring it up for
ES7. There is precendence for this feature in other languages - it was
recently added to C# and Hack and has always been in CoffeeScript.
TypeScript is waiting for TC39:
https://github.com/Microsoft/TypeScript/issues/16

In the past, this topic has invited a lot of bikeshedding, but I'd
like us to look past this. Several communities within and outside the
JS community have identified the need for this operator. My
understanding is that a decision needs to be made about whether the
operator should short-circuit additional invocations in the call chain
if the operand is null (aka. null propagation).

For example, if `a` is null, should `a?.b.c`:

1) evaluate to `(void 0).c` and throw a TypeError?
2) short-circuit at `a` and return `void 0`?

It appears that C# chose option #2 whereas Hack and CoffeeScript chose
option #1. Our current implementation chose option #1

Hold on, I guess it's a typo, since as discussed in the internal conversation, and based on the implementation, your current prototype transform implements option (2). I.e. it's not yet compositional. CoffeeScript also has option (2), and is not compositional, since:

`a?.b.c` and `(a?.b).c` have different semantics in case if `a` is `null`.
 
but we'd be
happy to build a reference implementation for option #2.


Yeah, (2) will make it compositional.
 

Err, option (1) I meant of course.

Dmitry 

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Kevin Smith
We should perhaps review this old thread:


for another possible way to avoid non-compositionality.  (Look for the suggestion about "Nil".  It's basically an exotic falsey object which returns itself for any property lookups or calls.)


On Mon, Apr 6, 2015 at 10:05 PM, Dmitry Soshnikov <[hidden email]> wrote:
On Mon, Apr 6, 2015 at 6:35 PM, Dmitry Soshnikov <[hidden email]> wrote:
On Mon, Apr 6, 2015 at 11:33 AM, Christoph Pojer <[hidden email]> wrote:
Tim Yung and I have hacked on a reference implementation for the
"Existential Operator" using esprima-fb and jstransform: "a?.b"

Example:

`a?.b` => `(a == null ? void 0 : a.b)`
`a?.b.c` => `(a == null ? void 0 : a.b.c)`

This must also make sure that `a` only gets evaluated a single time.

Based on previous discussions on es-discuss and TC39, it seems that
this was tabled for ES6. I think now is a good time to bring it up for
ES7. There is precendence for this feature in other languages - it was
recently added to C# and Hack and has always been in CoffeeScript.
TypeScript is waiting for TC39:
https://github.com/Microsoft/TypeScript/issues/16

In the past, this topic has invited a lot of bikeshedding, but I'd
like us to look past this. Several communities within and outside the
JS community have identified the need for this operator. My
understanding is that a decision needs to be made about whether the
operator should short-circuit additional invocations in the call chain
if the operand is null (aka. null propagation).

For example, if `a` is null, should `a?.b.c`:

1) evaluate to `(void 0).c` and throw a TypeError?
2) short-circuit at `a` and return `void 0`?

It appears that C# chose option #2 whereas Hack and CoffeeScript chose
option #1. Our current implementation chose option #1

Hold on, I guess it's a typo, since as discussed in the internal conversation, and based on the implementation, your current prototype transform implements option (2). I.e. it's not yet compositional. CoffeeScript also has option (2), and is not compositional, since:

`a?.b.c` and `(a?.b).c` have different semantics in case if `a` is `null`.
 
but we'd be
happy to build a reference implementation for option #2.


Yeah, (2) will make it compositional.
 

Err, option (1) I meant of course.

Dmitry 

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Brendan Eich-2
In reply to this post by Ron Buckton
That (putting the ? second) works for . ( and [, true. It's backwards
compared to other languages, though. Oh well.

The deeper issue is semantic, assuming a viable syntax. See ksmith's
latest message.

/be

Ron Buckton wrote:
> Wouldn't `.?` as an infix operator be unambiguous, compared to `?.`? There's no place other than decimal literals where this would be legaltoday,  and decimal literals already require either parenthesis or an extra dot to perform a property access in any event. With that lexeme, `x.?1:y` would be unambiguously an error. `1.?x:y` is unambiguously a conditional, while `1..?x:y` is unambiguously a null-propagating property access on the numeric literal `1.`.
>
> Ron
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Herby Vojčík
In reply to this post by Kevin Smith


Kevin Smith wrote:
> We should perhaps review this old thread:
>
> https://esdiscuss.org/topic/fail-fast-object-destructuring-don-t-add-more-slop-to-sloppy-mode
>
> for another possible way to avoid non-compositionality.  (Look for the
> suggestion about "Nil".  It's basically an exotic falsey object which
> returns itself for any property lookups or calls.)
>

Yeah, that's the Null Pattern I mentioned few posts before. I remember I
suggested this to be part of the language itself, as a first-class
member, but it seems it wasn't legible; OTOH, it seemed to be good
enough to use while still in the level of references, but when coming
back to values, it was suggested to be changed to undefined.

It is still interesting question if it could be part of the language
itself, but even if not and only applicable as a reference, it can be a
good solution (it that case a?.b.c would yield undefined, not an error
in case a is null).

Herby
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Nick Krempel
In reply to this post by Christoph Pojer
On 6 April 2015 at 19:33, Christoph Pojer <[hidden email]> wrote:
`a?.b` => `(a == null ? void 0 : a.b)`
`a?.b.c` => `(a == null ? void 0 : a.b.c)`
 
Would it not be more generally useful if it returned "a" rather than "void 0" in the appropriate case, that is:

`a?.b` => `(a == null ? a : a.b)`

This way the notion of nullness/undefinedness the user is working with would be preserved.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Existential Operator / Null Propagation Operator

Nick Krempel
In reply to this post by Jordan Harband
On 6 April 2015 at 20:01, Jordan Harband <[hidden email]> wrote:
If I want the short circuit in option 1, I'd do `a?.b?.c` to indicate that, whereas in option 2 if I don't want the short circuit, I'm forced to use separate variables.

Worth noting that an option 1 `a?.b?.c` differs from an option 2 `a?.b.c` in that the latter is effectively asserting that if a != null then its b property is also != null, whereas the former is more lenient in what it accepts.

Also you are not forced to use separate variables in option 2, you can just use parentheses: `(a?.b).c` - hence the whole discussion of lack of transitivity (more correctly, associativity) for option 2. Or did I misunderstand what you're trying to achieve?



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
123