Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow restricting who can implement a particular protocol #39

Open
theScottyJam opened this issue Jul 26, 2021 · 1 comment
Open

Allow restricting who can implement a particular protocol #39

theScottyJam opened this issue Jul 26, 2021 · 1 comment

Comments

@theScottyJam
Copy link

theScottyJam commented Jul 26, 2021

Right now, this proposal shows how to make a public protocol that anyone can implement. There's also value in making it so only the creator of the protocol can control who's allowed to implement it, while letting anyone verify that the particular protocol is implemented.

For example, let's say TC39 decides to make an array protocol, where anything that implements all of the array methods would be considered an array, according to this protocol. And maybe they beef up some of the exotic arrays (such as the special arguments array) so that they conform to this protocol. This would be very useful - now in userland, instead of using Array.isArray() to check if something is an array that you can operate on, you can instead check if a particular parameter implements the array protocol - in other words, you can now code to an interface instead of an implementation. But, there's a dark side too ... now some userland libraries start conforming to this array protocol also, and application-level code starts relying on this conforming behavior. TC39 has just shot themselves in the foot - they're not able to add any new methods to this array protocol without userland code breaking! What they need is the ability to close the protocol to the public - only TC39 can specify which classes are allowed to implement it, no one else is allowed to conform to it. In other words, anyone's allowed to do an "implements" check to see if an instance conforms to the array protocol, but TC39 has full control over which classes actually pass the "implements" check.

The ability to close the ability to implement a particular protocal would also be valuable for third party libraries, for the same reasons why it would be valuable for the Javascript language itself.

This idea was sparked by this thread on the readonly collections proposal, which was trying to decide if an inheritance relationship should be built between the read-only collections and normal collections. They weren't planning on actually inheriting any behavior (i.e. they would override every single method), they just wanted to build the relationship, presumably for polymorphic purposes. IMO, their problems would better be solved through the use of interfaces, but that wouldn't be possible unless there's a way to make a closed interface, in which only the interface author decides who will implement it.


There's multiple ways to make "closed protocols" possible. A straight-forward way to do it, is to declare that a protocol is "closed" for further additions after the initial creation.

// The "closed" keyword specifies that no one's allowed to do ad-hoc implementations of this protocol.
closed protocol MyProtocol {
  protocolFn() {
    return 'whatever'
  }

  implemented by Array {
    // ...
  }
}

// Alternativly, maybe it makes sense to make "closed" the default,
// and you have to use an "open" keyword if you want to allow anyone to implement it.

Another way that I find particularly nice, would be to piggy-back off of the private declarations proposal, and make it so a protocol can only be implemented if it has access to that private field.

private #privateTag

protocol MyProtocol {
  outer #privateTag

  protocalFn() {
    return 'whatever'
  }
}

class MyClass {
  implements protocol MyProtocol {
    outer #privateTag = true
  }
}

The private declarations proposal is also in stage 1, and I wouldn't want to link this proposal's progress to the success of this other proposal. So, if we think this private fields idea is a better way to go, then maybe this feature can be done as a follow-on proposal instead, after we see how private declarations matures.

@theScottyJam
Copy link
Author

theScottyJam commented Aug 13, 2021

Some related discussion towards this idea has been happening on the TC39 forms here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant