ecma262
ecma262 copied to clipboard
Editorial: define thenable
a quick fix for #2868
I'd like to discuss a seemingly simple question "Is p
promise?" a little bit more.
First, it leads me to a more general question: what constitute an is-a relation in JavaScript? I'm not sure the spec addresses this question explicitly. In general OOP sense, is-a determines which behavior is expected from an object (according to its (sub-)type). [[Prototype]]
assignment changes the behavior and can be considered a change of an object (sub-)type. For example, instanceof
operator can be easily "broken":
const p = Promise.resolve();
console.log(p instanceof Promise); // --> true
Object.setPrototypeOf(p, null);
console.log(p instanceof Promise); // --> false! Is p still a Promise?
When we "break" the expected behavior of an object should its "type" be considered the same? Here by the "type" I don't mean the result of typeof
operator, but the more general OOP meaning, which probably better corresponds to OrdinaryHasInstance ( C, O ).
In case of Promise
we indeed have IsPromise()
in the spec, but is it the sole source of truth for an "is p a promise" question? How this is determined for other types which do not have Is%Typename%()
operation?
Back to the Promise Objects section. There are two definitions literally a dozen lines above the proposed patch:
- A promise
p
is fulfilled ifp.then(f, r)
will immediately enqueue a Job to call the functionf
.- A promise
p
is rejected ifp.then(f, r)
will immediately enqueue a Job to call the functionr
.
When we break the [[Prototype]]
these definitions no longer work. I guess, a non-negligible part of the spec breaks as well when we allow [[Prototype]]
setting in arbitrary places. And of course there are also infinite number of possibilities to adjust the [[Prototype]]
and thus the behavior to different extents which may constitute a different degrees of "behavior breakage".
Now back to your question "Is p
promise?". I think that until is-a is formally defined in the spec[^1] my answer would be: it depends on what do you mean by that question. If you mean IsPromise(p)
the answer is 'yes', if you mean p instanceof Promise
the answer is 'no'.
Summarizing the more general part:
- is there an official definition for is-a relation in the JavaScript spec[^1]?
- what about subtyping in the general OOP sense?
- should one be added?
- should we open a new discussion/issue regarding this subject?
What do you think?
I'm by no means a JavaScript (or any language) expert, quite the opposite. A feedback from more experienced people is much appreciated.
[^1]: and please point me to such a definition if it exists!
is there an official definition for is-a relation in the JavaScript spec?
No.
what about subtyping in the general OOP sense?
No.
should one be added?
In my opinion, no. None of the normative requirements in the spec require us to give precise definitions to any of those, and they are used in somewhat vague ways in general, so it's best we stay out of trying to give precise definitions.