Existential Operator / Null Propagation Operator

Claude Pache claude.pache at gmail.com
Wed Apr 8 15:18:51 UTC 2015


> Le 7 avr. 2015 à 21:09, Herby Vojčík <herby at mailbox.sk> a écrit :
> 
> 
> 
> Kevin Smith wrote:
>> 
>> > Plus, it can be used for "normalizing" null/undefined to undefined:
>> >
>> >  var normalizedFoo = ?foo;
>> >
>> > Seems sort of nice that it is separated and there are no special
>> operations for ?., ?(, ?[.
>> 
>> I agree, that is nice.  But how does Nil get transformed into undefined?
> 
> While you do operations like call, construct, get on the reference (obtaining another reference), it shortcuts to return Nil. Whenever you are not in position to shortcut ref-to-ref (end of expression, for example), and you actually needs a value, it just converts to undefined.
> 
> ?a.b()['foo'] => "smalltalk-like"
>  (((('a' asRefIn: env) nilRefIfValueNullOrUndefined "ref, may be nil"
>  at: 'b') "returns ref, may be Nil"
>  callWithArguments: #()) "returns ref, may be Nil"
>  at: 'foo') "returns ref, may be Nil")
>  value "now, value is needed, ref needs to dereference"
> 
> Hopefully this sheds some light. If not, then I don't know how to explain it someone with better pedagogy skill must weight in.

Here is another, more thorough explanation (and how it could be implemented in the spec):

We introduce a special unique additional Reference [6.2.3 ReferenceType], that we call “the Nil Reference”. Unlike other resolvable References, it does not have a concrete binding at its backend, but it is more like a `/dev/null` or `/dev/zero` device. The Nil Reference has the following properties:

* when read [6.2.3.1 GetValue], it produces `undefined`;

* when written [6.2.3.2 PutValue] or deleted [12.5.4 deleteOperator], it acts like a blackhole;

* as a more exotic behaviour, when it appears when evaluating the leftmost term of a property accessor [12.3.2 PropertyAccessors] or a function call [12.3.4 FunctionCalls], it is not dereferenced to `undefined` so that a TypeError would be thrown. Rather, the subexpression evaluates to the Nil Reference again. For example, here is how some algorithms of the of the spec could be modified in order to implement the "forwarding" behaviour of the Nil Reference:

    MemberExpression : MemberExpression [ Expression ]   (section 12.3.2.1)

    1. Let `baseReference` be the result of evaluating MemberExpression.
    2. ReturnIfAbrupt(`baseReference`).
    3. **If `baseReference` is the Nil Reference, return the Nil Reference.**
    4. Let `baseValue` be RequireObjectCoercible(GetValue(`baseReference`)).
    5. ReturnIfAbrupt(`baseValue`).
    6, Let `propertyNameReference` be the result of evaluating Expression.
    7. Let `propertyKey` be ToPropertyKey(GetValue(`propertyNameReference`)).
    8. ReturnIfAbrupt(`propertyKey`).
    9. Return a Reference whose base is `baseValue` and whose referenced name is `propertyKey`, (and whose “strict” flag, etc.)


    CallExpression : MemberExpression Arguments    (section 12.3.4.1)

    1. Let `ref` be the result of evaluating MemberExpression.
    2. ReturnIfAbrupt(`ref`).
    3. **If `ref` is the Nil Reference, return the Nil Reference.**
    4. Let `func` be GetValue(`ref`).
    5. etc.


[6.2.3 ReferenceType]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-reference-specification-type <http://people.mozilla.org/~jorendorff/es6-draft.html#sec-reference-specification-type>
[6.2.3.1 GetValue]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-getvalue <http://people.mozilla.org/~jorendorff/es6-draft.html#sec-getvalue>
[6.2.3.2 PutValue]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-putvalue <http://people.mozilla.org/~jorendorff/es6-draft.html#sec-putvalue>
[12.5.4 deleteOperator]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-delete-operator <http://people.mozilla.org/~jorendorff/es6-draft.html#sec-delete-operator>
[12.3.2 PropertyAccessors]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-property-accessors <http://people.mozilla.org/~jorendorff/es6-draft.html#sec-property-accessors>
[12.3.4 FunctionCalls]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-calls <http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-calls>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150408/481fe91c/attachment.html>


More information about the es-discuss mailing list