8 ms·
JavaScript TC39 implementing hashmark private class fields
- svckr 9y agoWouldn't it be funny if we see a resurgence of compile-to-js languages? If JavaScript keeps on piling up layers I could see people longing for a simpler, smaller language. Where there was coffeescript to highlight functional features in JS in a time where most JS was imperative, maybe we'll see a language that takes the OO sugar away to, again, reveal the functional language that's underneath.
- kodablah 9y agoFWIW the arguably ideal target for compile-to-web tech, WebAssembly, is adding some OO too [0]. 0 - https://github.com/WebAssembly/gc/blob/master/proposals/gc/Overview.md#objects-and-method-tables https://github.com/WebAssembly/gc/blob/master/proposals/gc/O...
- just_astounded 9y agoUntil wasm has GC, we're not likely to see much in the way of compile-to-web outside of C, C++, or Rust.
- pjmlp 9y agoThere is already a .NET prototype. https://github.com/SteveSanderson/Blazor https://github.com/SteveSanderson/Blazor https://www.youtube.com/watch?v=MiLAE6HMr10 https://www.youtube.com/watch?v=MiLAE6HMr10 WebAssembly without native GC support is no different that targeting a real hardware CPU. One just has to implement it as well. As soon as WebAssembly reaches a more mature state, expect the resurgence of plugins and this time around we won't be able to disable them.
- gulbanana 9y agoblazor is not .NET compiled to WASM. blazor uses a .NET runtime called DotNetAnywhere, which is written in C and compiled with emscripten. the actual .NET IL is then interpreted at runtime by DNA.
- pjmlp 9y agoTrue, but the fact is that people are already toying with the idea of bring such runtimes back into the browser. Also if you bother to read the meeting minutes from WebAssembly meetings, developers from .NET team are present in such meetings.
- just_astounded 9y agoFancy!
- erikpukinskis 9y agoI am absolutely planning on forking an old school JavaScript off of the current runtimes. Or at least forking NPM. Not soon, because for now writing ES5 and running it on ES6 runtimes is Good Enough for my current purposes, as I'm still <1.0.0 so nothing really matters. But eventually I'm going to want a separate package space, and a separate language community. Modern JavaScript is cool, but it loses many of the benefits of old school JS: - only runs on newer devices - requires a precompile step - more language to learn - confusing concurrency model - confusing inheritance mechanisms - no incentive to learn to use closures, callbacks, and prototypes properly If I was willing to accept all of those things, I would just use a straight up better language, like Rust or Haskell, and get the additional benefits of type checking and deterministic performance. But I'm not interested in those things. I want a simple run-everywhere language for beginners to get started on. JavaScript used to be that, but modern JavaScript is not that language anymore. So, I'm going to bring back ES5. Why not. Who's with me?
- just_astounded 9y agoI remember when Crockford released the fantastic book, JavaScript The Good Parts. I disagreed with some of his opinions in that book, like avoiding the use of 'new', but that book - more than almost anything else, helped me educate folks on how to use js well. I used to order copies for every member of my team. I wonder if, instead of a fork, we can just make a case for a subset of js. Take the good new things, and ignore the rest, like a modern "Good Parts".
- mercer 9y agoCould you elaborate on the things you disagreed with? For example, for some reason I prefer avoiding new but I'm conflicted about it. I'd really like to hear your input as to why perhaps using 'new' is a good thing.
- erikpukinskis 9y agoNot OP, but new is dangerous because it makes it easy to put a lot of methods on an object, which is generally an anti-pattern. But sometimes that's what you want. I think a good use case is view models... You're not mutating anything, but you have a large number of consumers that are using different subsets of views on a piece of data. Constructing those by hand can be a PITA. Although, it's dangerous there. "Lots of views on a piece of data" might be a way of covering up "several disparate pieces of data in one place" or "data that is playing two roles when it should be transmuted instead". So, it's good to be afraid of new. I am still frequently decomposing a single index of objects into separate indexes of literals fairly often. I often get sucked into thinking something is an object when it's really just a few separate pieces of data indexed together. I also use new for libraries that export something that isn't exactly a function, but more a point of reference. For example my browser-bridge module is a point of reference for the computation between a web request and response. It's not really an action, but it's a thin representation over a handful of low level things you want to do in that space. It's purpose is to wrap up a set of concerns. Essentially, OO is generally bad in JavaScript, but sometimes it's good and in those cases new is nice.
- blargathon 9y agoKinda disappointing. I don't really like the # for privates. It's not an elegant solution. It feels a bit like a one-off hack honestly.
- pitaj 9y agoThere's not really a better way while maintaining encapsulation.
- just_astounded 9y agoDon't we already have solutions (closures/WeakMap) for hard encapsulation? Seems like '#' just pollutes the language and isn't really needed.
- pitaj 9y agoThere are solutions, but people want a syntax solution for it. Personally, I think that private instance properties should be a separate proposal from static and instance properties. That way, people could decide if they want some of it, or all of it.
- jwalton 9y agoRight now I'm prefixing variables I don't want external actors to change with underscores, which doesn't actually do anything, so is arguably more of a hack. :P
- BinaryIdiot 9y agoYou could encapsulate them with a closure. They don't _need_ to be exposed.
- cromwellian 9y agoDoes this scale in a large code base? What's the effect on memory and performance of hiding most of your fields by closures?
- dyeje 9y agoCan someone provide some context? This link just drops you into the middle of the argument.
- wavefunction 9y agoSome in the JavaScript community have been asking for private members as a language feature and some folks do not want this as there is a subset of JavaScript programmers who worry about many concepts from OOP "polluting" the relative minimalism of JavaScript. A fear I share to a certain extent. From reading the thread it sounds like some feel that the addition of private members is being accomplished by fiat rather than community consensus.
- mcphage 9y ago> From reading the thread it sounds like some feel that the addition of private members is being accomplished by fiat rather than community consensus. There's a difference between "community consensus" and "consensus of the people posting comments on this github issue".
- hajile 9y agoWhat evidence is there for the "silent majority"? There's no good way to collect that kind of data (after all, they're silent). It sounds like a baseless statement of "fact" to bolster an otherwise losing position.
- jpambrun 9y agoLook at the harsh responses that we can already see on HN and you will understand why I usually prefer to remain silent on such topic. A lot JS devs seem to feel very strongly about any kind of change.
- skue 9y agoBackground for this proposal and discussion can be found in this repo’s README and additional docs: https://github.com/tc39/proposal-private-fields https://github.com/tc39/proposal-private-fields
- watty 9y agoSeems like a pretty fair and well though out solution after reading the latest response by bakkot.
- Andrex 9y agoAgreed. I've been following the spec for a few months and while # is "ugly," it serves the purpose of the concept well and works with the current spec/implementations without much headache. Seems like a win-win to me and I haven't seen a convincing argument for why private # properties shouldn't move forward as they are.
- just_astounded 9y agoI think the concern is that if you look here: https://github.com/tc39/proposal-private-fields/issues/14 https://github.com/tc39/proposal-private-fields/issues/14 and other places, you'll see this massive push back from the community, yet the proposal is moving forward regardless.
- model_m_warrior 9y agoGotta get into the enterprise somehow. Even if that means bloating the language so its easier for the career desk jockeys to use (ie: dont ask them to learn something new).
- dmitriid 9y agoPushback from the community means nothing to TC39. Zilch. Zero. Nada. The only instance of something dropped was cancelable observables. AFAIR it was only because some other group at Google opposed it. Everything else is carried full steam ahead. Enjoy your import() instead of the vastly superior System.loader. Enjoy your hashes as member access specifiers. Dumpster fire. Template literals. BigInts. `new.target`. Dumpster fire. `import.meta`. Dumpster fire
- just_astounded 9y agoWhile it hasn't changed their minds, I do see the authors of the proposal actively discussing and engaging with the community. That's better than nothing, I suppose.
- gue5t 9y agoJavascript is a poorly-designed, committee-managed, machine-oriented intermediate language. Why should hackers care?
- rocky1138 9y agoThis is the primary reason I didn't like the idea of adding "classes" to JavaScript in the first place. Classical OOP doesn't really have a place here and all it does is invite the wrong type of thinking into the language.
- just_astounded 9y agoAgreed. We already had solutions for inheritance, etc... using prototypes, which are more powerful than classic OOP. Now we're in sort of a mess hybrid thing where issues like this are mostly unsolvable in a clean way.
- stupidcar 9y agoJS classes build on prototypal inheritance, they aren't an alternative mechanism. So you apparently either don't understand them, don't understand "classic OOP", or both.
- just_astounded 9y agoYeah, I've only been doing OOP for about 22 years, so I'm pretty new to it. The point was that the syntactic sugar isn't needed. The 'class' sugar actually obscures the power of prototypal inheritance, and imho, discourages people from learning it - to their, and the language's, detriment.
- camus2 9y ago> The point was that the syntactic sugar isn't needed. Yes it is. The success of CoffeeSCript is absolutely a validation that developers are more productive with syntactic sugar such as the class keyword, destructuring and many many other features. Now nobody forces you to use them. So why complain? It doesn't make Javascript harder to read for you, quite the contrary.
- just_astounded 9y ago
- model_m_warrior 9y agoI honestly do not see the need for these bloated features being added to Js just to appease programmers who refuse to learn a differing methodology.
- pavlov 9y agoA noteworthy feature of JavaScript is that it is predominantly a scripting language for large OOP-designed C++ systems. All the major browsers are C++ underneath, and so is Node. This has created an odd tension where the APIs that programmers use are implemented as OOP under the hood, yet JavaScript itself shied away from OOP concepts. With features like this, the JS standard is slowly creeping towards the style of programming that underlies the ecosystem.
- jorblumesea 9y agoTrue "Classes" in JS always seemed like a hack anyways. It will never be true OOP, so why shoehorn these concepts into it? Especially given prototypical inheritance patterns we will never have real java style oop patterns. Except for primitives, almost everything is an object, but they are basically hashmaps, not real classes or objects as someone from other languages might think of them. Imo, the language was not build or designed for some of these heavier OOP concepts. Just my opinion. This seems to fly in the face of many of the great things ES6 implemented.
- Andrex 9y agoYou don't need all aspects of OOP ever to get use out of some of its concepts. ES2015 classes are much cleaner and easier for newbies to grok than messing with the prototype chain, which was the way that sort of thing was achieved before. Classes also make a lot of sense for custom elements (Web Components.) See Polymer v1 compared to v2.
- jorblumesea 9y agoEs2015 classes are just syntactic sugar around prototypically inherited objects. I agree they are nicer to use but under the hood there's no change. Which is why adding all of these oop concepts seems contrary to how the language is designed. At the end of the day JS has no true classical classes. Not an expert just my opinion.
- Andrex 9y agoGood point! I do think that private properties is a worthwhile endeavor though, even if it's more of a "hard OOP" concept that on the surface conflicts with the historical ES spec.
- erikpukinskis 9y agoES2015 classes are not easier to learn for newbies, they're easier to learn for Rubyists and other people coming from OO languages. There's nothing hard about this: function Person(name) { this.name = name } Person.prototype.greet = function() { return "Hi, "+this.name } var me = new Person("Erik") console.log(me.greet()) The syntax hurts your brain if you're used to looking at something else, but the control flow is actually very simple and totally transparent, unlike ES6, which does magical things that can't be understood by thinking about where the thread is moving.
- agentultra 9y agoThe keywords were reserved in the latest spec for just this purpose. I don't think the rationale for their inclusion is a good one. The inclusion of such keywords in languages like C++, Java, etc was well-meaning but a mistake in retrospect. In the presence of global variables and direct assignment these keywords are the PHB approach to information hiding. They require ceremony and diligence to achieve true encapsulation. It's a murky situation at best. See Bob Martin https://www.youtube.com/watch?v=TMuno5RZNeE&t=2325 https://www.youtube.com/watch?v=TMuno5RZNeE&t=2325 and Bertrand Meyer on Eiffel: http://se.inf.ethz.ch/old/teaching/ss2007/0050/slides/03_softarch_info_hiding_lang_constr_3up.pdf http://se.inf.ethz.ch/old/teaching/ss2007/0050/slides/03_sof... (Bertrand Meyer coined the Open/Closed Principle and is the developer behind Eiffel). At this point though I see their inclusion in JS being almost inevitable. Just another feature to ignore. It'd be nicer if they would look to add syntax for higher-order operators like compose to the language instead of this.
- simplify 9y agoWhy are private properties so sorely needed? Ruby is an OOP language, and gets along just fine without it.
- dwb 9y agoYou can declare visibility in Ruby: https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classe... It can usually (always?) be gotten around though.
- simplify 9y agoRight. You can say something's "private", but there's always a way to access it. As far as I'm aware, this has never been an actual problem, and in fact has been useful since you can "patch" a library if you really need to.
- frou_dh 9y agoAdmittedly I have barely used Ruby, but isn't the fact that those "attr_reader"s have to be declared explicitly an indication that the fields are private by default?
- simplify 9y agoattr_reader :my_prop is just a shorthand way of creating a convenience method that returns the internal value of @my_prop. But in any case, there is always a way to access a Ruby object's internal instance values. See my other comment in this thread.
- pier25 9y agoPersonally I'm not against classes, if someone prefers to use classes instead of prototype it's fine by me. What I don't understand is why the TC39 is pushing for classes and classic OOP instead of other more pressing issues. You can accomplish OOP with prototypes. IMO the lack of type checking is much more problematic. Flow and TypeScript are just adding a new layer of problems to an already convoluted workflow.
- frou_dh 9y agoThere's a cute use of WeakMap to do private fields in a GC-friendly way let ages = new WeakMap() export class Person { constructor(name, age) { this.name = name ages.set(this, age) } // ages.get(this) }
- calafrax 9y agoI always wonder why if people need these features so badly they don't just program in Java or C++?
- pjmlp 9y agoBecause currently they aren't supported on the browser. But thanks to WebAssembly they will be eventually there again.
- rurban 9y agoI find it extremely amusing that the once clear JavaScript turns into ugly Perl, whilst Perl thrives to clear its ugly sigils and starts using ascii keywords for such properties. Design by committee rears its ugly heads