Skip to content
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

!? usage #486

Closed
annevk opened this issue Mar 20, 2016 · 22 comments · Fixed by #2547
Closed

!? usage #486

annevk opened this issue Mar 20, 2016 · 22 comments · Fixed by #2547
Labels
completion records Relates to completion records, and ? / ! notation.

Comments

@annevk
Copy link
Member

annevk commented Mar 20, 2016

#424 was closed though the remaining calls of OrdinaryGetOwnPropery were not updated to include !. So that probably needs to be fixed.

While closing @bterlson also mentioned that all abstract operations return a completion value and therefore must use ? or !.

That does not seem consistent with the draft, e.g., IsCallable is never prefixed.

There should probably be some more reliable set of rules.

@allenwb
Copy link
Member

allenwb commented Mar 20, 2016

@annevk @bterlson

and also probably worth noting that abstraction operations used for static semantics specification can't produce abrupt completions because they happen outside of the ES runtime execution environment.

@bterlson
Copy link
Member

? or ! are not mandatory. If not used the assumption is that you're operating on a completion record (static semantics is the one exception I think?). There is a rule in 5.2 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. It's in that spirit that I closed #424.

However, I understand wanting to avoid ! when calling abstract operations that cannot throw. We should probably fix #253 and notate certain operations as non-throwing and specify that these return values not completion records. That would necessitate not using ! and ? on such operations. I'll add this to emu.

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 26, 2016

We should probably fix #253 and notate certain operations as non-throwing and specify that these return values not completion records.

(I have a related proposal, but it's waiting for #452 to be merged.)

@annevk
Copy link
Member Author

annevk commented Mar 26, 2016

@jmdyck so given the proposal in #497 we would remove ! for OrdinaryGetOwnProperty calls since that never returns an abrupt completion?

@domenic
Copy link
Member

domenic commented Mar 26, 2016

However, I understand wanting to avoid ! when calling abstract operations that cannot throw. We should probably fix #253 and notate certain operations as non-throwing and specify that these return values not completion records. That would necessitate not using ! and ? on such operations. I'll add this to emu.

Hmm, I do not like this approach. The reason I wanted #253 in the first place was so that I know, when writing other "code" that uses that abstract operation, whether I should use ! or ? at the call site, and consequently whether the call site itself can throw or not throw. Eliminating the ! from the call site reduces clarity, making me jump to the definition of the abstract operation to find out if we're assuming it returns a non-completion record, or a completion record.

I'd much rather have AbstractOp(x) always return a completion record, that must always be unwrapped via ! or ?. The extra character is a very minimal burden and adds a lot of good explictness.

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 27, 2016

@annevk:

so given the proposal in #497 we would remove ! for OrdinaryGetOwnProperty calls since that never returns an abrupt completion?

The proposal in #497 doesn't require the removal of the "!". You could remove it, and the semantics would be the same (just as the semantics are the same if you remove an "Assert:"), but that doesn't mean it'd be a good idea. I think it'd be the editor's call.

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 27, 2016

@domenic:

I'd much rather have AbstractOp(x) always return a completion record, that must always be unwrapped via ! or ?.

It seems to me there are two intertwined ideas here:

  • One is how it looks in the algorithm step: every AbstractOp(x) must be preceded by ! or ?. (And I agree that the extra character is a minimal burden and adds explictness.)
  • The other is the underlying semantics: every AbstractOp returns a completion record, and ! and ? 'unwrap' this.

I think these ideas are separable, and we can retain the good of the former while getting rid of (what at least some people believe is) the bad of the latter. #497 might be a way to do so.

@domenic
Copy link
Member

domenic commented Mar 27, 2016

I disagree that the ideas are separable. The latter is good, not bad.

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 27, 2016

Well, hm, you're not saying much to bolster that position. How about this: what benefit does the latter provide (that you don't already get from the former)?

@domenic
Copy link
Member

domenic commented Mar 27, 2016

A consistent type system that makes it easy to reason about algorithm flow.

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 28, 2016

Hm, interesting. Just to be clear, the type system you're talking about is not for ES, but for the pseudo-language in which ES is defined, right?

@domenic
Copy link
Member

domenic commented Mar 28, 2016

Correct. ! and ? are operators in this system.

@jmdyck
Copy link
Collaborator

jmdyck commented Mar 28, 2016

Okay.

I need a short name for an underlying semantics in which every abstract op returns a Completion Record. For now, I'll just call it X. When you say that one of the benefits of adopting X would be a consistent type system, that suggests that without X, we do not have a consistent type system. Do you mean that in the sense of logical consistency? I.e., in the current type system, is it possible to arrive at two contradictory conclusions? Or are you talking about a different kind of consistency?

@bterlson
Copy link
Member

Right now my mental model aligns with Domenic's I think. Despite the fact that the completion record type presently doesn't allow certain abstract operations to return completion records because their return type is not an ECMAScript value (or empty), I think it's better to be more consistent in the sense that the same mental model can be applied to all invocations of abstract operations. Specifically, only static semantics for which a runtime exception mechanism makes no sense should return naked values and otherwise abstract ops should be understood to return completion records. Even static semantics I could see returning completion records considering they can throw errors, but they do so using a bulleted list of early error conditions rather than explicit algorithm steps.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 14, 2018

For those who would like to see a '!' at every operation-invocation that does not return an abrupt completion, how about this:

Find every operation that cannot under any circumstances return an abrupt completion, and change its name to begin with '!' (or whatever you like that's distinctive).

Then
Let _x_ be !Foo(...)
means "!Foo is an operation that never returns an abrupt completion, and thus the result of this invocation is certainly not an abrupt completion", whereas
Let _x_ be ! Foo(...)
means "Foo is an operation that can, under some circumstances, return an abrupt completion; however, we are asserting that the circumstances of this invocation are such that it will not in this case".

So then the people who are interested in that distinction can pay attention to the space after the "!", and the people who aren't interested in the distinction can just ignore the space.

@ljharb
Copy link
Member

ljharb commented Feb 14, 2018

What is the usefulness of that distinction at the callsite? In both cases, an implementor knows that an exception won’t be thrown; why does it matter if it’s because of something inherent to the operation, or because of guarantees made by the arguments?

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 14, 2018

Because one is a simple (probably statically-verifiable) property of the operation, whereas the other requires reasoning to confirm. The distinction is probably more useful to the writers & reviewers of the spec than to implementors, though I can imagine an implementor being interested.

@domenic
Copy link
Member

domenic commented Feb 14, 2018

I don't think that would be a good idea. If you're interested in signaling properties of the operation, I'd suggest working on #253. In any case, I'd still prefer a consistent calling convention, so that whenever you call an operation without !/?, you get back a completion record.

@ljharb
Copy link
Member

ljharb commented Feb 14, 2018

I’d prefer that determining that an operation can’t ever throw always requires reasoning about the operation’s actual spec text, tbh.

The purpose of ?/! is to unwrap the completion record, and either ReturnIfAbrupt, or assert that the completion type is Normal - it’s not to convey inherent properties of the abstract operation.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 14, 2018

If you're interested in signaling properties of the operation, I'd suggest working on #253.

I am, in #545.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 14, 2018

I’d prefer that determining that an operation can’t ever throw always requires reasoning about the operation’s actual spec text, tbh.

I'd prefer that it be statically determinable, which I think it mostly is.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 14, 2018

The purpose of ?/! is to unwrap the completion record

I don't subscribe to the view that every operation always returns a completion record (#496 + #497), so I disagree with you there.

it’s not to convey inherent properties of the abstract operation.

Okay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
completion records Relates to completion records, and ? / ! notation.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants