Open rbuckton opened 3 months ago
A preview of this PR can be found at https://tc39.es/proposal-explicit-resource-management/pr/232.
Ideally this can be pursued as a needs-consensus PR and not a follow-on to avoid making potentially breaking changes after implementations have shipped. I will bring this to the July/August 2024 TC39 plenary for discussion.
In the (extensive) discussions we had around extending built-ins in 2022 (focused on, but not exclusively about, Set methods), we concluded that we weren't going to make future built-in methods defer to other built-in methods on this
. Subclasses will need to override all relevant parts of the public interface.
I don't want to revisit that discussion, but to summarize, making this a bound getter rather than an alias will make non-subclass consumers slower, for the benefit of very slightly simpler subclassing. I think that's the wrong tradeoff and I believe the committee has agreed.
Hm, fair point. What was the motivation for having the dispose
/ disposeAsync
methods? What if we dropped them?
Besides the foot gun in https://github.com/tc39/proposal-explicit-resource-management/issues/231, it seems somewhat odd to me for the spec to define and give semantics for [Symbol.dispose]
and [Symbol.asyncDispose]
, and then seeming not to prefer those methods in DisposableStack/AsyncDisposableStack, instead giving them string-named methods to call.
Should user space implementations of [Async]Disposable follow suit? Other symbol-named methods with semantics carved out by the spec generally don't do this.
Should user space implementations of [Async]Disposable follow suit? Other symbol-named methods with semantics carved out by the spec generally don't do this.
They sometimes do: Array.prototype.values
is an alias for Array.prototype[Symbol.iterator]
(or rather, technically, the other way around); ditto for Map.prototype.values
and Set.prototype.values
.
String-named methods are nicer for consumers, but aren't a good basis for a protocol. So having both the symbol-named and string-named method is good practice, with one being an alias for the other.
As to the name, dispose
is a good name for a method when the action is generic disposal, but sometimes it's going to be something like close
or whatever, depending on the actual thing being implemented.
As discussed in #231 and #229, this explores the possibility of reintroducing bound getters for
DisposableStack.prototype.dispose
/AsyncDisposableStack.prototype.disposeAsync
. By making these methods getters, aDisposableStack
/AsyncDisposableStack
subclass that wishes to override disposal needs only to override the[Symbol.dispose]()
or[Symbol.asyncDispose]()
methods. By making them into bound method getters, an instance of either class can be more readily used as a field on an object literal:Subclassing:
Object Literals:
Fixes #229 Fixes #231