-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Notate abstract ops that can and cannot throw #253
Comments
What about the case where the result of In general I love this idea - being explicit about what can throw and what can't seems like an overall improvement. |
|
Sounds good - I like having an explicit "this is for side effects" mechanism like "Perform". |
Here's what I said when this was raised in the ecmarkup repo: Presumably "Perform AbstractOp(x)" implies not just that AbstractOp doesn't throw, but also that it doesn't return anything useful (via normal completion). (Or at least, that these things are known to be true for the particular arguments being passed.)
To generalize your suggestion, I think it would be useful (though even more work) if every operation had a "header" that systematically listed/described the operation's inputs (parameters) and outputs (returns). (Currently, preambles give some of this info, but not consistently or completely.) E.g., outputs/returns might say something like:
So the throw/nothrow distinction would be captured by whether any abrupt returns are listed. |
@jmdyck: that would be amazing, but much work... I think we can probably get there eventually by going down the path of incrementally adding !. Note that I fully support ! as a short-hand for "Assert: previous thing is not an abrupt completion". We can probably just start the incremental addition by doing a similar regexp replace as we did to kick off the ? conversion. |
I'm a little worried about extending the ECMASpeak programming language too fast. The RIA shorthand was a good buy in terms of readability/writability, but I'm not so sure about "!". |
I'm prepared to do the work if we can agree on a "header" syntax. |
I'm a fan of !. It fixes two important problems with the current spec:
I am less of a fan of the header syntax, but some mock-up screenshots could possibly convince me. |
No, it is a specified and documented feature of completion records to allow implicit access to the [[value]] field (cf. 6.2.2.2). How about doing it the other way around: Explicitly state with |
@anba, please no. 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. There are already too many hidden conventions going on in the spec (a criticism I keep hearing from fellow V8 implementers trying to make sense of it every other day). |
Yes, that is what I meant in the parenthetical. |
I agree. (And also the reverse implicit conversion.) 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. |
I want to support the general position expressed by @rossberg-chromium above. Maximizing clarity (and particularly for occasional readers should be among the highest priorities. Most readers of the spec. are not spending 8 hours a day emerged within it. More likely they are occasionally looking up some specific details. They may or may not have read the clause 5 conversions and even if they have they may not remember them what they read. @domenic things like CreateDataProperty(array, ToString(n), e) is used in situations where n is known to have a value that will convert to a string, without error. Most typically this is an integer valued index variable of a algorithmic loop. I considered making the conversion from completion to value explicit but found that formulation to be less readable. |
Going to close this issue as I believe we have satisfied the original request. |
I don't believe we have. The first bullet point is mostly implemented, but the overall request motivating it (as outlined in the subsequent ones) remains open. |
Oh I see, sorry about that. |
Is this really fixed? |
The only abstract operations that can throw now return a completion record; those that can't, don't. It's possible it's not being noted in the rendering just yet? cc @bakkot @michaelficarra to confirm |
I think I see. Wow, that is really unfortunate, for the reasons I argued long ago in #486 (comment) and elsewhere. I wonder how many places in HTML/Web IDL will need updating to remove the ! prefix they've been using. Oh well. I'll note that it seems like this idea doesn't hold for abstract/internal methods, e.g. https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getprototypeof returns a completion but cannot throw, and similarly for https://tc39.es/ecma262/#sec-declarative-environment-records-hasbinding-n . But I can understand why that would happen. |
It's true that for internal method overloads where some of them throw, the ones that don't still need to return a completion. |
@domenic re
We've adopted the convention (enforced by tooling) that every call of an operation which returns a completion record is of the form (The |
Does HTML / WebIDL call many AOs that don't actually return completions? My intuition would be that it doesn't actually, so relatively few sites would need changing. Edit: Upon looking in HTML the answer is actually yes, because there are several calls to predicates that now just return a boolean. I can prepare a PR for that. |
Just skimming https://webidl.spec.whatwg.org/#index-defined-elsewhere: MakeBasicObject, CanonicalNumericIndexString, GetFunctionRealm, IsConstructor, ... I'd guess maybe 1/4 of all abstract ops? |
Once the updated ecma262 biblio is published (for the first time since 2016...) it would probably be pretty easy to check those with tooling. I note that In an ideal world, tooling would do the same checks ecma262 does, so that authors actually have to deal with possible exceptions for operations which can sometimes throw. That's the main reason we did it this way: rather than just sprinkling |
As part of the tc39/ecma262#2547 the JavaScript specification has reformed how it deals with Completion Records, and thus what abstract operations can return. See tc39/ecma262#253 (comment) for a brief description of when to use ? vs. ! vs. nothing at all. Additional minor fixes: * Replace uses of ObjectCreate (which no longer exists) with OrdinaryObjectCreate. * Replace "Rethrow any exceptions" with the ? syntax. * Use ? with GetFunctionRealm, which can throw due to revoked proxies.
As part of the tc39/ecma262#2547 ecma262 has reformed how it deals with Completion Records. See tc39/ecma262#253 (comment) for a brief description of when to use ? vs. ! vs. nothing at all.
As part of the tc39/ecma262#2547 the JavaScript specification has reformed how it deals with Completion Records, and thus what abstract operations can return. See tc39/ecma262#253 (comment) for a brief description of when to use ? vs. ! vs. nothing at all. Additional minor fixes: * Replace uses of ObjectCreate (which no longer exists) with OrdinaryObjectCreate. * Replace "Rethrow any exceptions" with the ? syntax. * Use ? with GetFunctionRealm, which can throw due to revoked proxies.
In streams, which is heavily promise-based, there are a lot of abstract operations that cannot throw. The ES spec has these too, in smaller number.
Of course, this kind of nothrow vs. throw characteristic can be contagious. If you only use nothrow abstract ops in your abstract op, then your abstract op is nothrow. Whereas if you use any throwing ops, you are now throwing. Unless you are certain for external reasons that the given throw operation will not throw in this context, in which case you might want to assert that it is a non-abrupt-completion.
There are a couple action items here, some of which can be done independently:
Let _result_ be ! AbstractOp()
. Use it throughout. A lot of places in the spec currently use "perform" for this purpose, which is not defined anywhere.<emu-clause nothrow>
or<emu-clause flair="nothrow">
.The text was updated successfully, but these errors were encountered: