Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is why TC39 needs to work on fundamental language features like protocols. In Rust, you can define a new trait and impl it for existing types. This still has flaws (orphan rule prevents issues but causes bloat) but it would definitely be easier in a dynamic language with unique symbol capabilies to still come up with something.


Dynamic languages don't need protocols. If you want to make an existing object "conform to AsyncDisposable", you:

    function DisposablImageBitmap(bitmap) {
      bitmap[Symbol.dispose] ??= () => bitmap.close()
      return bitmap
    }
    
    using bitmap = DisposableObserver(createImageBitmap(image))
Or if you want to ensure all ImageBitmap conform to Disposable:

    ImageBitmap.prototype[Symbol.dispose] = function() { this.close() }
But this does leak the "trait conformance" globally; it's unsafe because we don't know if some other code wants their implementation of dispose injected to this class, if we're fighting, if some key iteration is going to get confused, etc...

How would a protocol work here? To say something like "oh in this file or scope, `ImageBitmap.prototype[Symbol.dispose]` should be value `x` - but it should be the usual `undefined` outside this scope"?


You could potentially use the module system to bring protocol implementations into scope. This could finally solve the monkey-patching problem. But its a fairly novel idea, TC39 are risk-averse, browser-side are feature-averse and the language has complexities that create issues with most of the more interesting ideas.


Isn't disconnecting a resize observer a poor example of this feature?


I couldn't come up with a reasonable one off the top of my head, but it's for illustration - please swap in a better web api in your mind

(edit: changed to ImageBitmap)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: