Repository: tc39/ecma262

Issue #497: eliminating implicit conversions to/from Completion Records
Created: 2016-03-26T15:15:13Z
Recap:
Section 6.2.2.2 "Implicit Completion Values" says:

Unless it is otherwise obvious from the context, an algorithm statement that returns a value that is not a Completion Record, such as: Return "Infinity" means the same thing as: Return NormalCompletion("Infinity").

and

Any reference to a Completion Record value that is in a context that does not explicitly require a complete Completion Record value is equivalent to an explicit reference to the [[Value]] field of the Completion Record value unless the Completion Record is an abrupt completion.

That is, there are implicit conversions to and from Completion Records.
Reaction:
In #253 (comment), @rossberg-chromium said:

The spec should not be optimised for maximum brevity but for maximum clarity. I think the implicit conversion from completion records to their values is actively harmful in that regard.

And in #486 (comment), @bterlson said:

There is a rule in 5.2 [sic] that allows us to treat a completion record as if it were a value but it's something I'd like to get away from.

In #253 (comment), I agreed, and said:

I've thought of an approach that I think would eliminate most of these conversions. I'll raise it in another issue when I have some time.

This post outlines that approach.  (I was hoping to submit a pull request, but now I'm not sure I'll have time in the near future.)

The basic idea is to do away with "normal" completion records.
That is, anywhere that an algorithm currently deals with a Completion Record whose [[Type]] is normal, instead just use whatever the [[Value]] of that record is. (You can ignore the [[Target]], it's always empty.)
Things that would disappear:

All of 6.2.2.2.
NormalCompletion()
Completion()
Steps of the form If val is Completion Record, let val be val.[[Value]] in the definition of ReturnIfAbrupt and "!".

Section 6.2.2, rather than defining "Completion Record", would define "AbruptCompletion Record".
For terminology, you could say something like: a "completion value" is either an "abrupt completion value" (i.e., an AbruptCompletion Record) or a "normal completion value" (i.e., empty or an ECMAScript language value).
The part of this approach that requires some work is to find all the algorithmic steps that currently deal with a Completion Record that might be a Normal Completion, and re-code them to deal with a 'completion value' that might be a 'normal completion value'. I'm guessing you could find all the places that might need to change by searching for [[Type]], [[Target]], and [[Value]], but that's just a guess.
I can volunteer to do the work, but as I say above, I'm not sure how soon I could deliver, so someone else might like to take it on.

Duplicate issue #1572: ! shorthand for completion record [[Value]] extraction is unnecessary
Created: 2019-06-07T05:21:46Z
In §5.2.3.4 ReturnIfAbrupt Shorthands, we define a shorthand ! that's not really related to ReturnIfAbrupt. This shorthand asserts that the completion record is a normal completion and extracts its [[Value]]. But at the end of §5.2.3.1 Implicit Completion Values, we say

Any reference to a Completion Record value that is in a context that does not explicitly require a complete Completion Record value is equivalent to an explicit reference to the [[Value]] field of the Completion Record value unless the Completion Record is an abrupt completion.

I think we should either

remove this clause and use the ! shorthand or explicit [[Value]] extraction throughout the spec, or
remove the ! shorthand, its usages, and any explicit [[Value]] extraction

Closing comment (2019-06-18T00:49:05Z): @jmdyck I think it would be useful to make it at the call site as well as the declaration site.
The thing I am envisioning is:

Algorithms which never return abrupt completions are marked as such, and written so that they return unwrapped values, and are consumed as such.
Algorithms which sometimes return abrupt completions are marked as such, and written so that they always return completion records. To return a value they would need to explicitly return NormalCompletion(value).*

At a call site which knows that its particular usage will always result in a normal completion, the completion is unwrapped with !.
At a call site which does not know this,

If it would do what ReturnIfAbrupt does, it unwraps the completion with ?.
Otherwise, when it needs to handle abrupt completions itself (e.g. in promise logic), it does not use  a macro but always handles the value returned by the call as a completion record.





And then get rid of all implicit conversions, both from and to completion records (except possibly as in the footnote below).
This is similar to #497, except without the mixing of completion records with non-completion values. I'm sure someone has proposed this before.
*: I'm flexible on this last part; we could instead have spec text which says that return value in an algorithm marked as returning completion values means that it is wrapped in NormalCompletion().