The Existential Operator

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

The Existential Operator

Dmitry Soshnikov
Hi,

(I remember, I mentioned this couple of years ago, but not sure about whether it was considered, etc)

Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.

```js
var street = user.address?.street;
```

The `street` is either the value of the `user.address.street` if the `address` property exists (or even if it's an object), or `null` / `undefined` otherwise.

This (roughly) to contrast to:

```js
var street = user.address && user.address.street;
```

(the chain can be longer in many cases).

The same goes with methods:

```js
var score = user.getPlan?().value?.score;
```

If potentially it could be interesting for ES7, I'll be glad helping with the proposal, grammar and algorithm (unless it was considered previously, and decided that it's not for ES for some reason).

P.S.: I tried to solve this issue using default values of destructuring assignment, but it doesn't help actually.

Dmitry

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

Re: The Existential Operator

Claude Pache
Le 20 mai 2014 à 05:50, Dmitry Soshnikov <[hidden email]> a écrit :

> Hi,
>
> (I remember, I mentioned this couple of years ago, but not sure about whether it was considered, etc)
>
> Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.
>
> ```js
> var street = user.address?.street;
> ```
>
> The `street` is either the value of the `user.address.street` if the `address` property exists (or even if it's an object), or `null` / `undefined` otherwise.
>
> This (roughly) to contrast to:
>
> ```js
> var street = user.address && user.address.street;
> ```
>
> (the chain can be longer in many cases).
>
> The same goes with methods:
>
> ```js
> var score = user.getPlan?().value?.score;
> ```
>
> If potentially it could be interesting for ES7, I'll be glad helping with the proposal, grammar and algorithm (unless it was considered previously, and decided that it's not for ES for some reason).
>
> P.S.: I tried to solve this issue using default values of destructuring assignment, but it doesn't help actually.
>
> Dmitry

Question: What is the semantics of the following:

        a?.b.c

Is it the same thing as
       
        (a?.b).c
        (a && a.b).c

or the same thing as:

        a && a.b.c

(For the sake of the argument, just ignore the distinction between "falsy" and "null/undefined".)
If it is the second option, I fear that the semantics of the so-called "existential operator" is more complicated than just an "operator".

—Claude

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

Re: The Existential Operator

A Matías Quezada
I think the current use of this operator will only make sense if the operator interrupts the whole sentence so

    a?.b.c

Will be the same as

    a && a.b.c

And

    a?().b?.c?.d

Will be same as

    a && (x = a(), x.b && (x.b.c && x.b.c.d))

---
A. Matías Quezada
Senior Javascript Developer



2014-05-20 11:31 GMT+02:00 Claude Pache <[hidden email]>:
Le 20 mai 2014 à 05:50, Dmitry Soshnikov <[hidden email]> a écrit :

> Hi,
>
> (I remember, I mentioned this couple of years ago, but not sure about whether it was considered, etc)
>
> Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.
>
> ```js
> var street = user.address?.street;
> ```
>
> The `street` is either the value of the `user.address.street` if the `address` property exists (or even if it's an object), or `null` / `undefined` otherwise.
>
> This (roughly) to contrast to:
>
> ```js
> var street = user.address && user.address.street;
> ```
>
> (the chain can be longer in many cases).
>
> The same goes with methods:
>
> ```js
> var score = user.getPlan?().value?.score;
> ```
>
> If potentially it could be interesting for ES7, I'll be glad helping with the proposal, grammar and algorithm (unless it was considered previously, and decided that it's not for ES for some reason).
>
> P.S.: I tried to solve this issue using default values of destructuring assignment, but it doesn't help actually.
>
> Dmitry

Question: What is the semantics of the following:

        a?.b.c

Is it the same thing as

        (a?.b).c
        (a && a.b).c

or the same thing as:

        a && a.b.c

(For the sake of the argument, just ignore the distinction between "falsy" and "null/undefined".)
If it is the second option, I fear that the semantics of the so-called "existential operator" is more complicated than just an "operator".

—Claude

_______________________________________________
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: The Existential Operator

Aaron Powell

It might be worthwhile keeping an eye on the C# language discussion on the same operator - http://roslyn.codeplex.com/discussions/540883

 

 

From: es-discuss [mailto:[hidden email]] On Behalf Of A Matías Quezada
Sent: Tuesday, 20 May 2014 7:56 PM
To: Claude Pache
Cc: es-discuss
Subject: Re: The Existential Operator

 

I think the current use of this operator will only make sense if the operator interrupts the whole sentence so

 

    a?.b.c

Will be the same as

 

    a && a.b.c

 

And

 

    a?().b?.c?.d

 

Will be same as

 

    a && (x = a(), x.b && (x.b.c && x.b.c.d))


---

A. Matías Quezada

Senior Javascript Developer

 

 

2014-05-20 11:31 GMT+02:00 Claude Pache <[hidden email]>:

Le 20 mai 2014 à 05:50, Dmitry Soshnikov <[hidden email]> a écrit :


> Hi,
>
> (I remember, I mentioned this couple of years ago, but not sure about whether it was considered, etc)
>
> Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.
>
> ```js
> var street = user.address?.street;
> ```
>
> The `street` is either the value of the `user.address.street` if the `address` property exists (or even if it's an object), or `null` / `undefined` otherwise.
>
> This (roughly) to contrast to:
>
> ```js
> var street = user.address && user.address.street;
> ```
>
> (the chain can be longer in many cases).
>
> The same goes with methods:
>
> ```js
> var score = user.getPlan?().value?.score;
> ```
>
> If potentially it could be interesting for ES7, I'll be glad helping with the proposal, grammar and algorithm (unless it was considered previously, and decided that it's not for ES for some reason).
>
> P.S.: I tried to solve this issue using default values of destructuring assignment, but it doesn't help actually.
>
> Dmitry

Question: What is the semantics of the following:


        a?.b.c

Is it the same thing as

        (a?.b).c
        (a && a.b).c

or the same thing as:

        a && a.b.c

(For the sake of the argument, just ignore the distinction between "falsy" and "null/undefined".)
If it is the second option, I fear that the semantics of the so-called "existential operator" is more complicated than just an "operator".

—Claude

_______________________________________________
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: The Existential Operator

Dwayne
Claude Pache, 

I had to read up on this existential operator to realize your question. In your example the variable 'a' is the target/operand of the existential operator. If 'a' isn't null or undefined then the result will be the result that you'd expect had you not used the operator, assuming theres not a TypeError in the expression. Here I choose to define an operator as a shorthand function of which I don't find overly complicated.

function example() {
  If (a !== null && a !== void(0)) return a;
  return void(0);
}

If 'a' is undefined...

var a = void(0);
example(a).b.c

Would normally throw but with the existential operator...

var result = a?.b.c

Does not.

result === void(0) // true

Another thought.

var a = {};

var result = a?.b.c;

Will throw because there can be no property 'c' on undefined.

var result = a?.b?.c; <-- Awesome semantics!

And of course: result === void(0) // true


On Tue, May 20, 2014 at 3:30 AM, Aaron Powell <[hidden email]> wrote:

It might be worthwhile keeping an eye on the C# language discussion on the same operator - http://roslyn.codeplex.com/discussions/540883

 

 

From: es-discuss [mailto:[hidden email]] On Behalf Of A Matías Quezada
Sent: Tuesday, 20 May 2014 7:56 PM
To: Claude Pache
Cc: es-discuss
Subject: Re: The Existential Operator

 

I think the current use of this operator will only make sense if the operator interrupts the whole sentence so

 

    a?.b.c

Will be the same as

 

    a && a.b.c

 

And

 

    a?().b?.c?.d

 

Will be same as

 

    a && (x = a(), x.b && (x.b.c && x.b.c.d))


---

A. Matías Quezada

Senior Javascript Developer

 

 

2014-05-20 11:31 GMT+02:00 Claude Pache <[hidden email]>:

Le 20 mai 2014 à 05:50, Dmitry Soshnikov <[hidden email]> a écrit :


> Hi,
>
> (I remember, I mentioned this couple of years ago, but not sure about whether it was considered, etc)
>
> Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.
>
> ```js
> var street = user.address?.street;
> ```
>
> The `street` is either the value of the `user.address.street` if the `address` property exists (or even if it's an object), or `null` / `undefined` otherwise.
>
> This (roughly) to contrast to:
>
> ```js
> var street = user.address && user.address.street;
> ```
>
> (the chain can be longer in many cases).
>
> The same goes with methods:
>
> ```js
> var score = user.getPlan?().value?.score;
> ```
>
> If potentially it could be interesting for ES7, I'll be glad helping with the proposal, grammar and algorithm (unless it was considered previously, and decided that it's not for ES for some reason).
>
> P.S.: I tried to solve this issue using default values of destructuring assignment, but it doesn't help actually.
>
> Dmitry

