How it feels to learn JavaScript in 2016

# J Decker (7 years ago)
# Jordan Harband (7 years ago)

aka "how it feels to learn"?

A decent response: medium.com/front-end-hacking/how

# kai zhu (7 years ago)

tc39 is partly to blame for promoting the perception of javascript language instability, which promotes tooling instability.

generators, es modules, destructing, let, fat arrows have caused tremendous harm to tooling stability, which has made frontend-development hell for everyone.

# Mark (7 years ago)

kai, what do you think would've been a better alternative? (Honestly curious)

# James Kyle (7 years ago)

generators, es modules, destructing, let, fat arrows have caused tremendous

harm to tooling stability

The exact opposite is true. Features like ES modules have helped stabilize the ecosystem in many ways even if we're still figuring out interoperability.

# kai zhu (7 years ago)

tc39 should have staggered the release of so many high-impact changes over es6/es7/es8/etc.

es6 is essentially javascript++, like c/c++. you can't expect senior c programmers to trivially transition projects to c++, or for existing c toolings to automatically extend to c++.

# Naveen Chawla (7 years ago)

kai zhu, why are you transitioning projects at all? As mentioned in a previous discussion, I recommend transitioning as you encounter code to be worked on, no need to transition in one go. Otherwise, just leave working projects as they are! After all, TC39 has a mission to "not break the web"!

# Bob Myers (7 years ago)

If you don't like those features or the associated tooling, then don't use them. Meanwhile, other people will be using them to build reliable, well-engineered, large-scale, performant applications. Bob

# kai zhu (7 years ago)

in frontend-development, the majority of use-cases are for small/medium-scale applications, where es6 toolings are inappropriate due to their complexity.

"reliable, well-engineered, large-scale, performant applications" are a niche application of javascript. tc39 should focus on making lives of everyday javascript programmers easier (who mainly want simple and stable tooling for simple/moderate webapps), instead of catering to niche people wanting google/facebook-scale apps.

# Naveen Chawla (7 years ago)

kai zhu, it sounds like you have a bad manager who is over eagerly pushing for a disruptive transition in a well established ES5 project to new features. The way to gracefully introduce the new features is incrementally in new code, not existing code, or when modifying existing code. If your manager is pushing to translate the whole code base and you are finding that a waste of time, then that is not the fault of TC39 or the language; that is the fault of the manager.

The features themselves are superior, more powerful and easier to use than the former ES5, so "everyday javascript programmers" will have a better time whether they are writing tiny or massive apps.

Yes, new apps should use those features immediately, and the developers will experience the benefits, sometimes very significant

# Florian Bösch (7 years ago)

I use a simple build script/requirement/module system I wrote myself in a few dozen lines that does things the way I like it. I find the permanent churn of pointless new flavors of the same thing annoying and distracting, whatever happened to writing code and be done with it, programming isn't spending time tweaking your super hip setup so long by the time you're done something new is now the new hotness.

# Frederick Stark (7 years ago)

Best response I've seen: medium.freecodecamp.org/javascript-fatigue-fatigue-66ffb619f6ce

I'd just like to thank TC39 for not breaking compatibility. All the niche old libraries I use that were written in ES5 still work in my ES6+ projects with no issues.

The ability to take it or leave it when it comes to new features makes the changes easy as pie

# kai zhu (7 years ago)

naveen, how are es modules or generators superior in getting a frontend product shipped? "powerful" does not equate superior.

success in shipping a product correlates highly to having maintainable code (with consistent styguide) that's easy to debug. generators are a nightmare to debug (compared to callbacks and promises) when doing integration and qa. es modules have confusing async-magic that few frontend devs really understand, and results in brittle module-loading code nobody wants to touch and risk breaking after its written.

the es6+ projects i've worked on all have significant amounts of brittleness which leads to them being difficult-to-ship as features could not be added or modified without fear of code-changes breaking something. 2016 and 2017 have been rough years for anyone trying to get es6+ products shipped. and i suspect it will remain the same for 2018.

if you're a product manager and your priority is to ship a frontend product, then your safest bet is to avoid es6 altogether.

# Naveen Chawla (7 years ago)

I like ditching the intricacies of function prototypes and using classes. Intricacy leads to less maintainability because there is a greater surface area for mistakes and bugs. Arrow functions make this even better because you can reliably move code that uses this into and out of them without having to create any self = this references. And then await async - logical algorithms in async world are more straightforward to implement and read. This, again, feeds into maintainability. The foundations of these abstractions are rock solid and their usage is straightforward - there isn't a loss, only gain, for using them.

But, if you prefer ES5 (I don't) then just use it

# Alexander Jones (7 years ago)

This appears to be borderline trolling.

I can assert with confidence that ES6+ is bringing clear wins in maintainability and developer efficiency. If your colleagues are writing ‘brittle’ code in ES6 I’d argue it’d be worse in ES5 on average.

(Also a mailing list is a great way to get FUD into a discussion without fear of downvotes. Who knew?)

— The Silent Majority

# T.J. Crowder (7 years ago)

On Sun, Oct 29, 2017 at 9:57 AM, Alexander Jones <alex at weej.com> wrote:

This appears to be borderline trolling.

Sadly, I have to agree with that.

I can assert with confidence that ES6+ is bringing clear wins in maintainability and developer efficiency. If your colleagues are writing ‘brittle’ code in ES6 I’d argue it’d be worse in ES5 on average.

And with that.

Kai Zhu, I think the problem is you see JavaScript has a scripting language for web pages. It is not. It is a fully-fledged language for writing full-stack applications, desktop applications, embedded applications, tools, and more. It is evolving and will continue to evolve. TC39 ensures -- and it's NOT easy -- that it remains backward-compatible. So as many, many have said: If you don't like the new stuff, don't use the new stuff. If others are using the new stuff and you're unhappy with that, I suggest you take it up with them, not this list.

Separately: I find your repeated claim to be speaking for people other than yourself to be...not useful. You can have your opinion. Claiming it's more than that, however, weakens rather than strengthening your argument. (In my opinion.)

-- T.J. Crowder

# Wes Garland (7 years ago)

On 27 October 2017 at 01:48, kai zhu <kaizhu256 at gmail.com> wrote:

es6 is essentially javascript++, like c/c++. you can't expect senior c programmers to trivially transition projects to c++, or for existing c toolings to automatically extend to c++.

Really? I was in that particular boat at one point in my career. I typed extern "C" { ............ } a lot. No big deal.

Similarly, as a JS developer, both front and back end, I have figured out how to transition my projects from ES5 to ES6 in the most efficient way possible: I have done absolutely nothing, and they continue to work perfectly. In fact, I have ES3 code still running in the wild.....

# kai zhu (7 years ago)

On 10/28/17, Frederick Stark <coagmano at gmail.com> wrote:

I'd just like to thank TC39 for not breaking compatibility. All the niche old libraries I use that were written in ES5 still work in my ES6+ projects with no issues.

introducing the new typeof Symbol() === 'symbol' does break backwards compatibility with many es5 libraries that default to 'object' type if typeof is not 'boolean', 'number', 'string', 'function', or 'undefined'.

fortunately symbols are not used by everyday programmers (and rightly so), so its rarely encountered by these libraries. if tc39 did really care about backwards-compat, they should've treated it as an 'object' type with a Symbol.isSymbol subtype-check like Array.isArray.

this brings up another backwards-compat issue - what's the typeof for proposed BigInt / Int64 / Decimal? i prefer treating them as 'number' or 'object' with subtype-checks BigInt.isBigInt et al., but Symbol has dangerously broken that precedent. in general my opinion is tc39 should freeze the existing set of typeofs (and use subtype-checks) for sake of backwards-compat and library/tooling stability.

# Logan Smyth (7 years ago)

Kai, that's not what backward-compatibility means though. It doesn't mean that new code automatically works with older code, it means existing code doesn't break when used alongside other existing code. Yes, adding new features to the language means that assumptions made by old code may not hold when used with new code. There is no way for existing code to break due to the introduction of a new typeof return value, unless there's actually new code introduced that uses symbols. There is no way in the world, in the general case, to introduce a change that will never invalidate assumptions that someone has made at some point in the history of an entire language. All TC39 can do is entire that new features are exposed in such a way that assumptions made won't break as they are currently used.

# Oriol _ (7 years ago)

It was kind of obvious that checking whether some value is an object by ensuring that it's not any of the existing primitives would stop working if a new primitive was added, which effectively happened with symbols. If some library used that, I think it is to blame. Instead, I would recommend something more simple and reliable like

function isObject(value) {
  return Object(value) === value;
}
function isObject(value) {
  return new function(){ return value } === value;
}
# kai zhu (7 years ago)

i disagree. you can write more maintainable and cleaner code with the premise typeof's will never change again (and give a one-time pass for symbols), instead of over-engineered paranoid code that it may change again in the future.

# T.J. Crowder (7 years ago)

On Sat, Nov 25, 2017 at 6:09 AM, kai zhu <kaizhu256 at gmail.com> wrote:

introducing the new typeof Symbol() === 'symbol' does break backwards compatibility with many es5 libraries that default to 'object' type if typeof is not 'boolean', 'number', 'string', 'function', or 'undefined'.

Which ones, specifically?

-- T.J. Crowder

# Claude Pache (7 years ago)

Le 25 nov. 2017 à 16:03, kai zhu <kaizhu256 at gmail.com> a écrit :

i disagree. you can write more maintainable and cleaner code with the premise typeof's will never change again (and give a one-time pass for symbols), instead of over-engineered paranoid code that it may change again in the future.

It is the responsibility of the programmer to write forward-compatible code, i.e., code that does not make assumptions that are likely to break in the future. For instance, one can reasonably think that the domain of the typeof operator may expand.

Naturally, the programmer should be smart enough in order to make the difference between paranoia and common sense: this is part of the art of programming.

# kai zhu (7 years ago)

claude, mature nodejs database drivers with frozen business logic for stability reasons are examples of libraries that you are asking to change whenever tc39 decides to expand typeof's on a whim which may break them.

the maintainers of sqlite3 for example have stated its in maintennance mode (mapbox/node-sqlite3#870), and all commits for the past 2 years have dealt exclusively with its build process so it can successfully compile with each nodejs release.

i write database code myself. what was my reaction to the introduction of the 'symbol' typeof? annoyance at trying to figure out what pathological use-case a user might want to pass a 'symbol' type to the database. i imagine mongodb / mysql / sqlite3 maintainers are equally annoyed with trying to figure that out. if tc39 had treated symbols as a regular 'object' type, then we wouldn't have that problem, and the current undefined behavior when its encountered in db drivers.

# Jordan Harband (7 years ago)

Except that they're not regular objects; and if they'd done that, there'd just be the same potential problems with code naively written to accept an object (since Symbols are primitives, they don't have persistent properties, for example).

Code that's written as if things will never change is brittle; "paranoid" code isn't over-engineered, it's simply engineered to handle change robustly.

# Alexander Jones (7 years ago)

They’re not even objects, let alone regular objects! :)

