3 ms·
No, JS engines choose it out of spec compliance. (Source: I worked on a JS engine for 10.5 years.) And your solution doesn’t solve the problem. The problem is
by pizlonator 2y ago
No, JS engines choose it out of spec compliance. (Source: I worked on a JS engine for 10.5 years.)
And your solution doesn’t solve the problem. The problem is you’ve got once closure that does close over a reference, and another closure that closes over the first closure, just not to call it, but because the function pointer carries meaning for the purpose of clearing the timeout.
A JS engine could solve this by saying that the state closed over by a closure is only live if the closure itself is live for the purpose of a call, but defining that is next to impossible given JS’s dynamism (the runtime would have to prove that clearTimeout doesn’t call its argument, which is a crazy high proof burden in JS).
- paulddraper 2y agoI don't know how to square this with your credentials, but the spec does not specify the GC behavior of closures. (This only thing it's ever said about GC was WeakMap/WeakSet in ES2015.) I'm sorry, I literally do not understand what you are saying. Java does closures this way. Python does closures this way. Google has considered not doing closures that way in JS. [1] This is an intentional but extremely optional implementation choice, made for performance reasons. (See Chromium thread.) [1] https://issues.chromium.org/issues/41070945 https://issues.chromium.org/issues/41070945
- pizlonator 2y agoIf you want to understand what I’m saying, then consider carefully if your solution even fixes the leak. It doesn’t. The original post isn’t clear on this and maybe that’s what you’re confused about. You’re right that the spec doesn’t call for a particular closure representation, but it makes only one representation practical due to the shared mutable state of scopes, which is mandated by the spec. This makes JS’s closures unlike closures in other languages, which allow for greater flexibility. But thats off topic for the original post - the leak - since that leak would exist even with your proposed separate scopes. Again: stated most precisely, and as I’ve said more than once in the thread, the leak is that closure #2 closes over closure #1, not that closure #2 closes over a separate variable in the same scope. Making the scopes separate won’t fix the leak.
- Zacru 2y ago>closure #2 closes over closure #1 I don't see this in the example. Closure #1 is never bound in the scope, as far as I can tell. Could you explain how closure #1 is closed over without being bound?
- pwdisswordfishz 2y ago> (This only thing it's ever said about GC was WeakMap/WeakSet in ES2015.) Even later than that — only when WeakRef and FinalizationRegistry appeared in ES2021 did TC39 bother to specify any GC behavior — and badly. https://es.discourse.group/t/liveness-barriers-and-finalization/1082 https://es.discourse.group/t/liveness-barriers-and-finalizat...
- deredede 2y ago> another closure that closes over the first closure, just not to call it, but because the function pointer carries meaning for the purpose of clearing the timeout. Isn't the second closure closing over the timeout identifier, which is a bare integer, rather than over the first closure?
- paulddraper 2y agoYes