Proposal: Alternative public, private, static syntax and questions
See
tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md
for
clarification of the #
sigil choice.
That is a very useful document. I guess I haven't opened the proposal in a while.
He puts a lot of stress on preserving encapsulation where as I was planning on relying on a type system to optionally provide that feature. That is given a dynamically typed variable accessing privates would probably be allowed. (Statically typed variables would detect and not allow that kind of like a more strict usage). I think the inheritance and using private names as keys are decent arguments. That said I'm personally not against allowing inherited classes access to their base class private members though. That is private acting like protected in C++ I think is fine for ECMAScript. Am I alone in being fine with that behavior? I'm kind of leaning toward: tc39/proposal-private-fields#14 that syntax for a true private class scope variable.
The key name conflict seems niche outside of key based data structures. I wrote an ORM system before and just used a key called "internal" to hold data in the past to get around a similar conflict. The # sounds like a similar workaround when required but allows everything to not be hidden in a nested object which is nice.
Are "protected" class fields a thing in this discussion at all? Or is the idea to use or implement a friend system later somehow?
With how I use Javascript currently, and the direction I want ECMAScript to head - toward types - I don't particularly like the proposal or necessarily support its goals toward creating an ideal encapsulation. (Also I really dislike the syntax).
Inline
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
On Thu, Jan 11, 2018 at 2:10 PM, Brandon Andrews <warcraftthreeft at sbcglobal.net> wrote:
That is a very useful document. I guess I haven't opened the proposal in a while.
He puts a lot of stress on preserving encapsulation where as I was planning on relying on a type system to optionally provide that feature. That is given a dynamically typed variable accessing privates would probably be allowed. (Statically typed variables would detect and not allow that kind of like a more strict usage).
The issue with leveraging static typing is that JS has never been a
statically typed language. Also, private fields are generally
something you shouldn't need static types to detect - even without the
sigil, it is in fact possible to require something like private foo
as a declaration and alter property lookup within classes to
check for local private names (for class instances) before public
ones. (Decided to create a GH issue out of this:
tc39/proposal-class-fields#69)
I think the inheritance and using private names as keys are decent arguments. That said I'm personally not against allowing inherited classes access to their base class private members though. That is private acting like protected in C++ I think is fine for ECMAScript. Am I alone in being fine with that behavior? I'm kind of leaning toward: tc39/proposal-private-fields#14 that syntax for a true private class scope variable.
Note: not even Java allows subclasses to access superclasses' private fields.
The key name conflict seems niche outside of key based data structures. I wrote an ORM system before and just used a key called "internal" to hold data in the past to get around a similar conflict. The # sounds like a similar workaround when required but allows everything to not be hidden in a nested object which is nice.
Are "protected" class fields a thing in this discussion at all? Or is the idea to use or implement a friend system later somehow?
Massive drawback of the # semantic: making a private variable public (a
common transition when the usage of a class evolves) requires a lot more
refactoring, since you have to remove every # for the variable across the
class and replace it with this
. Failing to do so in just 1 instance
creates a bug. The same drawback applies for privatizing a public variable,
in reverse.
Besides which as an instance variable I want to learn this
as the access
prefix. I don't want to have to learn 2 different access prefixes, one for
public and one for private. Access control in code only has one real
material advantage: simplifying the public interface of a class by hiding
factors that have no use from outside it. This is not big enough of an
advantage to introduce a new access prefix, which can lead to a plethora of
bugs due to confusion and/or publicization/privatization transitions during
the evolution of one's system.
I hadn't read the proposal properly, but the thrust of my point is the
same, read remove/add #
instead of "replace with this"
The proposal does a very poor job of explaining this, but #foo
is a
shorthand for this.#foo
, much like {foo}
is a shorthand for {foo: foo}
. That kind of thing has precedent in other languages:
CoffeeScript uses @foo
as a shorthand for this.foo
(although it's
not private), and Ruby uses @foo
as a shorthand for self.foo
(which is private by default). Most traditional strongly typed OO
languages just let you omit this
and just reference the property as
if it were a variable in scope, without the sigil, and Ruby does as
well for methods.
It saves 5 characters in the most common case, accessing private properties of the current instance.
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
Another problem with this.#myVar syntax is that it is not extensible to other access control definitions in future. For example "readonly" or "protected" etc.
I'd have to disagree. There are ways to spec around this, and as long as you make explicit what you're inheriting, it's not as hard as you might think.
Isiah Meadows me at isiahmeadows.com
Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com
sirisian/ecmascript-class-member-modifiers
Is this closer to what you think would be acceptable? Essentially C++/TypeScript kind of modifiers. Or does that still have issues?
Definitely TypeScript's system is better than the proposal. I often publicize private variables and privatize public variables (In other languages). The # scheme increases the effort to do so and increases the chances of bugs being introduced in doing so. This is why I oppose the # scheme.
I also don't accept the premises given in the justification, based on the very fact that changing the access status of a variable would make it clash with another variable, if this.x and this.#x were both allowed: I don't accept therefore that allowing this would be desirable let alone necessary.
I created a thread about static constructors a while ago here: esdiscuss.org/topic/proposal-for-a-static-constructor-and-static-member-variables It left me with some design thoughts so I wrote up the following proposal idea below, but never posted it because I couldn't understand why the current Stage 3 private proposal introduced a new token '#'. Maybe I missed something obvious in the design of the grammar or the way the internals work, but I didn't understand. Also I didn't understand why it does this.#x which seems verbose since every language with private members doesn't introduce this clutter. (It's like writing private everywhere you use it rather than one place which can't really be the simplest implementation right?).
sirisian/ecmascript-public-private-static
In the above proposal above I stuck with 'private' and 'static' keywords since it seems closer to other languages. Also I kept with the idea that default behavior is public to not introduce breaking changes. Can someone explain why ECMAScript can't use something like I proposed?