Question: What is the semantics of the following:

        a?.b.c

Is it the same thing as

        (a?.b).c
        (a && a.b).c

or the same thing as:

        a && a.b.c

(For the sake of the argument, just ignore the distinction between "falsy" and "null/undefined".)
If it is the second option, I fear that the semantics of the so-called "existential operator" is more complicated than just an "operator".

—Claude

_______________________________________________
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



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

Re: The Existential Operator

Andri Möll
In reply to this post by A Matías Quezada
Oh, one shouldn't ignore the difference between falsy and undefined. Implementing this in terms of falsyness will end up breaking someNumber?.toString() given a zero or someString?.length given an empty string. 

Andri

On 20 May 2014, at 12:55, A Matías Quezada <[hidden email]> wrote:

I think the current use of this operator will only make sense if the operator interrupts the whole sentence so

    a?.b.c

Will be the same as

    a && a.b.c

And

    a?().b?.c?.d

Will be same as

    a && (x = a(), x.b && (x.b.c && x.b.c.d))

---
A. Matías Quezada
Senior Javascript Developer



2014-05-20 11:31 GMT+02:00 Claude Pache <[hidden email]>:
Le 20 mai 2014 à 05:50, Dmitry Soshnikov <[hidden email]> a écrit :

> Hi,
>
> (I remember, I mentioned this couple of years ago, but not sure about whether it was considered, etc)
>
> Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.
>
> ```js
> var street = user.address?.street;
> ```
>
> The `street` is either the value of the `user.address.street` if the `address` property exists (or even if it's an object), or `null` / `undefined` otherwise.
>
> This (roughly) to contrast to:
>
> ```js
> var street = user.address && user.address.street;
> ```
>
> (the chain can be longer in many cases).
>
> The same goes with methods:
>
> ```js
> var score = user.getPlan?().value?.score;
> ```
>
> If potentially it could be interesting for ES7, I'll be glad helping with the proposal, grammar and algorithm (unless it was considered previously, and decided that it's not for ES for some reason).
>
> P.S.: I tried to solve this issue using default values of destructuring assignment, but it doesn't help actually.
>
> Dmitry

Question: What is the semantics of the following:

        a?.b.c

Is it the same thing as

        (a?.b).c
        (a && a.b).c

or the same thing as:

        a && a.b.c

(For the sake of the argument, just ignore the distinction between "falsy" and "null/undefined".)
If it is the second option, I fear that the semantics of the so-called "existential operator" is more complicated than just an "operator".

—Claude

_______________________________________________
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

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

smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: The Existential Operator

Brendan Eich-2
In reply to this post by Dmitry Soshnikov
Dmitry Soshnikov wrote:
Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.

Please see

http://esdiscuss.org/topic/sept-18-tc39-meeting-notes#content-2

and find "ARB: This is non-compositional". Citing text for reader convenience:

Existential Operator (strawman discussion)

(Presented by Brendan Eich, Mozilla)

Significant desire include a null and undefined check in syntax/operator form (a la coffeescipt)

    o = {}
    r = o?.p.q.r
    r = o?.p?.q.r

Mixed discussion about the needs and use cases as they apply to coffeescript code.

ARB: This is non-compositional

    o = {}
    r = o?.p.q.r
    r = (o?.p).q.r
    r = o?.p.q.r()

Results in…

    var o, r;
    o = {};
    r = o != null ? o.p.q.r : void 0;
    r = (o != null ? o.p : void 0).q.r;
    r = o != null ? o.p.q.r() : void 0;

Non-starter.

DH: Why not an operator that needs to be explicit?

    o?.p?.q?.r

LH: Why would you ever even use it on the first?

BE: Forget all of the problems with coffeescript's impl, the need exists.

YK: In the common cases, where it works, it works well. Where it doesn't, it falls apart unexpectedly.

WH: What about other contexts such as p?[x], p?.q[x], and p?(x) ? [Note that grammar problems arise for some of those.]

General agreement.

Conclusion/Resolution Seems useful, but not now. Semantics are unclear

---

The notes ended a bit too optimistically in my view! "Non-starter".

/be

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

Re: The Existential Operator

Dmitry Soshnikov
Woah! :) 2012 -- so I correctly recalled "couple of years ago". Thanks, glad it was discussed in detail.


On Tue, May 20, 2014 at 9:36 AM, Brendan Eich <[hidden email]> wrote:
Dmitry Soshnikov wrote:
Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.

Please see

http://esdiscuss.org/topic/sept-18-tc39-meeting-notes#content-2

and find "ARB: This is non-compositional". Citing text for reader convenience:

Existential Operator (strawman discussion)

(Presented by Brendan Eich, Mozilla)

Significant desire include a null and undefined check in syntax/operator form (a la coffeescipt)

    o = {}
    r = o?.p.q.r
    r = o?.p?.q.r

Mixed discussion about the needs and use cases as they apply to coffeescript code.

ARB: This is non-compositional

    o = {}
    r = o?.p.q.r
    r = (o?.p).q.r
    r = o?.p.q.r()

Results in…

    var o, r;
    o = {};
    r = o != null ? o.p.q.r : void 0;
    r = (o != null ? o.p : void 0).q.r;
    r = o != null ? o.p.q.r() : void 0;

Non-starter.


Yeah, that's the semantics CoffeeScript uses.

 

DH: Why not an operator that needs to be explicit?

    o?.p?.q?.r

LH: Why would you ever even use it on the first?

BE: Forget all of the problems with coffeescript's impl, the need exists.


OK.
 

YK: In the common cases, where it works, it works well. Where it doesn't, it falls apart unexpectedly.

WH: What about other contexts such as p?[x], p?.q[x], and p?(x) ? [Note that grammar problems arise for some of those.]

The grammar can be tweaked seems.
 

General agreement.

Conclusion/Resolution Seems useful, but not now. Semantics are unclear

Yeah, so now, when ES6 is closed, probably the topic can be reiterated later on for ES7.
 
---

The notes ended a bit too optimistically in my view! "Non-starter".


Yeah, for ES6 it's pretty optimistically :)

OK, thanks again for clarifying this Brendan, and for putting the notes here, appreciated.

The only reason I put the topic here, is (not to beat a dead horse of course), is that we recently had a long internal discussion thread about it. I first thought, that we could just implement an internal JS extension for now, and see how it goes (and if it goes well, potentially include it into ES7), but, true, it needs more clarifications and thoughts.

(still doable though)

Dmitry

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

Re: The Existential Operator

joe
How about an accumulator?  E.g., turn:

a?.b.c.d?.func();

into (if targeting ES5):

var t;
(t = a ? a.b : undefined,  
 t = t ? t.c : undefined,  
 t = t ? t.d : undefined,  
 t = t ? t.func() : undefined);

(in a proper VM you'd use the stack, of course, not a temporary variable).

Note how the presence of one ?. operator causes the entire chain (including normal .'s) to be transformed.  Not sure what the side effects of this would be, performance-wise.

Joe



On Tue, May 20, 2014 at 11:08 AM, Dmitry Soshnikov <[hidden email]> wrote:
Woah! :) 2012 -- so I correctly recalled "couple of years ago". Thanks, glad it was discussed in detail.


On Tue, May 20, 2014 at 9:36 AM, Brendan Eich <[hidden email]> wrote:
Dmitry Soshnikov wrote:
Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.

Please see

http://esdiscuss.org/topic/sept-18-tc39-meeting-notes#content-2

and find "ARB: This is non-compositional". Citing text for reader convenience:

Existential Operator (strawman discussion)

(Presented by Brendan Eich, Mozilla)

Significant desire include a null and undefined check in syntax/operator form (a la coffeescipt)

    o = {}
    r = o?.p.q.r
    r = o?.p?.q.r

Mixed discussion about the needs and use cases as they apply to coffeescript code.

ARB: This is non-compositional

    o = {}
    r = o?.p.q.r
    r = (o?.p).q.r
    r = o?.p.q.r()

Results in…

    var o, r;
    o = {};
    r = o != null ? o.p.q.r : void 0;
    r = (o != null ? o.p : void 0).q.r;
    r = o != null ? o.p.q.r() : void 0;

Non-starter.


Yeah, that's the semantics CoffeeScript uses.

 

DH: Why not an operator that needs to be explicit?

    o?.p?.q?.r

LH: Why would you ever even use it on the first?

BE: Forget all of the problems with coffeescript's impl, the need exists.


OK.
 

YK: In the common cases, where it works, it works well. Where it doesn't, it falls apart unexpectedly.

WH: What about other contexts such as p?[x], p?.q[x], and p?(x) ? [Note that grammar problems arise for some of those.]

The grammar can be tweaked seems.
 

General agreement.

Conclusion/Resolution Seems useful, but not now. Semantics are unclear

Yeah, so now, when ES6 is closed, probably the topic can be reiterated later on for ES7.
 
---

The notes ended a bit too optimistically in my view! "Non-starter".


Yeah, for ES6 it's pretty optimistically :)

OK, thanks again for clarifying this Brendan, and for putting the notes here, appreciated.

The only reason I put the topic here, is (not to beat a dead horse of course), is that we recently had a long internal discussion thread about it. I first thought, that we could just implement an internal JS extension for now, and see how it goes (and if it goes well, potentially include it into ES7), but, true, it needs more clarifications and thoughts.

(still doable though)

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: The Existential Operator

Andrea Giammarchi-2
then you could go like this ?

```javascript
function ifPresent(o, nmsp, dflt) {
  var r = nmsp.split('.').reduce(ifPresent.$, o);
  return r == null ? dflt : r;
}
ifPresent.$ = function (p, c) {
  return p ? p[c] : undefined;
};

var a = {
  b: {
    c: {
      d: 123
    }
  }
};

ifPresent(a, 'b.c.d', 456); // 123
```

FWIW I think having silent failures all over is not desirable so I'd like to know what's the concrete claimed need for this, if that's possible. (I've only read there's a need but I don't find the rationale)

Take care




On Tue, May 20, 2014 at 1:44 PM, joe <[hidden email]> wrote:
How about an accumulator?  E.g., turn:

a?.b.c.d?.func();

into (if targeting ES5):

var t;
(t = a ? a.b : undefined,  
 t = t ? t.c : undefined,  
 t = t ? t.d : undefined,  
 t = t ? t.func() : undefined);

(in a proper VM you'd use the stack, of course, not a temporary variable).

Note how the presence of one ?. operator causes the entire chain (including normal .'s) to be transformed.  Not sure what the side effects of this would be, performance-wise.

Joe



On Tue, May 20, 2014 at 11:08 AM, Dmitry Soshnikov <[hidden email]> wrote:
Woah! :) 2012 -- so I correctly recalled "couple of years ago". Thanks, glad it was discussed in detail.


On Tue, May 20, 2014 at 9:36 AM, Brendan Eich <[hidden email]> wrote:
Dmitry Soshnikov wrote:
Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.

Please see

http://esdiscuss.org/topic/sept-18-tc39-meeting-notes#content-2

and find "ARB: This is non-compositional". Citing text for reader convenience:

Existential Operator (strawman discussion)

(Presented by Brendan Eich, Mozilla)

Significant desire include a null and undefined check in syntax/operator form (a la coffeescipt)

    o = {}
    r = o?.p.q.r
    r = o?.p?.q.r

Mixed discussion about the needs and use cases as they apply to coffeescript code.

ARB: This is non-compositional

    o = {}
    r = o?.p.q.r
    r = (o?.p).q.r
    r = o?.p.q.r()

Results in…

    var o, r;
    o = {};
    r = o != null ? o.p.q.r : void 0;
    r = (o != null ? o.p : void 0).q.r;
    r = o != null ? o.p.q.r() : void 0;

Non-starter.


Yeah, that's the semantics CoffeeScript uses.

 

DH: Why not an operator that needs to be explicit?

    o?.p?.q?.r

LH: Why would you ever even use it on the first?

BE: Forget all of the problems with coffeescript's impl, the need exists.


OK.
 

YK: In the common cases, where it works, it works well. Where it doesn't, it falls apart unexpectedly.

WH: What about other contexts such as p?[x], p?.q[x], and p?(x) ? [Note that grammar problems arise for some of those.]

The grammar can be tweaked seems.
 

General agreement.

Conclusion/Resolution Seems useful, but not now. Semantics are unclear

Yeah, so now, when ES6 is closed, probably the topic can be reiterated later on for ES7.
 
---

The notes ended a bit too optimistically in my view! "Non-starter".


Yeah, for ES6 it's pretty optimistically :)

OK, thanks again for clarifying this Brendan, and for putting the notes here, appreciated.

The only reason I put the topic here, is (not to beat a dead horse of course), is that we recently had a long internal discussion thread about it. I first thought, that we could just implement an internal JS extension for now, and see how it goes (and if it goes well, potentially include it into ES7), but, true, it needs more clarifications and thoughts.

(still doable though)

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



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

Specifying the Existential Operator using Abrupt Completion

Claude Pache
In reply to this post by Dmitry Soshnikov

I have thought about the right semantics (and the issues) of the existential operator.

    user.getPlan?().value?.score;

The intended semantics of `?` is that, whenever its LHS evaluates to `null` or `undefined`,
the evaluation of the whole expression (or subexpression) is interrupted and return immediately `undefined`.
In other word, it may be seen as an abrupt completion, as demonstrated by the following expansion:

    (do {
        let result = user           // user
        result = result.getPlan // _.getPlan
        if (result == null)         // _?
            break                   // abrupt completion
        result = result.call(user)  // _()
        result = result.value       // _.value
        if (result == null)         // _?
            break                   // abrupt completion
        result = result.score       // _.score
    })

Now, it should be determined, whenever such an abrupt completion is encountered during evaluation,
in which cases it should propagate, and in which case it should be transformed into a normal completion of value `undefined`.
Roughly, property accesses and function calls should propagate it when it is found on their LHS,
and in all other cases it should be mutated it to NormalCompletion(undefined). E.g.:

    (user.getPlan?().value?.score || 0).toFixed(2) // the `||` operator interrupts the abrupt completion propagation


Here is a simple strawman that illustrates how that idea could be implemented in the spec.
It has some known (and unknown) issues, but I think it gives a good idea of the mechanism.
And it resolves quite naturally the non-compositional issue of the original strawman (see the remark at the end of the message).

The specification is patched as follows:

6.2.2 The Completion Record Specification Type

    An additional value is allowed for the [[type]] field, besides normal, break, continue, return, or throw; namely: failsoft.

6.2.3.1 GetValue(V)

An additional parameter is added to that abstract operation:

    GetValue(V, propagateFailsoft = false)

If the second argument is absent, it is presumed to be false. An additional step is prepended to the algorithm:

0. If V is an abrupt completion of [[type]] failsoft and if propagateFailsoft is false,
    a. Let V be NormalCompletion(undefined).


12.3 Left-Hand-Side Expressions

The production of MemberExpression is expanded as follows:

FailsoftMark:
    "?"

MemberExpression:
    (...)
    MemberExpression FailsoftMark

The runtime semantics is the following:

MemberExpression: MemberExpression FailsoftMark

    1. Let ref be the result of evaluating MemberExpression.
    2. Let val be GetValue(ref, true).
    3. ReturnIfAbrupt(val).
    3. If val is null or undefined,
        a. Return Completion([[type]]: failsoft, [[value]]: undefined, [[target]]: empty).
    4. Return val.

Here, there is an issue in expressions like `a.b?(c)`, because the correct `this` value of the method call won't be able to be determined.
This can be resolved by further suitable refinements.

Finally, in the algorithms involving LeftHandSideExpression's (section 12.3), some calls to GetValue(...) are replaced by GetValue(..., true).
They are:

Property Accessors
12.3.2.. Runtime Semantics: Evaluation
MemberExpression : MemberExpression [ Expression ]
Step 2. Let baseValue be GetValue(baseReference, true).

The new operator
12.3.3.1 Runtime Semantics: Evaluation
NewExpression : new NewExpression
Step 2. Let constructor be GetValue(ref, true).

ibid.
MemberExpression : new MemberExpression Arguments
Step 2. Let constructor be GetValue(ref, true).

Function Calls
12.3.4.2 Runtime Semantics: EvaluateCall
Step 1. Let func be GetValue(ref, true).

In all other cases, a call to GetValue(...) will intercept a failsoft abrupt completion and return `undefined`.


A notable fact of that strawman is that the two following expressions are equivalent:

    (a?.b).c
    a?.b.c

because evaluating a ParenthesizedExpression does not apply GetValue(...) (Section 12.2.10.4).

—Claude





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

Re: Specifying the Existential Operator using Abrupt Completion

Andreas Rossberg-4
On 21 May 2014 14:33, Claude Pache <[hidden email]> wrote:

>
> I have thought about the right semantics (and the issues) of the existential operator.
>
>     user.getPlan?().value?.score;
>
> The intended semantics of `?` is that, whenever its LHS evaluates to `null` or `undefined`,
> the evaluation of the whole expression (or subexpression) is interrupted and return immediately `undefined`.
> In other word, it may be seen as an abrupt completion, as demonstrated by the following expansion:
>
>     (do {
>         let result = user           // user
>         result = result.getPlan // _.getPlan
>         if (result == null)         // _?
>             break                   // abrupt completion

Drive-by comment: This would break the switch or loop statement
surrounding the do-expression (or be an error if there isn't any). You
need to wrap the statements into a labelled block and break that.

/Andreas


>         result = result.call(user)  // _()
>         result = result.value       // _.value
>         if (result == null)         // _?
>             break                   // abrupt completion
>         result = result.score       // _.score
>     })
>
> Now, it should be determined, whenever such an abrupt completion is encountered during evaluation,
> in which cases it should propagate, and in which case it should be transformed into a normal completion of value `undefined`.
> Roughly, property accesses and function calls should propagate it when it is found on their LHS,
> and in all other cases it should be mutated it to NormalCompletion(undefined). E.g.:
>
>     (user.getPlan?().value?.score || 0).toFixed(2) // the `||` operator interrupts the abrupt completion propagation
>
>
> Here is a simple strawman that illustrates how that idea could be implemented in the spec.
> It has some known (and unknown) issues, but I think it gives a good idea of the mechanism.
> And it resolves quite naturally the non-compositional issue of the original strawman (see the remark at the end of the message).
>
> The specification is patched as follows:
>
> 6.2.2 The Completion Record Specification Type
>
>     An additional value is allowed for the [[type]] field, besides normal, break, continue, return, or throw; namely: failsoft.
>
> 6.2.3.1 GetValue(V)
>
> An additional parameter is added to that abstract operation:
>
>     GetValue(V, propagateFailsoft = false)
>
> If the second argument is absent, it is presumed to be false. An additional step is prepended to the algorithm:
>
> 0. If V is an abrupt completion of [[type]] failsoft and if propagateFailsoft is false,
>     a. Let V be NormalCompletion(undefined).
>
>
> 12.3 Left-Hand-Side Expressions
>
> The production of MemberExpression is expanded as follows:
>
> FailsoftMark:
>     "?"
>
> MemberExpression:
>     (...)
>     MemberExpression FailsoftMark
>
> The runtime semantics is the following:
>
> MemberExpression: MemberExpression FailsoftMark
>
>     1. Let ref be the result of evaluating MemberExpression.
>     2. Let val be GetValue(ref, true).
>     3. ReturnIfAbrupt(val).
>     3. If val is null or undefined,
>         a. Return Completion([[type]]: failsoft, [[value]]: undefined, [[target]]: empty).
>     4. Return val.
>
> Here, there is an issue in expressions like `a.b?(c)`, because the correct `this` value of the method call won't be able to be determined.
> This can be resolved by further suitable refinements.
>
> Finally, in the algorithms involving LeftHandSideExpression's (section 12.3), some calls to GetValue(...) are replaced by GetValue(..., true).
> They are:
>
> Property Accessors
> 12.3.2.. Runtime Semantics: Evaluation
> MemberExpression : MemberExpression [ Expression ]
> Step 2. Let baseValue be GetValue(baseReference, true).
>
> The new operator
> 12.3.3.1 Runtime Semantics: Evaluation
> NewExpression : new NewExpression
> Step 2. Let constructor be GetValue(ref, true).
>
> ibid.
> MemberExpression : new MemberExpression Arguments
> Step 2. Let constructor be GetValue(ref, true).
>
> Function Calls
> 12.3.4.2 Runtime Semantics: EvaluateCall
> Step 1. Let func be GetValue(ref, true).
>
> In all other cases, a call to GetValue(...) will intercept a failsoft abrupt completion and return `undefined`.
>
>
> A notable fact of that strawman is that the two following expressions are equivalent:
>
>     (a?.b).c
>     a?.b.c
>
> because evaluating a ParenthesizedExpression does not apply GetValue(...) (Section 12.2.10.4).
>
> —Claude
>
>
>
>
>
> _______________________________________________
> 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: Specifying the Existential Operator using Abrupt Completion

Allen Wirfs-Brock

On May 21, 2014, at 5:56 AM, Andreas Rossberg wrote:

> On 21 May 2014 14:33, Claude Pache <[hidden email]> wrote:
>>
>> I have thought about the right semantics (and the issues) of the existential operator.
>>
>>    user.getPlan?().value?.score;
>>
>> The intended semantics of `?` is that, whenever its LHS evaluates to `null` or `undefined`,
>> the evaluation of the whole expression (or subexpression) is interrupted and return immediately `undefined`.
>> In other word, it may be seen as an abrupt completion, as demonstrated by the following expansion:
>>
>>    (do {
>>        let result = user           // user
>>        result = result.getPlan // _.getPlan
>>        if (result == null)         // _?
>>            break                   // abrupt completion
>
> Drive-by comment: This would break the switch or loop statement
> surrounding the do-expression (or be an error if there isn't any). You
> need to wrap the statements into a labelled block and break that.

Well, completion records are just a specification device and if we need a new [[type]] of abrupt completion to simplify specifying some semantics we certainly could add it.

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

Re: The Existential Operator

Claude Pache
In reply to this post by Andrea Giammarchi-2

Le 21 mai 2014 à 01:30, Andrea Giammarchi <[hidden email]> a écrit :

>
> FWIW I think having silent failures all over is not desirable so I'd like to know what's the concrete claimed need for this, if that's possible. (I've only read there's a need but I don't find the rationale)

The point of the Existential Operator in general, and of the details of its semantics in particular, is not to fail silently (although it can be abused for that), but to have a compact syntax for concrete cases where you must be prepared to receive either null/undefined or an object (as it happens when working with the DOM), and want to yield another value using a definite algorithm (accessing properties, invoking methods). Or do you think to a precise detail of the semantics of the Existential Operator, where silent failures are encouraged?

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

Re: The Existential Operator

joe
I don't think silent fails are always a bad thing.  I've been trying to make my code robust against unexpected nulls, preferably only in release mode.  That's not always easy to do, though (restricting the behavior to release builds), which is why I consciously chose to wait a year until the code was more mature.






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

Re: The Existential Operator

Axel Rauschmayer
In reply to this post by Brendan Eich-2
Dmitry Soshnikov wrote:
Will the "Existential Operator" for properly accessors be something interesting to consider for ES7 spec? Currently CoffeeScript uses it well.

Please see

http://esdiscuss.org/topic/sept-18-tc39-meeting-notes#content-2

and find "ARB: This is non-compositional".

David seems to suggest a compositional version: `o?.p?.q?.r`

I’m assuming that the left-hand side of `value?.prop` is an arbitrary value and that the property access is only made if that value is neither `undefined` nor `null`. AFAICT that’s also how CoffeeScript’s existential operator works.

I’m ambivalent about it, though: it would be useful, but would also add complexity to the language.

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de


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

Re: The Existential Operator

Andrea Giammarchi-2
In reply to this post by Claude Pache
Still haven't seen a convincing example but if generally everybody thinks is a must have I'll look quietly aside.

Take care


On Thu, May 22, 2014 at 10:17 AM, Claude Pache <[hidden email]> wrote:

Le 21 mai 2014 à 01:30, Andrea Giammarchi <[hidden email]> a écrit :

>
> FWIW I think having silent failures all over is not desirable so I'd like to know what's the concrete claimed need for this, if that's possible. (I've only read there's a need but I don't find the rationale)

The point of the Existential Operator in general, and of the details of its semantics in particular, is not to fail silently (although it can be abused for that), but to have a compact syntax for concrete cases where you must be prepared to receive either null/undefined or an object (as it happens when working with the DOM), and want to yield another value using a definite algorithm (accessing properties, invoking methods). Or do you think to a precise detail of the semantics of the Existential Operator, where silent failures are encouraged?

—Claude


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

Re: The Existential Operator

C. Scott Ananian
I've written a lot of coffeescript code and the existential operator is indeed one of the joys of the language.  I like David's attempt to bring rigor and compositionality to it.
  --scott

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

Re: The Existential Operator

Andrea Giammarchi-2
I never had the need to write CoffeeScript, and if that's the joy, why not just sticking in there? :P

Anyway, I am off this topic ... no problem at all. I will use, and hopefully never abuse, once it lands in JS but as everything is for JS, the hype and the abuse is trivially reached, and this is in my opinion an evil operator.

Best Regards


On Thu, May 22, 2014 at 4:11 PM, C. Scott Ananian <[hidden email]> wrote:
I've written a lot of coffeescript code and the existential operator is indeed one of the joys of the language.  I like David's attempt to bring rigor and compositionality to it.
  --scott


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

Re: The Existential Operator

Brendan Eich-2
In reply to this post by C. Scott Ananian
C. Scott Ananian wrote:
> I've written a lot of coffeescript code and the existential operator
> is indeed one of the joys of the language.  I like David's

You mean Claude's?

/be
> attempt to bring rigor and compositionality to it.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12