rdking / proposal-class-members

https://zenparsing.github.io/js-classes-1.1/
7 stars 0 forks source link

A question about membranes... #8

Open rdking opened 5 years ago

rdking commented 5 years ago

@erights

I was looking at the 8 equations that must be true for membranes:

bT[fT] = vT    ->    bP[fP] === vP
bT[fT] = vP    ->    bP[fP] === vT
bT[fP] = vT    ->    bP[fT] === vP
bT[fP] = vP    ->    bP[fT] === vT
bP[fT] = vT    ->    bT[fP] === vP
bP[fT] = vP    ->    bT[fP] === vT
bP[fP] = vT    ->    bT[fT] === vP
bP[fP] = vP    ->    bT[fT] === vT

After re-arranging them, I noticed that there's really only 4 equations:

//Equation 1:
bT[fT] = vT    ->    bP[fP] === vP    \    bT[f] = vT    ->    bP[f] === vP
bT[fP] = vT    ->    bP[fT] === vP    /

//Equation 2:
bT[fT] = vP    ->    bP[fP] === vT    \    bT[f] = vP    ->    bP[f] === vT
bT[fP] = vP    ->    bP[fT] === vT    /

//Equation 3:
bP[fT] = vT    ->    bT[fP] === vP    \    bP[f] = vT    ->    bT[f] === vP
bP[fP] = vT    ->    bT[fT] === vP    /

//Equation 4:
bP[fT] = vP    ->    bT[fP] === vT    \    bP[f] = vP    ->    bT[f] === vT
bP[fP] = vP    ->    bT[fT] === vT    /

because it doesn't matter whether or not the field key is wrapped in a Proxy. All that seems to matter is whether or not the base object and value object are a Proxies or not. Am I missing something critical here? A lot of argument has been levied against recent counter-proposals to class-fields over issues related to Membranes, especially with regard for how to handle private member names. If my assessment is correct, then such arguments have been a red herring from the start.

Actually, even if I'm wrong, aren't those arguments still a red herring since it is logically impossible for a private member access to cross a membrane, even in the case of a pseudo-sibling from another realm? Consider the following (uses class members semantics):


// CommonLib.js
export default class Lib {
  let data = ~~(Math.random() * 100);
  get data() {
    console.log("Retrieving private data");
    return this::data;
  }
  action(obj) {
    console.log(`My val = ${this::data}`);
    console.log(`Other val = ${obj::data}`)
    console.log(`Sum = ${this::data + other::data}`);
  }
}

//In Realm A:
import Lib from "./CommonLib.js";

function sendToRealmB(obj) {
  //Sends obj to realm B somehow
}

sendToRealmB(new Lib());

//In realm B:
import Lib from "./CommonLib.js";

function getFromRealmA() {
  //Gets an object from realm A somehow
  return obj;
}

var a = new Lib();
var b = getFromRealmA();

//The important part!
a.action(b);
b.action(a);

Here's the problem: since a and b are from different realms, they won't have the same "brand", and won't be able to access each other's instance variables. If there was a Membrane between a and b instead of a realm boundary, and proxy tunnels private access, then action would work as expected without breaking any of the equations. Since it's impossible for the field names to be used outside of the lexical scope of the class, that's not a concern.

Since class-fields presents a semantic similar to class-members, there's no problems there either. When it comes to Symbol.private, it's possible to both share the private name, and use the private name to access a member from outside the lexical scope of the class, but what does that matter? Regardless of whether or not the name is wrapped, the access will be proxy filtered in accordance with the 8 equations.

So again, why is membrane (and therefore Proxy) such a sticking point for these proposals?