{"action":"created","issue":{"url":"https://api.github.com/repos/tc39/proposal-class-fields/issues/106","repository_url":"https://api.github.com/repos/tc39/proposal-class-fields","labels_url":"https://api.github.com/repos/tc39/proposal-class-fields/issues/106/labels{/name}","comments_url":"https://api.github.com/repos/tc39/proposal-class-fields/issues/106/comments","events_url":"https://api.github.com/repos/tc39/proposal-class-fields/issues/106/events","html_url":"https://github.com/tc39/proposal-class-fields/issues/106","id":332477376,"node_id":"MDU6SXNzdWUzMzI0NzczNzY=","number":106,"title":"Private members break proxies","user":{"login":"jods4","id":3832820,"node_id":"MDQ6VXNlcjM4MzI4MjA=","avatar_url":"https://avatars2.githubusercontent.com/u/3832820?v=4","gravatar_id":"","url":"https://api.github.com/users/jods4","html_url":"https://github.com/jods4","followers_url":"https://api.github.com/users/jods4/followers","following_url":"https://api.github.com/users/jods4/following{/other_user}","gists_url":"https://api.github.com/users/jods4/gists{/gist_id}","starred_url":"https://api.github.com/users/jods4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jods4/subscriptions","organizations_url":"https://api.github.com/users/jods4/orgs","repos_url":"https://api.github.com/users/jods4/repos","events_url":"https://api.github.com/users/jods4/events{/privacy}","received_events_url":"https://api.github.com/users/jods4/received_events","type":"User","site_admin":false},"labels":[{"id":988247143,"node_id":"MDU6TGFiZWw5ODgyNDcxNDM=","url":"https://api.github.com/repos/tc39/proposal-class-fields/labels/semantics","name":"semantics","color":"dda458","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":161,"created_at":"2018-06-14T16:32:02Z","updated_at":"2018-07-17T05:04:10Z","closed_at":null,"author_association":"NONE","body":"I commented on an old issue in tc39/proposal-private-fields#102 but after reading the answer I feel like I should re-open an issue.\r\n\r\nIt's been discussed before: current `PrivateName` spec doesn't tunnel through proxies.\r\nIn my opinion the consequences have been under-evaluated.\r\n\r\nProxies are already quirky: they don't work with internal slots (bye `Number`, `Date`, `Promise` and friends), they change the identity of `this` (no equality, no `WeakMap`).\r\nBut at least, they work on classes.\r\n\r\nSo they are useful. Libraries and frameworks can provide many features that motivated building proxies: automatic logging, lazy objects, dependency detection and change tracking.\r\n\r\nMy point here is that `PrivateName` and `Proxy` don't work together. You have to choose one of the two features and give up on the other. Partitionning JS features in this way is terrible.\r\n\r\nHere is a basic example.\r\nLet's say a library provides `logReads`, a function that writes on the console every member that is read.\r\n```js\r\nfunction logReads(target) { \r\n  return new Proxy(target, {\r\n    get (obj, prop, receiver) {\r\n      console.log(prop);\r\n      return target[prop];\r\n    },\r\n  });\r\n}\r\n```\r\n\r\nNow let's say I'm writing an application and I use private fields for encapsulation, because they're nice.\r\n```js\r\nclass TodoList {\r\n  #items = [];\r\n  threshold = 50;\r\n\r\n  countCheap() {\r\n    return this.#items.reduce((n, item) => item.price < this.threshold ? n : n + 1, 0);\r\n  }\r\n}\r\n```\r\n\r\nI would like to use that nice logging library to better understand what happens when I run my code.\r\nSeems legit from a naive user's perspective:\r\n```js\r\nlet list = logReads(new TodoList);\r\nlist.countCheap(); // BOOOM\r\n```\r\nAhaha gotcha! And if you don't know the source code, why it crashes when inside a proxy might be a unpleasant mystery.\r\n\r\nPlease reconsider. All it takes to solve this is make `PrivateName` tunnel through proxy (no interception, encapsulation is fine).\r\n\r\nDon't think that returning bound functions from the proxy will solve this. It might seem better but creates many new issues of its own."},"comment":{"url":"https://api.github.com/repos/tc39/proposal-class-fields/issues/comments/405460415","html_url":"https://github.com/tc39/proposal-class-fields/issues/106#issuecomment-405460415","issue_url":"https://api.github.com/repos/tc39/proposal-class-fields/issues/106","id":405460415,"node_id":"MDEyOklzc3VlQ29tbWVudDQwNTQ2MDQxNQ==","user":{"login":"caridy","id":38969,"node_id":"MDQ6VXNlcjM4OTY5","avatar_url":"https://avatars1.githubusercontent.com/u/38969?v=4","gravatar_id":"","url":"https://api.github.com/users/caridy","html_url":"https://github.com/caridy","followers_url":"https://api.github.com/users/caridy/followers","following_url":"https://api.github.com/users/caridy/following{/other_user}","gists_url":"https://api.github.com/users/caridy/gists{/gist_id}","starred_url":"https://api.github.com/users/caridy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caridy/subscriptions","organizations_url":"https://api.github.com/users/caridy/orgs","repos_url":"https://api.github.com/users/caridy/repos","events_url":"https://api.github.com/users/caridy/events{/privacy}","received_events_url":"https://api.github.com/users/caridy/received_events","type":"User","site_admin":false},"created_at":"2018-07-17T05:04:10Z","updated_at":"2018-07-17T05:04:10Z","author_association":"NONE","body":"@EisenbergEffect decorator is just an example. If there are 3 actors, each actor can:\r\n\r\n* create the objects that they own and can hand them over to another actor for consumption\r\n* receive objects from another actor that is handing them over to them\r\n\r\nEither way, you have a little bit of control. If the framework is doing that coordination, the framework can create membranes around those objects. If the framework is not in between, the consumer can decide to wrap the objects received with a membrane. I will try to put some example together later this week, to illustrate how we do most of the gymnastics using membranes. "}}
{"actor":{"display_login":"caridy"}}