Specifying the Existential Operator using Abrupt Completion

John Lenz concavelenz at gmail.com
Wed Feb 3 19:28:39 UTC 2016


Did this happen?  I would like to see some progress here.


On Wed, Jan 13, 2016 at 10:51 AM, Claude Pache <claude.pache at gmail.com>
wrote:

>
> Le 13 janv. 2016 à 18:06, C. Scott Ananian <ecmascript at cscott.net> a
> écrit :
>
> On Wed, May 21, 2014 at 8:33 AM, Claude Pache <claude.pache at gmail.com>
> 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
>>         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
>>
>
> Whatever happened to this proposal?  I'd love to see a proposal for the
> existential operator continue to move ahead, and Claude's was the best one,
> IMO.
>  --scott
>
>
>
> Since nobody seems to have taken this, I will submit a formal proposal for
> stage 0 very soon (before two weeks).
>
> With respect to the above old draft, my proposal will use a special
> Reference instead of a special abrupt completion (see [1]); but the basic
> idea remains the same: the essential difference is that the spec will
> propagate the special Reference at chosen points instead of catching the
> special abrupt completion everywhere else.
>
> The exact syntax will remain open, as `?.` has some issues, and there are
> nonproblematic alternatives such as `.?` and `..`; but the semantics should
> be ok.
>
> [1]:
> https://esdiscuss.org/topic/existential-operator-null-propagation-operator#content-42
>
> —Claude
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160203/b1747134/attachment.html>


More information about the es-discuss mailing list