Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Use private.x syntax for referencing private fields #18

Closed
petamoriken opened this issue Jan 16, 2016 · 10 comments
Closed

Use private.x syntax for referencing private fields #18

petamoriken opened this issue Jan 16, 2016 · 10 comments

Comments

@petamoriken
Copy link

Please see this comment.

@petamoriken
Copy link
Author

IMHO, If protected fields might be a future extension, private keyword is better than # character.

class Foo {
  private x;
  constructor() {
    private.x = 1;
  }
}

@petamoriken petamoriken changed the title protected fields protected fields, private keyword Jan 16, 2016
@petamoriken
Copy link
Author

Sorry, I understood that private keyword couldn't make below Point#equals.

class Point {

    #x;
    #y;

    constructor(x = 0, y = 0) {
        this.#x = +x;
        this.#y = +y;
    }

    get x() { return this.#x }
    set x(value) { this.#x = +value }

    get y() { return this.#y }
    set y(value) { this.#y = +value }

    equals(p) { return this.#x === p.#x && this.#y === p.#y }

    toString() { return `Point<${ this.#x },${ this.#y }>` }

}

@petamoriken
Copy link
Author

However, this function produce the puzzle.

class Point2d {

    #x;
    #y;

    constructor(x = 0, y = 0) {
        this.#x = +x;
        this.#y = +y;
    }

}

class Point3d {

    #x;
    #y;
    #z;

    constructor(x = 0, y = 0, z = 0) {
        this.#x = +x;
        this.#y = +y;
        this.#z = +z;
    }

    equals2d(p) { return this.#x === p.#x && this.#y === p.#y }

}

let point2d = new Point2d(1, 2);
let point3d = new Point3d(1, 2, 3);

point3d.equals2d(point2d);  // Illigal

So, I affirm to use private keyword.

@zenparsing zenparsing changed the title protected fields, private keyword Use private.x syntax for referencing private fields Jan 17, 2016
@zenparsing
Copy link
Member

@petamoriken The equals2d method is obviously not going to work on an instance of another class. You'd need to use public properties instead, e.g.:

class Point3d {
    #x; #y; #z;
    equals2d(p) { return this.#x === p.x & this.#x === p.y }
}

Although I'm not sure the example makes much sense to begin with.

In any case, you could fix your syntax suggestion by allowing something like:

class Point {
    private x, y;
    equals(other) { return private.x === private(other).x && private.y === private(other).y }
}

I considered the private.something syntax, and there is a nice conceptual simplicity to it. But unfortunately:

  1. It's unexpected, given class syntax in other languages. Users are going to expect to be able to do this.something and will probably be surprised that they have to do private.something instead.
  2. The ergonomics are kinda bad. People already complain about having to type this. repeatedly in their code. Can you imagine having to type in private. repeatedly instead?

@petamoriken
Copy link
Author

@zenparsing Sorry, exactly the example is not good.

The equals2d method is obviously not going to work on an instance of another class. You'd need to use public properties instead, e.g.:

class Point3d {
    #x; #y; #z;
    equals2d(p) { return this.#x === p.x & this.#x === p.y }
}

Yes but, I propose that private properties should be hidden even on an instance of "the same class".
The reason:

  1. In other languages, it's ordinary. (It may be wrong because of my lack of experience.)
  2. I guess this private fields proposal is a syntax sugar of this WeakMap idiom, and no one considers protected state by WeakMap (see top of this issue). In the future, protected state will be discussed, this function produce the puzzle.

I considered the private.something syntax, and there is a nice conceptual simplicity to it. But unfortunately:

  1. It's unexpected, given class syntax in other languages. Users are going to expect to be able to do this.something and will probably be surprised that they have to do private.something instead.
  2. The ergonomics are kinda bad. People already complain about having to type this. repeatedly in their code. Can you imagine having to type in private. repeatedly instead?

IMHO, because new.target exists in ES2015, private. is not confused.
new.target changes a value where it called, this spec is similar to private., isn't it?

@zenparsing
Copy link
Member

I guess this private fields proposal is a syntax sugar of this WeakMap idiom, and no one considers protected state by WeakMap (see top of this issue). In the future, protected state will be discussed, this function produce the puzzle.

First, private fields aren't really syntax sugar for any WeakMap idioms (although you can you WeakMaps to simulate private fields). They are a user-facing syntax for ES object "internal slots" (which are part of the ES specification).

Second, I'm not sure how class-private (as opposed to "instance-private") fields has any bearing on protected state or syntax?

MHO, because new.target exists in ES2015, private. is not confused. new.target changes a value where it called, this spec is similar to private., isn't it?

new.target gets the value of the operand supplied to the new operator. It's not a commonly used feature.

Regardless, my previous two points still stand:

  1. In other languages, users just type in this.whatever. Why should we make them type in something different for JS?
  2. Having users type "private." for each private state access is a lot of typing. It's just too verbose.

@petamoriken
Copy link
Author

@zenparsing

In other languages, users just type in this.whatever. Why should we make them type in something different for JS?

It will change the meaning of this by the environment. Providing other object is better.

Having users type "private." for each private state access is a lot of typing. It's just too verbose.

That's right, but, using private that have already reserved is better than using # character that will get new meaning.

I'm sorry that I should have discussed this issue in wycats/javascript-private-state, I confounded them.

@zenparsing
Copy link
Member

It will change the meaning of this by the environment.

It changes property lookup rules if the name to the right of the "dot" is a special private field name (i.e. starting with "#" or "@", depending on what we choose). That seems fine to me.

using private that have already reserved is better than using # character that will get new meaning.

But you're proposing giving "private" a different meaning than is found in similar languages, so you're not actually saving anything conceptually. And it's longer. : )

@zenparsing
Copy link
Member

Going to close this for now - cool idea though!

@petamoriken
Copy link
Author

@zenparsing
OK. Thank you for your discuss! 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants