On Wed, May 21, 2014 at 8:33 AM, Claude Pache <claude.pa...@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
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to