Best comparison: Python review
I've written at length about why dynamic typing is bad, and workarounds like TypeScript can at best mitigate the destruction.
Dynamic typing is a sin
But you can define one of the values to be `undefined` and it's now in there!
Even a function parameter just gets `undefined` if it's not passed. All arguments are optional; you *can't* define a function that requires you to pass it a parameter. Let that sink in for a minute.
You also don't get an error when passing too many arguments to a function.
And I found out the hard way that in browsers, `setTimeout` silently does nothing if you pass its arguments in the wrong order. That was how I lost most of a day of work.
Even indexing a non-array and non-object isn't an error:
Arrays are objects?
See what I mean? It's like you're just assigning keys in an object, and array indices don't have any special meaning (though they do print sensibly).
It's like the holy trinity of `undefined`!
This is because arrays have a `length` attribute that stores the number of elements they supposedly have. So when you assign to an index, it changes the length, and then when you look at the array all the slots inbetween that don't exist as keys in the array are presented as these "empty items". `delete` is meant for removing a key from an object, so when used on an array, it only deletes the key and doesn't collapse the others or modify the `length` attribute, so it just leaves an empty slot behind. What a terrible newb trap.
You also can't add arrays with `+`; the `.push` method is how you're supposed to add elements to the end, and `.concat` is for adding arrays. The main way to delete from an array is `.splice`, but there are a lot of others depending on the specifics:
For some reason, `.splice` is also how you insert elements. The one method is basically a swiss army knife instead of using different functions to accomplish different tasks.
This type coercion is outrageous
I don't oppose all type coercion. For example, I support coercing between different numeric types. But this? Not only it is through the roof, it's wildly inconsistent, unintuitable, and most of the ones involving arrays and objects are complete nonsense. An operation that doesn't involve numbers should never come out as `NaN`; that's not what `NaN` means.
In general, things that are almost certainly mistakes should raise exceptions, not silently return a nonsensical value.
`null` vs `undefined`
There are *two* primitive values that represent the lack of a value, and they're different:
1. For function parameters, passing `undefined` causes the parameter to get its default value. Passing `null` causes it to get `null`.
2. `undefined` doesn't come out in JSON; `null` comes out as `null`.
To be fair, there is some kind of logic here in retrospect: `undefined` is something unset; `null` more represents an intentionally lack of a value. But the distinction is still unnecessary and confusing.
Objects can't compare for equality
`==` on objects (including arrays) compares for identity, not equality. If you want to test whether two objects are equal, you have to iterate over their keys.
In a language that has `==` and `===`, you would think `==` would compare by value for objects, and `===` would compare identity. But no, in the one case where the distinction would be actually helpful instead of a nefarious newb trap, they do the same thing.
Object constructors for primitive types
Also, this isn't a likely thing to trip over, but it's just infuriating:
Because objects are always true.
Javascipt uses exceptions like other dynamic languages, but it's lacking over Python and Ruby in that it doesn't support catching only specific types of exceptions. `catch` always catches everything and you have to manually check and reraise if you only wanted to catch some kinds. And like the others, it catches name errors. Ugh.
Why do all the dynamic languages catch name errors by default?
It does give good stack traces, and has the finally statement.
Lack of syntactic support for arrays
Variable declarations are a mess
- `var` - creates a function-local variable. That's all it does.
- `let` - two differences from `var`. It's *block-scoped* instead of function-scoped, and it doesn't allow redeclaring the variable with `let` later.
- `const` - like `let`, but makes the variable immutable.
What an elegant and straightforward system!
Because arrays are technically objects and so their keys as given by `for`..`in` are of course the *string* indices. This works for some use cases, but if you try to add to the index counter, it'll break your code in bizarre ways.
No generator expressions or comprehensions, though.
I use them every day; they feel a lot nicer than the `function` keyword. And the syntax is intuitive, too; it *looks* like you're taking the parameter list and doing something with it. Python has lambdas and in-function `def`, but lambdas are limited to just a `return` statement and `def` doesn't handle scoping the same way arrow functions do.
this article on Pylint shows an example of the difference where you would want the arrow function behavior.
Node OS threads
Stdlib and ecosystem
The JS stdlib is missing a lot of standard fare. No titlecase. No randint. No strftime and strptime. No regex escape! The community made a package on NPM for it even though it's only a few lines, because people kept hand-rolling it and getting it wrong.
Oh, wait, there are at least three others.
I guess the community didn't actually succeed in standardizing. This is why I say language designers underrate putting things in the stdlib.
A problem that seems to plague the NPM ecosystem is overdependency. Everything has a huge amount of dependencies. You can barely install anything without populating your `node_modules` with at least a hundred directories.
A lot of the dependencies are nonsense packages, which provide a single function of often just *one* line (and not even ones that are tricky like the regex escape).
This article is a good read on the situation
Ecosystems of other languages don't have this problem. Even Django, the giant all-the-features Python web framework, has only *3* dependencies, including indirect.
subscribe via RSS