-
Notifications
You must be signed in to change notification settings - Fork 28
Why does this check for IsPromise? #41
Comments
A change was made at the end of this thread: #37 . But if you're asking, why try to get to a native promise at all? That might go further back, when there was an attempt to make the resolve/reject callbacks not observable. |
In general yes, it's to reduce observability. Specifically about step 2; In other words, |
I think the spec normally only applies brand checks were necessary, see for example |
(The RegExp.prototype methods use To me, it is necessary here (because I think all APIs should be as strict as possible); what's the use case for having |
I agree with @anba WRT this issue.
this is not the design philosophy that ECMAScript has traditionally followed. We generally specify built-in methods to be a generic as possibly so they can be used with alternative object implementations that support a common API. Generally, brand checks are used in situations where where an algorithm has dependencies on the existence of an internal slot. IsRegExp is used when an built-in has different behavior depending upon whether a string or a "regular expression" as passed to it as an argument. A "regular expression" is defined to be any object that has a Symbol.match method. Note that the delegation to "then" in finally is a generic invocation, not a call to s specific method implementation or abstract operation. It may not may not end up invoking the built-in method that does a brand check. Basically, the promise finally method should be usable with any object that implements "then". |
I understand the traditionally followed philosophy; however, I'm asking what the use case is. If we keep the brand check, it can always be removed later - if we remove it now, it can't be added back later. Is there a concrete reason to loosen it up besides "consistency"? |
Promise.prototype.finally.call(instanceOfSomeNonNativePromiseWithoutFinally, onFinally); Available too many different |
@zloirock why wouldn't you prefer |
@ljharb OK, another example: YourNonNativePromise.prototype.finally = Promise.prototype.finally; instead of the previous example it's real case for me with |
In an engine where |
It's not always possible. For example,
For example, for engines without support unhandled promise rejection tracking or for the version without global namespace pollution. |
I’m still not sure I understand where you would have an engine that a) natively implements In other words, by the time |
None of your objections really matter. You are adding a single new built-in method, that is not time or place to be breaking internal consistency or trying to change a design philosophy that has been used to achieve internal consistency within the specification. This sort of consistency is not just a tradition. It is a reflection of specific design choices made within TC39 in reaction to earlier experience where there was variability among implementations about such checks and observing the problems that caused. Problems, because people actually did things like try to build alternative implementations of build-ins or selectively reuse built-ins in context other then their original use. Finally, note that JS is not a nominally typed language and JS subclassing is not subtyping. In fact JS does not even have the concept of distinct object types. All object are the same ES primitive type. Dynamic "type checking" in JS (and most other dynamic languages) isn't really type checking at all, it is really safety checking for low level primitive operations. Such checks prevents unsafe primitive operations such as accessing an internal slots that does not exist or trying to use a numeric object as an object reference. Your use of branding in Finally the argument, "if we add the error check now, we can always remove it in the future" doesn't work for actual developers. Individual developers who might run into such a unnecessary check can't wait years for the specification to be changed and for implementations updated. The "we can remove it latter" argument really only applies to internal TC39 considerations, not to actual usage. |
Indeed, I'm trying to apply it to internal TC39 considerations: that I think this consistency has been overly applied, and that I'd rather see us keep the check for now, given that it's a reversible decision, rather than make yet another irreversible decision. It's worth noting that if it were web-compatible, the committee would have preferred to change |
At any rate, if members feel strongly that this brand check should be removed, and implementors aren't concerned about the optimizability of wider exposure of ideally unobservable spec-created closures, then I'm sure I'll end up removing this - it's not a hill I want to die on. I do think, however, that more things should be doing brand checks, and I think it's unfortunate if "consistency" is going to forever constrain us to having everything duck type. |
cc @gsathya |
(I’ll also add; anything with internal slots is indeed nominally typed; that’s why brand checks continue to exist for all builtin types besides Error; the fact that many methods on a builtin don’t depend on the internal slots doesn’t change that) |
It depends upon your definition of "nominal type". Wikipedia's says
In ES you can define a class that in response to
I don't see how, using the Wikipedia definition, you could say that the resulting instance has the same nominal type as the related built-in or is a nominal subtype of the built-in. It probably could be described as having some sort of structural typing relationship with the built-in. |
In summary:
Nobody has yet demonstrated a use case where they'd need a native However, in the interest of moving the proposal along, and because in the 99.99999% case, the This will be a brief mention in update for the November meeting; if anyone objects to removing the brand check, or thinks it needs further discussion in the committee, please let me know. |
Were we discussing whether the PromiseResolve call in the then and catch functions is necessary? I don't see that changed by the patch. |
No, but that’s still necessary since the user’s callback could return any thenable - this is also the first time that’s been questioned; can you file a separate issue about it? |
I am going over the patch from @anba for the Firefox implementation. He made this comment:
I don't follow the Promise implementation, but this observation makes sense to me.
The text was updated successfully, but these errors were encountered: