-
Notifications
You must be signed in to change notification settings - Fork 75
Broad inclusion of operators #4
Comments
Below are some food for thought. I may find more use cases. (1) Given an iterator iter.return?.() (2) Given a DOM element foo.onclick?.() (3) More concretely, I’ve recently encountered a situation where I wanted to run the reportValidity method of an HTML form, but fall back to skip the check for browsers which don’t implement that method (since there is of course another check server-side): if (myForm.checkValidity && !myForm.checkValidity()) {
// validity check has failed and errors are reported to the user
// stop processing the form
return;
} With if (myForm.checkValidity?.() === false) {
// validity check has failed and errors are reported to the user
// stop processing the form
return;
} because |
Those all make sense to me. Did you have anything in mind for the constructor case? |
For the constructor case, no, I’ve currently nothing in mind except completeness. |
If we want to be super complete, besides the “optional constructor” case |
Seems like there are two decisions: which forms to include for .? versions, and which forms to short circuit over, even in the ordinary version. Would it make sense to choose the same set of forms for both of these? |
For me, it would make sense that the first set is included in the second set. |
@claudepache Yes, I agree about the subset relationship; I'm suggesting that maybe they should be equal (regardless of how expansive or restrictive we make things). The idea would be that it's less to learn. For reference, these sets are not equal in C#--the only forms are |
@littledan No, I don’t think that making the two sets equal make it less to learn, because it is not a useful rule. For instance, does it say whether |
OK, this seems reasonable. |
I think that |
I disagree with my past self. For someone not versed in the spec details, it would seem like an arbitrary restriction or an inconsistency if some construct is allowed in some location of an optional chain, but not in another. The case of |
I don't see how we can make everything work with optional chaining. It really seems like, at some point, programmers will just have to learn which things it works with, rather than taking it as an orthogonal primitive. |
Why? I personally would strongly prefer to work with engineers who take the time to learn their tools, but I can certainly imagine someone just getting started with programming writing code like: class Foo {
foo(){super??.foo()} // silence TypeError: (intermediate value).foo is not a function
}
const Bar= {};
new Bar??.('bar' ) // silence TypeError: Bar is not a constructor while they still have no idea what's going on to silence some errors while focusing on others. Of course, it's a pedagogical question whether they should learn that way, and many CS professors might argue that only code that passes a compiler, typechecker, linter, etc should ever be run. I don't think TC39 should make that pedagogical decision for the community, personally. ...Actually, to be honest, I myself might write code like that while debugging. I'd never ship it, but it might be nice to be able to eg; silence the errors while iterating on some other part of a program (eg; going back and forth between Bar being a struct or a class, deciding whether Foo should extend some other class, etc). FWIW, the debugging explanation might also explain why we don't see this code in practice; it may have been written, but thankfully it never shipped. |
(I do recognize that there's a cost to implementing features like these, and I don't mean to claim that the benefits I stated, or others I haven't thought of, outweigh those costs). |
There are other cases which were brought up on this repository, such as |
I have no intention of making
I am reluctant to make |
I think the difference with these is that they "look just like" member chaining and function soaking. That is, a naive writer of JavaScript would expect these to work (eg; they are not aware that
Fair enough 😄
That doesn't sound unreasonable to me, but I'm actually curious why? |
Because I don’t know how to make sense of it, and I am unwilling to think of the most reasonable meaning just for the sake of it. And even if I determined the meaning it should have, I am unwilling to introduce it in the spec just because it looks nice to have But if you have reasonable meaning and a reasonable use case, just open an issue. |
For reference, other issues about in/ex-cluding operators from optional chains: Currently included in the spec:
Currently excluded from the spec:
|
Now that we are at Stage 3, we can consider that the set of included operators is fixed. There remains only the relatively minor issue of private field access: see #28. |
This proposal includes not just
?.
but also?.[
and?.(
. It's easy to see why?.
is useful when navigating around a JSON document, and?.[
may be for analogous situations, but the method call and constructor parts are a bit more obscure. Are these included out of an abstract sense of orthogonality, or were there particular use cases in mind that motivated them? If so, it would be good to include them in the explainer. IIRC the number of operators here was brought up at the January 2017 TC39 meeting as a point to revisit with an eye towards starting more minimally. cc @dhermanThe text was updated successfully, but these errors were encountered: