-
Notifications
You must be signed in to change notification settings - Fork 37
Stop this proposal #10
Comments
I agree. the OO is useless. and getters/setters too. |
I totally agree with him. In the traditional class based approach, this might be needed, so as TypeScript does. But JavaScript is not class based, it's based on prototype linked object oriented language. "Class" in Javascript is a way different from others, and mixing original class based features into JavaScript is really bad idea. IMO, generally I don't use "private field" in JavaScript, because it doesn't needed at all. Some of the people can say: "What if you need a encapsulation in JavaScript?" I know, using closure to implement encapsulation and using private field is quite different, not just syntactic looks, but I just want to ask one question: "Does it really need encapsulation in JavaScript?" If you really needed that one, I just recommend to use TypeScript. This proposal makes hard to read other people to didn't know what # means. Making readable code is also most important part of modern days, there is no programming language that uses "#" as private field in class. If this proposal passed, later we couldn't understand what code looks like. Who knows? What kind of strange syntax will added future? |
It's true, this proposal rests on people being able to learn what Aside from the difficult of learning that |
@littledan personally, for me it's quite easy to learn, but I simply don't like the look of the code with |
@futagoza But private fields already got stage 3, there will be |
@trotyl I'm not objecting, I'm giving my opinion on the syntax look. For private values it looks fine, but once you start using it for methods as well the syntax starts to look weird to me, but if it goes through anyway because others want it, I don't mind. |
This spec causes confusion with |
On the contrary, I find the |
Once you have private fields, private methods and accessors are a natural extension; and if you haven’t them, people will try to emulate them using private fields. Reusing the example of the explainer: class Counter extends HTMLElement {
// real private field
#xValue = 0;
// emulated private accessors (not really accessors, because of syntax constraints)
#getX = function () { return #xValue; };
#setX = function (value) {
this.#xValue = value;
window.requestAnimationFrame(this.#render.bind(this));
};
// emulated private method
#clicked = function () {
this.#setX(this.#getX() + 1);
};
// etc.
} So,... it’s too late to stop the private stuff now; it had to be done with private fields. |
This is a sign that JavaScript is nearing its end. Something will overtake it, like Dart tried to do. |
I agree. Because the design philosophy is different, these two are not necessary for javascript. |
@tasogare3710 Do you think JS has enough facilities for encapsulation already? |
@stevenvachon I never understood this idea that languages reach their end once they get features. Do you have an idea of a language that went through that kind of pattern? (C++ seems to be doing very well within its domain, for one; I think its biggest problems (undefined behavior and lack of memory safety) are not about too many features). |
@littledan it's not the features themselves, but the cryptic syntaxes that JavaScript is often limited to. |
@stevenvachon If we used |
@littledan If soft private is not enough, I think that other languages should be used. In addition, # is generally a symbol representing the interned string in the language where the symbol is first class citizen. Nobody thinks that it is a private field. I do not want to hard code reading. |
As I understood it, |
|
@littledan Why do we need to introduce privacy newly into the property? Since javascript uses properties from the beginning(consistently from original javascript to currently), internally always have slots. This will have the same effect as newly introducing privacy. |
Yes , it should be stopped! The # is the same as !@$%^&*() class Person{
$x=0;
$getX(){
}
} |
The issue with Sigil is only a small misfortune. I think that people who oppose this proposal are mainly the same thought as @rico345100. |
The The
Why not start with adding the new behavior and enabling it through a comment annotation using a babel plugin like so: // @private
foo() {} Then people can try it out, see if they use it, if they like it, etc. FlowType could adopt it and type check using it. And this comment syntax might even be fine for a long time. Then if its a great feature, start the discussion about the declaration syntax first. Maybe introduce Then we could turn the |
This should not be part of JavaScript. If people want to use this kind of thing, they should use typescript |
The first thing to mention is that @littledan said "...and the proposition that classes are bad", but the class is not bad. I agree that the And, i understand one thing. People who dislike However, this issue is an issue against the private field itself for the reason "javascript does not need a private field". I have a suggestion. How about separating Sigil issue from this issue? |
@tasogare3710, we've heard from a lot of people, especially library authors and frameworks like node, that they do need private fields. Closures don't provide the same sort of encapsulation - they don't provide a good way for many objects to be able to examine each other's state without exposing that state to the world. For example, it's very difficult to use closures to implement something like class Point {
#x;
#y;
equals(p) {
return this.#x === p.#x && this.#y === p.#y;
}
// other methods
} So, while I understand that you have not had a need for private fields, that's not enough to establish that the language doesn't need them, especially when we've heard from a lot of people that they really do. |
What makes JS nice is that it is hackable and monkey-patchable. You can poke around. There are so many internal node things that I've used and monkey-patched over the years that are absolutely necessary. And sometimes its good to be able to look around just for debugging purposes. E.g. inspecting the internal state of a library you are using. I think if you are a library author, perhaps you have different priorities than a consumer. If there is a bug, you already have the project checked-out, and you can fix your own library, or you know potential workarounds. If you are consuming a library, you just want things to work, monkey-patch if necessary, and move on. Making everything private assumes that there are never bugs that can only be debugged by inspecting the internals, but every library has bugs. And since there are so many toolchains involved these days, its not so easy to just git clone, npm link, and inspect, and usually npm dists are not bundled with sources. |
@vjpr, that's never been entirely true - you can't poke around inside of closed-over variables (except with debugging tools, of course, but debugging tools will be just as free to modify private fields as they are to modify closed-over variables). Indeed, the sort of privacy provided by closures has very much served as a model for private fields. That aside, this is the reflection vs encapsulation debate. It's one the committee is very aware of, but having considered it at length we came down on the side of encapsulation. There are of course major benefits to allowing reflection, which we all are familiar with, but there are also real costs. (And I think that's something other languages have been finding as well.) |
class Runner {
#items
run() { this.#items.map(x => this.#foo(x)) }
#foo() { console.log(x.foo) }
}
const runner = new Runner
console.log(runner.#items) Every dev would make There are two cases:
I've read the faq, and a bunch of the discussion issues here. I think library developers requests are being prioritized over users, and there are more users than library developers, and as I mentioned above they have different priorities. Anyway, if it has to happen, then please use the |
@bakkot My opinion is consistent. If you have problems with the following code, you should use other languages instead of javascript. var private_fields = new WeakMap
class Point {
constructor(x, y) {
private_fields.set(this, {x, y})
}
equals(p) {
var {x: my_x, y: my_y} = private_fields.get(this)
var {x, y} = private_fields.get(p)
return my_x === x && my_y === y
}
}
var __x__ = Symbol("x")
var __y__ = Symbol("y")
class Point2 {
constructor(x, y) {
this[__x__] = x
this[__y__] = y
}
equals(p) {
return this[__x__] === p[__x__] && this[__y__] === p[__y__]
}
}
Delegation does not require other different objects in advance to make a new object. However, private fields currently have classes only. This leads to the wrong design in javascript which is a prototype based OOP. The wrong design is to give the illusion that javascript must prepare another different objects before creating a new object. It is a characteristic of inheritance, not delegation. In javascript(and prototype based OOP), constructor functions and class constructors(these are instance creations) must be used to remove boilerplate code for initialization. There is "one-of-a-kind objects" created by other methods in javascript. function SameKindObject() {
// A lots of initializations.
// However, it has common properties.
}
var common1 = new SameKindObject
var common2 = new SameKindObject
var common3 = new SameKindObject
// this is "one-of-a-kind"
var not_common = {
// include unique properties
} Even though allow private fields, you can not have private unique properties in "one-of-a-kind objects" in the current proposal. This part has room for discussion. Btw, is inspection included in reflection? Javascript is an easy to inspect by nature( Although we should not test private fields, inspection is essential for logging, debugging and externalization etc. However, private fields may make to these difficulties. |
Or use development tools, or for that matter just make it public.
Again, or just make it public. I don't understand why you'd make something private which you wanted users to have access to.
Many, many developers have asked for this. This is precisely the hard-private vs soft-private debate. They're not saying "it's hard to tell what is private". They're saying "if this is not actually private, it's part of my public API, and my users will read and change it regardless of how much I intended them not to, and that makes my life much more difficult".
It is part of our mandate to balance different needs, yes. But most users don't need to access internal state of libraries, I think; it's only a fairly small subset who want this. And to a large extent the needs of library authors are the needs of users, because users need those library authors to keep maintaining their libraries.
We discussed it at some length a while ago and decided to go with the current setup. We might revisit if there's some reason to, but it would have to be something more than "I don't like it".
If something comes up which we hadn't thought about, reasonably high. It's very unlikely that we will change anything purely on the basis of things we've already discussed at length, though, like hard vs soft private.
This is not the opinion of the committee. WeakMaps work for this, but are non-obvious, somewhat awkward to use, and error-prone.
Yes, this is something we've thought about. We may well add them later, just not as a part of this proposal. However, this use case is already reasonably well met by closures, I think: var priv = 1;
var obj = {
pub: 2;
method() {
return this.pub + priv;
}
};
Yes.
Not always. There has never been a way, as part of the language, to inspect the variables a function closes over.
Again, this is the reflection vs encapsulation debate, which we've talked about a great deal. These are points which have been brought up (many times) before, and even taking them into account, we still felt that having a reasonably easy way to provide encapsulation was important. That said, logging and debugging can be accomplished by development tools, which can access whatever they want, including private fields. And I'm not sure what you mean by externalization; there are a couple of ways I normally encounter that term, but none of them seem like they'd really be impeded by private fields. In any case, if the developer doesn't actually want encapsulation, they shouldn't use private fields. There is a fundamental conflict between reflection and encapsulation; if the benefits of reflection (including inspection) to a specific developer outweigh the benefits of encapsulation, then just don't use private fields. That's not a sufficiently good reason to deny them to everyone. |
The changes about JS recently really give me a strong reason to learn about TS. The stupid commitee push me out of JS!!!! People will vote by code. |
Why did they favor the # syntax instead of breaking backward compatibility? |
I Don't think JavaScript need private Class fields to implement private variables with closure functions. |
For instances, it does, since the only other way to do it is with closed-over WeakMaps. |
This comment has been minimized.
This comment has been minimized.
Good feature, I'd like it (add to eslint ban rules) |
I hope it will be abandoned. If not, well, time to learn some new programming language because I don't want to mess with this ugly syntax. |
Also +1 to stop it, 'cause of rejecting this: #8 UPD: To not to make another comment: My reasons are primary about wheel-reinventing synthax. Backwards compatibility could be avoided by not using it without transpiler in new code. With the same efforts, we could just do i.e. About public fields: it's not actually a problem to hide it, because of the fact, that it needs js engines work. If one prefers small work with engines and then headache throughout js coding, I don't share his idea. |
The first two items in the FAQ explain why that syntax isn't used. Your +1s are just noise if you're not actually addressing the reasons. |
Maybe its time to go back to the drawing board if your goals require such bizarre and unjavascripty syntax in order to "achieve" them. Maybe the goals are too stringent. Maybe javascript simply can't be fixed without breaking backwards compatibility. Honestly, the last point should not be surprising based on how long javascript has maintained backwards compatibility. You can't cater to old code forever. This proposal is a mess. |
I recently created scrolling-menu using private methods/fields and I was surprised at how much I did like it, despite my previous complaints. Check it out to see for yourself. |
Was it not Katy Perry who once so wisely said
|
Maybe before she learnt how to javascript and understood there's no need for them. Seriously, I'm doing javascript almost every day for the last 12 ys and I've never found myself in the situation like "OMG, I wish javascript had private fields, it would make my life so much easier" and I've been talking to many people in the last few months about this and they actually agree with this. I don't know who you are talking to and why do you think that this is such a great idea (that it's already in stage3) but there's certainly a lot of people who are not active here nor they are blogging on medium and yet if you tell them about this proposal they will just facepalm and say, yeah, javascript :-/ And they don't understand a lot of other of your work, for example exponential operator - when you explain that it's just sugar for |
Don't forget that There are plenty of valid use cases for private fields. The common convention right now is to use one or two underscores ( Private fields give developers control over encapsulating what logic of their code is exposed for consumption. It's no different than private fields in Java, C#, or any other language. When JS started, it was not used as a full featured language. Now that JS apps are becoming more and more complex, missing features such as traditional classes and private fields become more and more useful. |
Or you can treat all fields as private and provide methods for what's
supposed to be public. And contrary for data objects, treat them as structs
with public data but without any methods.
And no, it's not going to be like in java/c#, these langs dont have
prototype chain, there are no types and there are so many differences.
Also, I was talking specifically about exponential operator, I agree about
classes but there are many cases where the use-case is very hard to imagine.
Not to mention for example pattern matching, which is going to be very
limited without types and so again it feels like we are going for quantity
instead of quality.
|
@cztomsik if they're accessible or observable from outside the class, you're treating them as public. If you want them to be private, they actually have to be private. Discussions of other proposals belong on those proposal repos. |
JavaScript already has private methods. This proposal is merely syntactic sugar. The reasons for its syntax has been explained and there're no better alternatives. See my link above -- it's actually not ugly. |
We all know there's reasons this syntax has been chosen. But don't pretend sigils aren't Ugly AF. Case in point. |
@ljharb developers are not dumb - having a gun doesn't imply shooting yourself. @stevenvachon it's syntax sugar for something you actually don't want, private methods are impossible to test, monkey-patch and introspection devtools will be harder too (if possible at all). I've actually seen your repo and my points still apply - try to write some tests and you'll notice the difference. There is a reason why people are sometimes unit-testing "private" methods. There are also valid uses for monkey-patching (polyfills & zone.js just to name a few). |
@cztomsik if that’s the metaphor you want to use, then actual statistics say that yes, it does imply exactly that, far more often than is accepted - but let’s plead stay away from that metaphor here. Private things are impossible to test because private things should not be tested - test the public api and behavior/semantics, and only that. Devtools have superpowers, so nothing is impossible for them, including introspecting private fields. There’s no need to runtime monkeypatch; that’s what forking is for. |
Um, there are tests. |
i think it would make a lot of sense to actually list libraries (or related proposals) where authors "asked for private properties and methods". Because right now (even by reading meeting notes) - there is no transparency on who and why want this.. And maybe if the case is compelling for wider audience, "twitter" auditory (like myself) will stop over-reacting. p.s.: this proposal also pushes 4 separate things at the same time
I think, most people would actually accept private fields, if more conventional syntax was proposed and there were more motivational examples. |
I'm not writing tests to make somebody happy, I'm writing tests to avoid bugs and testing private method is sometimes the most simplest and straightforward way to cover something - or at least some critical part. What you say is naive and very disconnected from reality. Time spent for tests is time which could be used for features, and so that's why people do it and why it's totally fine. What you propose is nice in theory but often a lot of extra work (with no real benefit) in practice.
Ok then, let's say I want to do such tool - how can I do it? Where's some API for this? Can I call it from user-space? Or do I have to fork V8?
I'd agree that it's something which should be avoided, but you're wrong that there's no need, there is - and polyfills & zone.js (mentioning again, for some reason you've ignored those) are exactly that, react-hot-loader does some nasty shit too and that's done by react core devs (who arguably could bake some support there but they didn't). @stevenvachon In that case, I'm sorry I had to miss them, but my points are still valid. |
This is my biggest problem with this. It seems like these people don't give two craps about who hates this proposal or who want it. THEY want it and that's all that matters. They don't seem to care to show us evidence that the javascript community wants this. That attitude is toxic and doesn't belong in a standards-making process. The burden of proof is on the proposers to show us that this is wanted by the community. Telling us "there's no other way to do this" is simply not relevant. |
I think it will impair existing elegance of Javascript so it should be omitted.
The text was updated successfully, but these errors were encountered: