Does private(expr) create a private storage block?

Herby Vojčík herby at mailbox.sk
Thu Jan 19 16:05:08 PST 2012


Mark S. Miller wrote:
> For const classes specifically, my intention is that the "private state"
> object is "sealed", i.e., it is non-extensible and all its properties
> are non-configurable, but generally writable unless declared otherwise.

Ok, so I present the concerns and then the proposed solutions.

Concern I. An efficient implementation. The private state should be 
allocated with the instance as part of a single allocation, and with no 
undue burden on the garbage collector. (from the class proposal)

(the quote above is also part of this concern)

Concern II. The ability to have private mutable state on publicly frozen 
objects. (from the class proposal)

I went as far as thinking of blending private state with the object 
itself when possible (instances of const classes seemed to be such), but 
this invalidates such optimization (unless freeze would magically left 
private state writable).

Concern III. The ability to use private(foo) on any object and defining 
private stqte lazily, if not present. (me)

Concern IV. No need for 'private foo [= bar];' construct, ability to use 
'private(this).foo = bar | null;' instead having same outcome. (me)

Concern V. We don't want any observable private state object in any 
revised classes proposal. It may be that the current proposal is a bit 
out of date on this, just in terms of terminology and its possible 
misinterpretation (Brendan Eich's reply to this thread)

Solution.
   0. Define prvName as Name.create() for internal use of the private 
keyword inside the class code.
   1. Let 'private foo;' in construct be sugar for 'private(this).foo = 
void 0;'.
   2. Let 'private foo = bar;' in construct be sugar for 
'private(this).foo = bar;'.
   3. Read access to private(foo).bar should
     - check if foo[prvName] exists
     - if not, return undefined
     - if yes, return foo[prvName].bar
   4. Write access to private(foo).bar should
     - check if foo[prvName] exists
     - if not, try to foo[prvName] = null <| {} (may raise errors)
     - do foo[prvName].bar = valueToBeWritten (may raise errors)

The errors in 4. are fine - the former means the object is not 
extensible, so lazy private state cannot be created, but it is 
semantically ok; the latter means the private state itself is not 
extensible or the property itself is read-only.

Why it works for const classes: It creates those properties in private 
state, which are written (declaration is desugared to write) in 
constructor. Then, the instance is frozen/sealed and the private state 
is sealed.

Concern I: OK. Maybe smart compiler can do static analysis of the 
constructor code and create the object prefilled. But I think developer 
can do this as well, hinting nicely to the compiler by code like:

   class Foo {
     constructor () {
       ...
       private(this).{
         // all or majority of the private data
       }
       ...
     }
     ...
   }

Concern II: Freezing object does not make private state itself frozen. OK.

Concern III: Solved by lazy creation of private state.

Concern IV: Solved by desugaring, making the cases identical, enabled by 
lazy creation.

Concern V: prvName is not visible, private names are not in key list.

> --
>      Cheers,
>      --MarkM

Herby

P.S.: I posted another thread with proposal for shortcut for 
private(this), but it still did not reach the list (I see private(this) 
as non-elegant, too).


More information about the es-discuss mailing list