In my opinion protected is about encouraging best practices and design patterns. In Java, all protected and private members are acceptable by Reflection, yet those features do successfully encourage best practices.
From the concepts that I've seen (including my own implementation in lowclass), reaching the protected members from the outside involves writing convoluted hard-to-understand code. For example.
This issue in my implementation can be solved by simply making instance prototypes non-configurable.
In a native implementation, no such issue would ever arise, because the protected inheritance can be totally hidden.
My implementation is in JavaScript, where I can't hide protected and private prototypes. I am 100% sure that if I implemented this at the engine level, I'd be able to 100% hide protected members from public access. My first attempt would be using call-stack tracking, among other things, which is literally impossible in JavaScript with async call stacks, but not impossible at the engine level.
If I can can imagine how to achieve protected access with synchronous call stack tracking in plain JavaScript (@rdking knows about call stack tracking too I believe), then I know you can too! I didn't try it because I knew it wouldn't work as soon as async code broke out of the synchronous context.
It is possible to implement async call-stack tracking with generator functions, because all points of exit from and entry to async processes are controlled by a scheduler that knows when to return to a yield
, and therefore knows which part of a stack it is returning to. But the user would have to explicitly use our own generator implementation instead of native async/await.
We could compile async/await with Babel to use our own implementation of generators, and then we'd be able to track call stacks in async code, to make this proof of concept.
Once we're tracking call stacks, we have information that could be used in a protected implementation.
If I can visualize it, I can make it! :)
@rdking said
Because the code is in 1 place, and that code knows about all the classes that have been created using it, it is able to manage the protection scheme.
Exactly, and this is precisely what the native engine is in relation to all JS code that the engine runs.
How can C leak properties from B? From perspective of C, I would treat a property access on a B instance as public because the inheritance tree path diverged and does not match.
Possible ways to make the rules:
-
Using "assignability" could be one way to make the rules: C can access B protected if B is assignable to C, but B isn't assignable to C. Similarly, if D extends C, then C can access D protected because D is assignable to C (D is a C), but D can not access C protected because C is not assignable to D (C is not a D).
-
Another way to make the rules could be that the hierarchy of one class must be a subset of the other class, and either class can access their protected members if and only if the protected member is inherited from a third class hierarchy that is a subset of the two classes accessing each other's protected members. This is slightly less restrictive than the previous assignability-based version.
I prefer option 2.
I think it may be worth making future concepts using a fork of a browser and implementing the concepts in native code (unless the concept is 100% implementable in pure JS, as not all concepts are). Making concepts in pure JS may be limiting potentially good outcomes for the JS community.
@ljharb What if TC39 required Stage 2 proposals to have an implementation based on a fork of a browser using native code, before being allowed to enter Stage 3 (unless the concept is 100% implementably in pure JavaScript)? This might be a really good thing! It'd at least help everyone verify concepts in an environment with the true flexibility that can't be polyfilled in JavaScript, and therefore would lend to better discussion on the benefits and merits of the concepts before they get to Stage 3 and 4.
@rdking I wish you were on TC39 with the time you need to implement your concepts at the native level.
For that matter, I wish I were too, as then I too would probably have more time to prove my theories while getting paid. At the moment, I don't have this opportunity, and I have only limited unpaid free time for this sort of stuff. I'm assuming that TC39 members often get to work on these things while they are paid by the major companies that employ them.