tc39 / proposal-class-public-fields

Stage 2 proposal for public class fields in ECMAScript
https://tc39.github.io/proposal-class-public-fields/
488 stars 25 forks source link

Automatically adding a new public API member [Symbol.classProperties] to every class that uses a given syntax is not good #4

Closed domenic closed 8 years ago

domenic commented 9 years ago

This makes this proposal unusable for libraries which need to conform to specified API contracts, for example jsdom.

It's also very strange that using syntax in an otherwise-normal class suddenly introduces a new member on that class that you didn't declare.

A realistic alternative would be some kind of reflective API that is not installed as a member on the class and on its prototype. Although the motivation for this entire reflective API story is lacking, being only a couple sentences in the current docs.

jeffmo commented 9 years ago

This makes this proposal unusable for libraries which need to conform to specified API contracts, for example jsdom.

Can you expand on this a bit? Storing into slots isn't necessarily off the table and might help here, but I want to be sure I understand your concern first.

jeffmo commented 9 years ago

Although the motivation for this entire reflective API story is lacking

I will try to expand on this a bit in the proposal text as well, but it mostly boils down to the fact that without a means of reflection and userland adjustment we'd be leaving a hole in the way one can inspect and update the structure of a class's declared structure.

Passing a class to a library (for example) should allow that library to tweak the class's structured definition in the same way it can do now. Test systems should be able to introspect class definitions for purposes of asserting/testing/mocking/etc them. Etc

wycats commented 9 years ago

I agree and prefer Reflect.defineField for this purpose (it also aligns with decorators better).

I plan to submit a PR tomorrow for discussion :)

domenic commented 9 years ago

The DOM interfaces do not have this extra symbol present. So a conforming implementation of them, e.g. jsdom or a self-hosted browser implementation, cannot use this proposal as is.

That motivation is not very good. Classes have many properties today (set in the constructor) that are not exposed to reflection.

Anyway, all of this is moot as per #1 this proposal is simply impossible as is. You cannot allow the insertion of synchronously running user code in the middle of the HTML parser or the property descriptor creation algorithm or anything else, without breaking a ton of assumed invariants.

jeffmo commented 9 years ago

The DOM interfaces do not have this extra symbol present.

Nor would they need it present until they wanted to add declared properties. I must be missing something here so I'm very interested in understanding. I don't intend to hold up the slots idea based on this, but I do want to understand the context so I can make sure it's considered in any future iteration.

Classes have many properties today (set in the constructor) that are not exposed to reflection.

Indeed, and this poses a problem today -- we don't know which properties are to be expected on a class because they are assigned (often dynamically and occasionally) most often in method logic. The purpose of this proposal is to allow the user to state the intended properties for the class for exactly this purpose (whether assigned at construct time or later). So I guess the succinct justification for reflection is to bring class properties into the class's structure with the same or similar fidelity that one can understand a class's method structure.

domenic commented 9 years ago

All I am saying is that I cannot use this proposal in jsdom or in self-hosted interfaces. Which is sad and reduces the utility of this proposal. I would like a variant on this proposal that is usable in such environment.

Indeed, and this poses a problem today

I don't think this problem is solvable, given that JavaScript still allows the freedom to add or modify properties at any time. It might be solvable in another language that requires static shapes, such as StrongScript or some variant of TypeScript. But in that case it's a matter for those other languages to standardize, not to make a only-works-sometimes effort in JavaScript for.

jeffmo commented 8 years ago

This was addressed in a recent update to the abstract. Spec text will follow soon