Making every new addition to the language be a subtype of object just creates a worse language. Given the constraints and requirements it was the right choice to make symbol a new primitive. Technically it “broke the web”, like literally every new change to the language. But that’s not as black and white as people make it out to be, by using such a catchy phrase.

typeof: officially subject to extensions.

Alex

# kai zhu (7 years ago)

neither is null really an object, which for all practical purpose is treated like a primitive, but the precedent was set to make it an object. symbol changed that precedent.

typeof: officially subject to extensions.

we agree to disagree. my opinion is introducing more types will only make things that were simple more complicated.

# Logan Smyth (7 years ago)

typeof null is "object" for entirely historical implementation reasons, not because things that don't fit the existing primitive list are automatically object. Adding a new typeof symbol doesn't change a precedent, because there was no such precedent. I understand that it's not what you want, but that doesn't make it the wrong choice for the language.

If Symbols had been made typeof "object", we'd have way more people on here complaining about the exact opposite expectation that code like this would work, where they assumed that object meant something that could have properties added to it.

function addState(obj) {
  if (typeof obj !== "object" || obj === null) throw new Error("State can
only be added to objects");
  Object.defineProperty(obj, "state", {value: ""});
}

for instance if it were "object" instead, this would pass the library's check and then throw because you can't define properties on a symbol, instead of the nice error that the library author intended.

Adding additional typeof results also allows developers to write code defensively. A dev could absolutely write

switch(typeof foo) {
  case "undefined":
  case "object":
  case "number":
  case "string":
  case "boolean":
    // handle normally
    break;
  default:
    throw new Error(`Unexpected value with ${typeof foo}`);
}

to enforce their assumptions about type, and give the user helpful feedback if new types are added in the future. If Symbol had been added as "object", there's is no way for developers to do this. Someone can guess "maybe a new typeof will be added", but they would be super unlikely to guess that a new object type would be added that didn't behave like any other thing with typeof `"object".

At the end of the day, a new data type is always going to break assumptions made somewhere, independent of whether there is a new typeof result or not, and if that's already the case, adding a new typeof is much more consistent with the types already in the language because Symbols do not behave like normal objects.

I can't tell from what you've said so far, is your complaint that a new typeof result was added, or is it that Symbols aren't actual objects? If the complaint is entirely about typeof then I feel like my above comments mostly make that clear, but if your issue is just that they should have conceptually been objects, then I don't feel like you've made it clear why that would be better than a new primitive (independent of typeof).