Proposal: The Conditional Fail and Recover Operators; or: a more generic Existential Operator

joe joeedh at gmail.com
Tue May 27 10:58:45 PDT 2014


I like the basic idea.  I think the problem is that this is too original
for a language like ECMAScript.  There isn't any prior body of experience
of what the use cases and consequences would be.

I'd suggest submitting the proposal to the Traceur people:

https://code.google.com/p/traceur-compiler/

I might play with this in my own in-house ES6 compiler, but unfortunately
I'm the only using it (heh, or who would want too; it's terrible code;
purely a production tool).

This gives me another idea.  We need a community wiki for new, experimental
language ideas.  A kind-of pre-strawman wiki, I guess.  Someplace where
people could post proposals, experimental compiler projects like Tracuer
(and even related languages like CoffeeScript), could implement them and
post feedback, etc.  Proposals could then be forwarded to the ecmascript
committee after accumulating enough experience of how they work in practice.

Best,
Joe

On May 27, 2014 12:03 AM, "Claude Pache" <claude.pache at gmail.com> wrote:

>
> Since nobody gave their advice, I'll give my own one :-)
>
> The particular case of the Existential Operator (conditional property
> access and conditional method call) is probably the more usual one.
> The case that I 've come across, which is maybe the more common one not
> covered by the Existential Operator,
> consists of using a static method, but thinking of it as if it were a
> method of its first argument.
> Some syntactic sugar could help to both replace it to the correct position
> (at the right side of the object)
> and integrate it well with the Existential Operator.
> Thus, I think we could explore rather that direction.
>
> Ok, I stop my monologue here...
>
> —Claude
>
> Le 23 mai 2014 à 09:18, Claude Pache <claude.pache at gmail.com> a écrit :
>
>
> Le 22 mai 2014 à 23:58, Claude Pache <claude.pache at gmail.com> a écrit :
>
> Hi,
>
> Today, I came to a case where I wanted to grab a reference to some getter
> of the DOM,
> but to not fail if it doesn't exists:
>
> ```javascript
> try {
>   originalElementsGetter =
> Object.getOwnPropertyDescriptor(window.HTMLFormElement.prototype,
> 'elements').get
> }
> catch(e) {
>   originalElementsGetter = undefined
> }
> ```
>
> (If you are curious: the context is monkey-patching `<form>.elements`, so
> that it includes
> the `<output>` elements of the form, for I've just discovered that IE
> forgets to include them.)
>
> This seems to be a typical case for the Existential Operator (?.) we spoke
> recently about
> (although, in my precise case, a try/catch does the trick).
> However, the Existential Operator works only on properties and methods:
>
> ```javascript
> // Bad: if window.HTMLFormElement?.prototype is undefined,
> Object.getOwnPropertyDescriptor will protest loudly.
> originalElementsGetter =
> Object.getOwnPropertyDescriptor(window.HTMLFormElement?.prototype,
> 'elements')?.get
>
> // Here is what I could use:
> Object.defineProperty(Object.prototype, '$getOwnPropertyDescriptor', {
>   value: function(prop) { return Object.getOwnPropertyDescriptor(this,
> prop) }
> , writable: true
> , configurable: true
> })
> oldElementsGetter =
> window.HTMLFormElement?.prototype?.$getOwnPropertyDescriptor('elements')?.get
> ```
>
> Can we do better?
>
> I want to propose a mechanism that can simply express the following
> (only partially fulfilled by the Existential Operator):
>
> 1. check for nully (null or undefined) values at precise spots of an
> expression being evaluated;
> 2. if a nully is found, stop the evaluation of the entire current
> (sub)expression, and yield undefined;
> 3. or, instead of yielding undefined, provide an alternate value;
> 4. and be able to determine precisely what "the current subexpression" of
> point 2 means.
>
> So, let's introduce the Conditional Fail Operator (`??`), and, its
> counterpart, the Recover Operator (`!!`).
> (You could think of them as a throw/catch-like mechanism, or, better, as a
> break/block-like mechanism.)
> For the sake of illustration, I have artificially lengthen my original
> example:
>
> ```javascript
> originalElementsGetter =
> Object.getOwnPropertyDescriptor(window.HTMLFormElement??.prototype??,
> 'elements')??.get??
>                         !!
> Object.getOwnPropertyDescriptor(window.HTMLElement??.prototype??,
> 'elements')??.get??
>                         !!
> Object.getOwnPropertyDescriptor(window.Element??.prototype??,
> 'elements')??.get
> ```
>
> The semantics are the following:
>
> * `??` is a unary operator that is used as suffix. If its operand is nully
> (null or undefined),
>   the evaluation of a certain expression (more precisely defined below)
> that it is part of, fails immediately.
>   Otherwise, the operand is just returned as is.
> * `!!` is a short-circuiting binary operator. It evaluates its LHS.
>   If the evaluation is not interrupted by a `??`, it returns the result.
>   But if the evaluation is interrupted by a `??`, it evaluates its RHS and
> returns the result.
> * For any assignement operator (`=`, `+=`, etc.), if the evaluation of its
> RHS is interrupted by a `??`,
>   the RHS is replaced by `undefined` and the assignment is performed
> normally.
> * All other operators and function calls are transparent to the failure
> signal send by `??`
>   (you have to stop it by an explicit `!!`).
>
>
> I see a nasty footgun in the last two bullets, in case someone refactors
> from `foo.bar = baz??` to `fooMap.set('bar', baz??)`, for the latter will
> fail silently.
> But we do want function calls to be transparent to  `??`-failure signals,
> as it can seen in my original example.
> The best alternative I can see, is the following:
>
> * All operators (excluding `!!`, of course, but including assignments) and
> function calls are transparent to failure signals.
> * If a failure signal remains uncaught, an error is thrown (and this
> condition may even be statically determined and produce an early error).
>    This will catch (!) early failed-assignment bugs, and force the
> programmer to be more explicit.
>
> With this amendment, my example must be completed with a final `!!
> undefined`:
>
> ```javascript
> originalElementsGetter =
> Object.getOwnPropertyDescriptor(window.HTMLFormElement??.prototype??,
> 'elements')??.get??
>                         !!
> Object.getOwnPropertyDescriptor(window.HTMLElement??.prototype??,
> 'elements')??.get??
>                         !!
> Object.getOwnPropertyDescriptor(window.Element??.prototype??,
> 'elements')??.get??
>                         !! undefined
> ```
>
> —Claude
>
>
> As I have shown in [1], it seems relatively easy to spec such a behaviour
> using a custom Abrupt Completion.
> The proposed spec needs to be refined in order to avoid precocious
> GetValue(...) calls,
> but I am able to write a complete strawman in case there is interest.
>
> WDYT?
>
> —Claude
>
> [1]
> http://esdiscuss.org/topic/specifying-the-existential-operator-using-abrupt-completion
>
>
>
> _______________________________________________
> 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/20140527/73e276e8/attachment-0001.html>


More information about the es-discuss mailing list