rdking / proposal-class-members

https://zenparsing.github.io/js-classes-1.1/
7 stars 0 forks source link

Syntax inconsistency: public static property / public instance property #2

Closed mbrowne closed 5 years ago

mbrowne commented 5 years ago

This syntactic inconsistency seems problematic:

const static a = 1
readonly z = 0

Especially when you consider that let/const is used for all data properties/variables except public instance properties:

const static a = 1
const b = 2
let c = 3

// only this one doesn't use 'let' or 'const'
readonly z = 0
mbrowne commented 5 years ago

I wonder if something like this might be preferable:

prop y = 0
readonly prop z = -1

...which has the added advantage that you could declare writable public properties and not only readonly ones. I realize that encapsulation is an essential part of OOP and some people might see this as a disadvantage, but given the history of JS and the fact that you can already declare public writable properties in the constructor, I think this would be more consistent with the existing mental model of the language and developer expectations.

rdking commented 5 years ago

Those 2 declarations are very different things. Nowhere in ES do you have a chance to glean a property descriptor from anything declared with let or const.

const static a = 1 defines a non-writable instance variable in the constructor instance closure. readonly z = 0 defines a non-writable public property of the prototype.

Are they similar? Maybe, but the syntax reflects the fact that they are 2 very different things. I don't see any issue with adding an additional keyword to make it clearer that you're creating a public property, but that in itself may just be moving the inconsistency. It would go from inconsistency between data member definition styles to inconsistency between public member definition styles.

Sadly, the inconsistency itself is immutable. However, since there is a distinct difference between an "instance variable" and a "public property". It seems to me to be a little less problematic to have that inconsistency help reflect that 2 different types of things are being created.

I'm by no means sold on this. Just give me a good enough argument, or enough people who find this might be problematic.

mbrowne commented 5 years ago

const static a = 1 defines a non-writable instance variable in the constructor instance closure.

What the heck is a static instance variable? At least to anyone with an OOP background, that's a contradiction in terms. I'm guessing you mean that static const is a non-writable "static class variable" or something like that, which would be defined in a constructor-level closure rather than instance-level. Because if static means something instance-level, that would be very confusing.

Just checked the readme again, and this part makes sense to me:

Hidden static members are placed in a separate closure attached to the constructor function. Such members can be accessed via the :: operator with the constructor function itself as the target object.

But the phrase "Static Instance Variables & Constants" (also in the readme) does not.

Anyway, assuming that static variables are associated with the constructor function rather than the instances, that still leaves the question of how to declare a publicly-accesible static property. The ability to do so can be very useful. Yes, I realize that you can already do MyClass.myStaticProp = whatever after declaring your class, but I think it's important to have some way to do this inside the class declaration rather than after it.

rdking commented 5 years ago

What the heck is a static instance variable?

Sorry about that. Spent a good portion of the day re-writing the spec for this proposal. My brain is a little fried. Where I said "instance variable", I should have said "class variable". There's nothing wrong with calling it a "static class variable" except that it's redundant given that all "class variables" are inherently static. I'll make adjustments across the docs again.

As for public static properties, that's pretty straight forward. I didn't leave that out at all.

class  A {
  static publicProp1 = 0;
  static publicProp2;
}
rdking commented 5 years ago

I've made some updates to the README.md. There's still some more clarifications I need to make, but your issues should be addressed now.

rdking commented 5 years ago

The latest version of README.md is ready.

mbrowne commented 5 years ago

It seems my original objection here was due to being unaware of the static publicProp syntax. So it is logically consistent: let/const is required for instance or static variables, but not properties. I'm not sold on keywordless public data properties, because that means there are now three kinds of syntax to sort out:

  1. let/const (instance variables)
  2. keywordless (public prototype properties)
  3. keywords (static and readonly properties)

But that's more of an overall concern so I'm closing this...