> Me: oh, cool, they fixed so many tiny things I had bumped up against
> Some others: oh no, why are things changing
I'm not getting it. Maybe I'm reading this wrong, but to me these seem pretty obvious small issues to smooth over. > Me: oh, cool, they fixed so many tiny things I had bumped up against
> Some others: oh no, why are things changing
I'm not getting it. Maybe I'm reading this wrong, but to me these seem pretty obvious small issues to smooth over.For example why introduce a new method to support negative indexing. Supporting `array[-1]` instead of `array.at(-1)` would mean one less thing to remember.
Many of the changes make the language feel like a hodge podge made from parts of other languages. This lack of cohesion is IMO what makes upgrading the language always feel like moved cheese.
For example, if you have a `binarySearch` function that returns -1 if an element isn't found, a developer might do something. `const result = arr[index]; if (result !== undefined) { ... }`. This would then start returning the last element instead of undefined at that index.
But what do I care, whatever mess and complexity arises from these "good enough" implementations is left for the generation after us to deal with :)
A lot of old code in other languages may be hard or impossible to compile and run without significant work.
Changing browsers to interpret `arr.get(-1)` as `arr[arr.length - 1]` doesn't affect any old code using `arr[-1]`.
It's not about supporting old browsers. It's about supporting old code.
Adding new syntax and functions to the language is not a breaking change. Old code will continue to work.
If you start using these new features in your application, and it no longer works on old browsers, then sure that's a breaking change. But that's a choice for you to make. The language is still backwards compatible.
There's a valid example of code that would be broken (`indexOf` returns `-1` as "not found"). Is it a good way of solving whatever the author was trying to do? Probably not, especially now that sets exist. Is it code you might conceivably find on hunreds of sites across the past decades of the world wide web? You bet.
Yes, we could introduce another "use strict". But we only just got rid of the one via ESM (which enforces strict mode). That was a one-off hacky solution to a hard problem coming off the end of a failed major version release of the language (look up ECMAScript 4 if you get a chance). We don't want to see a repeat of that.
Surely there should be a simple way to have a header in each file with the language version, and then the file will be interpreted as that version?
You may find [2] and [3] especially enlightening to understanding this thinking, and any other discussions from ES Discuss on the topic if you fell like digging into history.
[1] https://johnresig.com/blog/ecmascript-harmony/
You grab some code in one of your old projects for implementing a binary search. Can you copy-paste it into a new project that targets a newer language version?
The question isn't as simple as "does it have syntax errors", because we're talking about changing semantics here. Given a set of semantic changes and a piece of code, figuring out (either as a human or a computer) whether the observable characteristics of that code have changed is somewhere between vexing and impossible. It's entirely possible, for example, that your code encounters changed semantics, but not in a way that changes the actual behavior of the code.
In this world it just becomes very, very difficult to reason about extremely common operations; it'd be a constant source of frustration. There's a good reason you rarely see languages versioning their behavior in impactful ways.
This is nothing JS specific. Breaking changes are breaking changes. If you can, don't introduce them.
> simple way to have a header in each file with the language version
One special aspect that differentiates JS from other languages:
It's both a language AND a universal runtime. A lot of JS that's executed is not JS that's written by humans but generated by a compiler/transpiler.
So adding a layer of header versioning is not a big win in terms of developer experience: It would anyways be the deployment toolchain that's responsible to deal with such a versioning scheme. It would ideally be invisible to the developer.
You can add a polyfill to check if `Array.at()` exists, and if it doesn't, create a function that does the same thing and add it to the `Array` object, so now all `Array.at()` code works as expected.
Then once every environment you target supports `Array.at()` by default, you can remove the polyfill to reduce the size of your code.
if (array.at) {
explode();
}
Adding the at function would break the above code which depends on array.at being undefined.This is also why the language got Array.prorotype.flat instead of flatten (flatten was breaking an old version of a popular library called Mootools): https://developer.chrome.com/blog/smooshgate/
Before that point, browser environments were so different that you needed to write code per-browser. Those theoretical concerns didn't really matter since in-practice you were essentially coding the same app in different scripting languages.
Totally. It's just extending the prototype that causes the problem though, not extending from (class myclass extends array). This causes a lot of confusion among new js devs so I underline this on every opportunity.
It will live as long ad JS is popular. The main threat is web assembly which will make JS compatibility seem quaint.
In practice there seems to two different sides of typescript code.
1. Regular projects: tend to have rather easy to understand/write/maintain code.
2. Dependency code: tends to have code-golfed metaprogramming that the IDE uses to auto-magically autocomplete and highlight issues in regular project code.
The only consistently annoying thing about it is how dumb it plays with JavaScript's built in array methods but it still is sufficiently smart 80% of the time (and the other 15% a simple `as const` does the trick)
IMO it was entirely good enough for what it does quite a while ago. No need to add more—that's purely introducing risk (of the language's ecosystem getting worse, mainly) from my perspective.
The first comment I read after yours is literally "I hate how much programming languages change"
That, and for various reasons, it’s easy to use "import" everywhere in browser-side code, but painful to use "import" in Node. That’s a major selling point for ESBuild in my mind—I can avoid dealing with Node as much.