Skip to content

Commit

Permalink
Document privacy model
Browse files Browse the repository at this point in the history
As discussed in #136, this is an important missing piece of documentation. cc @allenwb @erights
  • Loading branch information
littledan committed Aug 8, 2018
1 parent 796ad80 commit 37c58d0
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions PRIVACY_MODEL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
This proposal introduces new metaprogramming concepts on private fields and methods. This document describes the invariants, guarantees and scope of this privacy as a whole, in light of this feature.

## Private fields and methods are *hidden*

Previous documentation used the term "hard private" to explain the guarantees, but that term may lead some to false conclusions. Here, we use the term *hidden*, defined as follows:

> A class element is *hidden* with the syntax `#name`, which makes it inaccessible except to those granted explicit access to it.

This comment has been minimized.

Copy link
@ljharb

ljharb Oct 10, 2018

Member

Also unobservable, which is a critical piece.

This comment has been minimized.

Copy link
@littledan

littledan Oct 10, 2018

Author Member

This paragraph was written to be short enough to understand; I'd prefer not to make it longer. I was intending for "inaccessible" to sort of imply that.

This comment has been minimized.

Copy link
@ljharb

ljharb Oct 10, 2018

Member

In threads on this very repo, the difference needed to be called out for some to understand. I don’t think there is a simple term that implies everything which is why “hard private” was historically used.

This comment has been minimized.

Copy link
@littledan

littledan Oct 11, 2018

Author Member

PRs welcome for improving documentation. I'm not sure if what's happening is confusion exactly or a difference of goals.

This comment has been minimized.

Copy link
@rdking

rdking Oct 11, 2018

It's a difference in goals. This is the reason the documentation needs to be clear about what the goals are. As has been discussed before, the peculiarities of this proposal are entirely due to the fact that "unobservable" is a goal. If it weren't, there would be scarce little precluding the private x/this.x syntax that would be far easier to understand.

In this proposal, the following mechanisms grant access to hidden elements:
- Being lexically contained inside the place where the hidden element is defined, e.g., `class { #x; method() { this.#x } }`, the body of `method()` can see `#x`.
- Decorating an element, e.g., in `class { @dec #x; #y; }`, `@dec` can see `#x` but not `#y`.
- Decorating a class containing the element, e.g., in `@dec class { #x; #y; }`, `@dec` can see `#x` and `#y`.

Future proposals may also grant access to hidden elements, but this will always be through a mechanism which is syntactically apparent; implicit access will never be granted. For example, a `protected` contextual keyword could be added to classes which grants access to subclasses, and this access grant would be similar to that which decorators do.

## Object capability analysis

Private fields and methods are analogous to a WeakMap. Each hidden class element has an associated Private Name, which can be seen as in 1-1 correspondence with a WeakMap. Just as WeakMaps may be passed around, so can Private Names. Private Names are passed by default to element decorators and class decorators. With this understanding, private class elements can be used to achieve object capability-based security.

In practice, the ability to decorate hidden class elements is hoped to strengthen, not weaken, encapsulation by making it applicable in more cases, where a strict lexical-scoping-only regime would reduce applicability and force greater use of non-private mechanisms.

## Invoking decorators without trust

To invoke a decorator which should not be trusted with private names, it is possible to wrap the decorator so that it will not see Private Names as follows. This technique, of using JavaScript code to achieve isolation goals in conjunction with new JavaScript features by design, is nothing new; for example, Proxy and WeakMap were designed to be combined to build a membrane abstraction. Membranes are a small, trusted JavaScript library which enables interaction with untrusted code, much like this function.

```js
function restrict(decorator) {
assert(typeof decorator === "function");
return descriptor => {
assert(descriptor[Symbol.toStringTag] === "Descriptor");
switch (descriptor.kind) {
case "class":
let elements, privateElements;
for (let i = 0; i < descriptor.elements.length; i++) {
let element = descriptor.elements[i];
let arr = typeof element.key === "object" ? privateElements : elements;
arr[arr.length] = element;
}
let result = decorator({...descriptor, elements});
for (let i = 0; i < privateElements.length; i++) {
result.elements[result.elements.length] = privateElements[i];
}
return result;
case "method":
case "field":
assert(typeof descriptor.key !== "object");
return decorator(descriptor);
default:
assert(false);
}
}
}

// Example usage

@restrict(defineElement("my-element"))
class MyElement {
#x; // will not show up in defineElement
y; // will show up in defineElement
};
```

4 comments on commit 37c58d0

@rdking
Copy link

@rdking rdking commented on 37c58d0 Oct 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't line 33 be

let elements=[], privateElemens=[];

? They're never initialized.

@littledan
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rdking Yes, it should be. Good catch! PRs welcome.

@rdking
Copy link

@rdking rdking commented on 37c58d0 Oct 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also thought it had been decided in July that class decorators wouldn't be allowed access to private fields since that severely weakens encapsulation.

@littledan
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rdking You're right; this document needs changes. PRs welcome also!

Please sign in to comment.