Hacker News new | ask | show | jobs
by tmikaeld 1105 days ago
Is he talking about the old < ES5 javascript or the new ES6+ with WebAPI standards?

Because to me, it's quite remarkable how JavaScript has evolved since < ES5. ES6+ introduced a slew of features like arrow functions, template literals, async/await, destructuring, classes, enhanced object literals and native modules. It's way more developer friendly when writing new stuff than it used to be.

Not to mention, the integration with Web APIs has been a game changer. Fetch API, WebSockets, Web Storage, WebRTC and Service Workers, WebAssembly really enables a lot of functionality that's all easy to use and very fast. TypeScript also helps with gradual typing together with syntax highlighting and lookups are superb for avoiding unexpected mutations and a lot easier re-factoring.

Also, what do he suggest would be the replacement? Because it's not enough to replace the scripting language, it would need to fit into the DOM, HTML and CSS too.

1 comments

> ES6+ introduced a slew of features like arrow functions, template literals, async/await, destructuring, classes, enhanced object literals and native modules.

This is the problem.

All of this has made the language worse. Just accreting features doesn't make the foundation less broken.

> All of this has made the language worse. Just accreting features doesn't make the foundation less broken.

I see this view a lot - what I rarely ever see is a concrete discussion about what exactly is wrong with the "foundation" of javascript.

Because to me... Javascript is actually a decent-ish solution to the UI space (it nicely balances reactivity and code complexity by presenting an event driven, single threaded context)

It has the same warts that literally every production language accumulates: some operators are overloaded in ways that make for wacky edge-cases, some features were introduced by not great, and so they still exist but mostly gather dust.

JS also has some really incredible work put into it -

---

> ES6+ introduced a slew of features like arrow functions, template literals, async/await, destructuring, classes, enhanced object literals and native modules.

This is the problem.

---

Frankly - I understand that increasing language complexity is sometimes not the right call - but I think the vast majority of the features you just poo-pooed are pretty damn nice. I don't even mind the classes - just because it makes Crockford and the other enterprise java folks shut up (otherwise - I sort of mind the classes, at least when not using TS).

What I do find particularly impressive is how flexible JS is, and how much support can be added without actually changing the runtime - that's not something all that many enterprise languages can attest to, and it's that same flexibility and simple extensivity that has allowed JS to continue to grow.

Following on: JS (and browsers in general) are actually one of the absolute wins for software freedom (free as in freedom, not as in beer) because absolutely everything is shipped to you in inspectable and modifiable payloads. I can and have edited JS/html/css to make broken sites work.

My single biggest complaint about WASM is that we lose this property for websites, and I think that's a pretty huge fucking loss.

> I don't even mind the classes - just because it makes Crockford and the other enterprise java folks shut up

This is the second time I've seen in this thread that people lump Crockford in with Java enterprise folks, but Crockford routinely says `class` was the worst addition to JS.

> What I do find particularly impressive is how flexible JS is, and how much support can be added without actually changing the runtime

Funny enough, this sounds a lot like something Crockford would say.

I think Crockford's main gripe with JS these days is that TC39 is more concerned with adding superfluous features than cleaning up footguns. There is a video from 2018 where he goes through some of the more popular ES6 features and mentioned which ones he likes/dislikes. [1]

[1] https://www.youtube.com/watch?v=XFTOG895C7c

> This is the second time I've seen in this thread that people lump Crockford in with Java enterprise folks, but Crockford routinely says `class` was the worst addition to JS.

Because Crockford was one of the people advocating for a particular style of initialization of objects that mirrored classes, but was not directly a class before classes existed in JS. (see: https://crockford.com/javascript/inheritance.html)

It is utterly enterprise and classlike in nature though, and not my cup of tea. Mainly - I just wanted enterprise folks to stop trying to re-invent classes in the language, and the class keyword stopped that behavior.

Big net win for the language in my opinion - even though I personally still don't use classes all that often.

---

His modern take is fairly reasonable, though.

His modern take, advocating prototypes, has been around since 2006 (https://crockford.com/javascript/prototypal.html).
I know - I just keep getting older... hard to believe that was nearly 20 years back now, and not 20 months.
I might not have the best take since don't have a huge grudge against javascript but I definitely think there are some concrete problems in its foundations.

Specifically js has very unusual attitudes to basic syntax operations that are at this stage undoable without breaking an insane amount of existing code. For some examples:

- Use of == does not do what it does in almost every other language, but won't flag an error if a user thinks if does. Instead very difficult to track bugs will be introduced.

- Calling nonexistent object keys won't flag an error but return None. I've seen this lead to weird errors that are hard to find a lot of times.

- Duck typing in a lot of operators like + and - can create unexpected results.

At a high level, I think these are all choices to bake "truthyiess" into fundamental operations that often end up masking errors. They could pretty easily be solved if js, with those errors present, wasn't such a massive foundation for so much stuff.

I obviously can't speak for anyone else, but I think those are the kind of things most people are referring to when they talk about js having problematic foundations.

But none of those are actual issues with shops that are writing JS today (Literally: Zero items on that list).

> Use of == does not do what it does in almost every other language, but won't flag an error if a user thinks if does. Instead very difficult to track bugs will be introduced.

"==" does basically what it should... (I also avoid it, but it makes a perverted kind of sense for easing into programming) and the bugs introduced aren't difficult to track at all: literally find and replace "==" with "===" resolve places that became too strict, then make it a lint rule.

>Calling nonexistent object keys won't flag an error but return None. I've seen this lead to weird errors that are hard to find a lot of times.

This... is basic dictionary behavior across SO MANY LANGUAGES. Frankly - having worked with languages that make a missing key an exception (looking at you C#/C++) I'd take the JS route any day.

> - Duck typing in a lot of operators like + and - can create unexpected results.

Yes. This is programming. Have you seen Ruby (or python - or god help you custom operator implementations in c++)? Because holy fuck is JS reasonable as all get here when compared to some other popular languages.

----

> I obviously can't speak for anyone else, but I think those are the kind of things most people are referring to when they talk about js having problematic foundations.

Basically - Look: I agree JS has some warts. Literally every language does. I just really don't see those warts as deserving of FUD around foundational problems that so many people talk about.

These are problems easily solved with tooling today. ESLint + TypeScript literally addresses every example you raised. Static analysis works pretty well these days.
I agree but I guess we differ in that I wouldn't consider Typescript JavaScript but instead a very closely coupled but different language.
>I see this view a lot - what I rarely ever see is a concrete discussion about what exactly is wrong with the "foundation" of javascript.

The things that were added mostly were to fix problems of JS:

arrow functions => because of "this" shenanigans

template literals => I'd say a basic part of a language

async/await => Promise/future hell

destructuring, classes, enhanced object literals => These are all syntactic sugar/nice to haves. Nothing really was broken here.

native modules => Another time I'd say that it's a basic part of a language

> All of this has made the language worse. Just accreting features doesn't make the foundation less broken.

Nope, most of these have made the language better. Optional chaining is better than a litany of `&&`, `...` is generally better than `Object.assign` or `concat`, `async/await` are generally better than callbacks... The list goes on. Rejecting these new features wouldn't have magically improved the foundation.

What exactly is "broken" about the foundation of JS? I hear this all the time and people can never back it up.

It is extremely performant for a scripting language, it is easy to debug, and it works in many scenarios.

People try too hard to be contrarian. Same thing happened with PHP and many other languages.

Have you ever read JavaScript: The Good Parts? It does a great job of describing lots of broken bits.

More specifically, a few things that I think are pretty bad off the top of my head:

- Implicit type coercion

- Confusing scope binding, i.e., `this`, `bind`, etc.

- Inconsistent Array API — some methods return a new value; some methods mutate the value![0]

- `['1', '7', '11'].map(parseInt)` …lol?!

Maybe you shouldn't be so quick to jump to this conclusion that any criticism of your pet technology comes from a place of ignorance or pretension.

[0]: I've actually spoken with Brendan Eich about this one, and he conceded it wasn't a good idea. IIRC, he was just copying what Perl did.

> Maybe you shouldn't be so quick to jump to this conclusion that any criticism of your pet technology comes from a place of ignorance or pretension.

Maybe your argument just isn't that great?

I mean - look, I've worked in a LOT of languages now in the 25 years I've been writing code. Js is certainly no bastion of language perfection, but it's also sure as fuck not on shaky foundations.

Almost all of your criticism basically boil down to: JS won't break backwards compatibility for me! WAHHHHH!

Because none of your examples are really issues:

- Implicit type coercion.

happens in a lot of languages - keep a table around if you need it.

- Confusing scope binding, i.e., `this`, `bind`, etc.

this is literally core to the language - it's not any more confusing than learning about the difference between class definition vs an object instance.

- Inconsistent Array API — some methods return a new value; some methods mutate the value![0].

This is a fair complaint - but all the functions that mutate have non-mutating versions now - JS just won't break compatibility for you by removing the old ones... "WAH!")

- `['1', '7', '11'].map(parseInt)` …lol?!

You know damn well what you're doing Mr radix. Variadic languages have some edge cases. If you don't like it, use Number like a sane person:

['1', '7', '11'].map(Number)

ParseInt is usually not what you want, but again... JS won't break compatibility for you - that doesn't mean the foundation is shaky...

It just means that some parts are older than others.

And on the seventh day He finished his work that he had done, and he rested on the seventh day from all his work that he had done.
How performant a scripting language ends up being is partly due to a couple of fundamental design choices, and partly just due to investment.

The fact JS has very limited interaction between threads makes a JIT much easier to write.

In terms of design there’s a lot of annoying things round equality, operators, and coercion which makes everything just that little bit harder to keep in your head. The standard library also has a bunch of inconsistencies in the way it works. I work on a JS implementation every day and I’m always referring to the spec to double check odd corner cases.

I think the choice of double as the only original numeric type has caused a lot of confusion too, even though I’m not in the camp that says you should never use floats.

> The fact JS has very limited interaction between threads makes a JIT much easier to write.

And easier for developers to write and reason about. This is not small thing. Re-entrant code by default (and basically by mandate) eliminated deadlocks in even a beginner's code. Do you understand how amazing a language is than encourages concurrency and allows parallelism with any fear of deadlocks or explicit atomism?

You can absolutely have concurrency bugs in async JavaScript code, don’t kid yourself that you can’t, or even that it’s hard to do.

The reason I mentioned the concurrency model making the JIT easier is that the concurrency model makes it easier to manage the replacement of methods on the stack when an assumption has been invalidated, and this helps with the speed of the compiled code. The same also applied to various languages with green threads or global locks, but outside the JS world being able to use multiple cores has proved more useful than the difference in single threaded code.

Never said you couldn't have concurrency bugs.

I specifically mentioned thread deadlocks and atomism. You cannot claim locks, so you cannot claim them out of order. JavaScript has no notion of "atomic integer increment" since all variable access is atomic/single threaded.

That is not the same as the straw man claim you asserted for me.

And I reiterate: no deadlocks or atomism concerns greatly aids developers in writing secure and robust code. It does not eliminate all bugs, concurrent or otherwise, nor did I ever claim it did.

If you can find a code example in browser-based JS that triggers a deadlock, I'd be fascinated to learn about it.

> Just accreting features doesn't make the foundation less broken.

That's indeed the gist of Douglas' remark.

But if you have not much experience beyond JS, that is very hard to recognize.

Douglas is grey and old. Most JS devs are on the younger side of the IT work force.