Skip to content

Instantly share code, notes, and snippets.

@littledan
Last active Aug 7, 2020
Embed
What would you like to do?
`private` and `with`: Separating the naming and definition of private names

private and with: Separating the naming and definition of private names

Private field and method declarations do two things at once: they position the scope/availability of the private element, and they define its meaning. This proposal allows those two functions to be separated: private declares the scope, and with defines it in a class or object.

private #foo;

class C { with #foo; } // reference the outer definition

new C().#foo;  // works, since we're within the scope of the name
private #foo;

function f() { return { with #foo: 1 }; }

f().#foo
function counter() {
  return {
    #counter: 1,  // defined within this object only
    inc() { return this.#counter++; }
  }
}

Rules: There must be exactly one with per private, and this must be in the same unit of parsed code (i.e., the restriction is enforced by static semantics). It is not possible to use with on a name which was not explicitly defined by private. private definitions may be shadowed by other private definitions, or by keywordless definitions.

Invariants met:

  • No real new stuff: this just splits up the scoping and definition into two places.
    • This "excavates"/"explains" the existing construct as class C { private with #x } (though that syntax would be invalid)
  • Scoping for classes and objects is the same; no lack of parallelism
  • Private names are still only defined once, so they still stand for just a single "brand"
    • Implies that brand-checking is a valid implementation of private methods
    • Implies that private names still provide a good basis for "nominal types"/Wasm RTT equivalence
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment