Help wanted: Membrane proxies + Object.freeze() == paradox
On 5/23/17 3:44 AM, Alex Vincent wrote:
- I create matching "membrane" proxies for wetB and wet_b named dryB and dry_b,
Shouldn't you also have a proxy for webB.prototype (called dryproto, let's say)? Otherwise your "wet" and "dry" object graphs are actually a single kind of weird object graph...
Then:
- Reflect.get(wetB, "prototype") === Reflect.getPrototypeOf(wet_b)
- Reflect.get(dryB, "prototype") !== Reflect.getPrototypeOf(dry_b)
And then Reflect.get(dryB, "prototype") === dryproto === Reflect.getPrototypeOf(dry_b), I would hope.
On Tue, May 23, 2017 at 2:44 AM, Alex Vincent <ajvincent at gmail.com> wrote:
Full details are at ajvincent/es7-membrane#79 , which is where I'm hoping to find a solution.
To fix this, you must create a third object for each dry proxy, to serve as its [[ProxyTarget]]. There's no way around it. And you're right, it's not easy; you have to implement all of the handler methods, because none of the defaults do the right thing anymore.
All the target checks in the design were intended to (a) allow proxies to claim to have immutable parts; and yet (b) maintain the language's invariants that immutable parts cannot change, even for proxies. [[ProxyTarget]] looks like an ease-of-use feature, but it's not; it's really in support of (a) and (b), and as you've found, it actually makes some things harder.
Take a look at Tom's explanation of the "shadow target" technique at research.google.com/pubs/pub40736.html section 4.3
Yes, I've been using the shadow technique in my es7-membrane project for quite some time. I was trying to minimize a fairly complex test case here.
Obviously, I can reintroduce shadow targets into the minimal testcase, but then I need to figure out how to make the prototype object I'm trying to get consistent again... still working through the details of that in my head.
I think the most straightforward thing is something like this:
gist.github.com/jorendorff/85d74ef7dce0118664535f84d57d6788
To restate the obvious, this is a minimal fix for your minimized test case, not production code you can take and use. You'd need to implement all the rest of the handler methods.
Thanks, Jason. I tried that approach last night (calling setPrototypeOf within the getPrototypeOf trap), and it caused a nasty regression in one of my other prototype-checking tests. I assumed at the time that I had done something wrong, but your quick summary shows that instead I was doing something right, and that my prototype chain handling was incorrectly implemented...
Full details are at ajvincent/es7-membrane#79 , which is where I'm hoping to find a solution.
In short: if
Then:
This is a paradox: I claim that what's true on the "wet" object graph should be true on the "dry" object graph.
Please, if you can offer help on this to fix the sample code I've posted, or if you can confirm that my claim above is incorrect and never can be correct, I'd appreciate it.
Alex Vincent
Hayward, CA, USA