As someone coming up to speed with frameworks like React and Angular 2 it feels like that all over again.
As someone coming up to speed with frameworks like React and Angular 2 it feels like that all over again.
It is funny that after the Rails driven success web devs had moving away from J2EE they are falling right back into the same traps - ultra complex bloated frameworks built on a terrible language.
Even if you consider JS a bad language, proper abstractions can change the face of it entirely. By your logic, assembly is also bad since it is absurd to write anything useful in it. IMO Elm is a step in the right direction.
JS is kind of a 'bad language' because:
1) It's missing some pretty important things. Try to determine if a value is a number. Seriously. Look into that mess. Or anything else. Doing simple type-checking is crazy, and we basically are resigned to 'best practices' - which is crazy.
2) Prototype chaining is a neat idea and has some merits - but in reality it makes things super-duper complicated. Ask 10 JS devs how it works and get 21 answers. That is bad.
3) Almost nothing is built in. You need to use a lot of 3rd party libs to do common things.
4) There is no such thing as 'JS' - ever browser, every version - you get completely different implementations. Maybe we can't blame 'JS' - but pragmatically, this means JS is a problem.
A minor issue is issues with packaging, encapsulation and scale, which is also a function of loose typing. When JS programs get complex, they get unruly, and you wish you might be able to do things in an OO language at that point.
JS is really light, and that has advantages - and I think it's the best language for a lot of async things - and UI's are inherently async - so that's good.
In 5-8 years JS might be 'stabilized' in terms of libs or de-facto standards and it will grow.
To anyone who's programmed in other, more established languages, I think it's clear JS has some weirdness that doesn't need to be there.
But I like it.
ES6 doesn't fix any of it, typescript fixes some of it.
https://babeljs.io/repl/#?babili=false&evaluate=true&lineWra...
Compare step 1 of http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-nu... with http://www.ecma-international.org/ecma-262/6.0/#sec-number.i...
2) I felt the same way for a while, but recently I was working on something where I ended up really "abusing" the prototype system, and when you actually spend the time to learn it, it's not that bad! It's different, that's for sure, but it's not bad.
I like to think sometimes that if javascript came before C, would we still call many of these things "bad"? Would we call javascript's equality table "weird", or would it be C's that was the weird one? Would C be the star in a talk labeled 'Wat' where they laugh at the absurdity of 'a' == 97? So much of the stuff that people complain about in JS is because they have expectations from other languages. Sometimes those expectations are a good thing, but other times they are just different, and taking the time to actually learn how and why it's different can make you a much better programmer.
3) I genuinely like this about JS. There is no "one true way". The language is free to evolve, change, get new features, get new functionality, and easily "polyfill" old browsers outside of the release cycle. And that's important in JS because there is no one "authority". Keeping the stdlib small means that it's easier for new implementations to crop up, and it leaves the "niceties" to be developed by libraries. It's what allows libraries like ramada and lodash to be so powerful. They wouldn't be where they are today if the stdlib was more opinionated/complete.
4) But again I kind of like this. It does often make things more difficult, but at the same time it improves the ecosystem. I honestly believe that the fact that there are competing implementations is pretty much the only reason javascript (and in some ways, all dynamic languages) are as fast as they are today! Not only that but the fact that there are multiple competing implementations keeps most devs "honest". For the most part I don't need to worry about someone writing code that will run on version X on platform Y. I don't need to worry that the next "update" will require us to spend a week cleaning up removed functionality. It does lead to a lot of "crap" accumulating in the language, but over time that crap can and will be removed. JS is a fluid, constantly-evolving language, and because of that you tend target a point in time, not a "release", and the impressively awesome backwards compatibility means that while your older code might look outdated, it's not going to suddenly stop working.
I do agree that complex JS programs need much more tooling to be manageable, but it's working out very well in my experience. It's just different.
You just proved my point!
A) Even if you are correct - it's terrible. This is completely ridiculous that there's no basic check for extremely common and mundane type-checking. Moreover, it's the same issue for other types!
B) Worse: you're wrong.
isNaN('100') = false isFinite('100') = true
The string '100' would pass your check as a Number :)
Underscore uses:
"toString.call(number) === '[object ' + Number + ']';"
So noodle on that for a while: I'm assuming you're an experienced JS programmer and you can't test to see if something is a number! Embarrassed? It's ok. 9/10 JS programmers would get it wrong. I had to look it up! Which is my point - it's really bad!
2) Prototyping is not bad because it's prototyping - it's bad because it's really confusing. Point: nobody has - or will 'borrow' this idea form JS. Again - almost zero JS devs really understand how it works.
3) Again I disagree. There definitely should be a 'true way' for the most common operations. There should only be one 'true way' to test to see if something is a Number (!) - and for basic things like string operations - 'one true way' is better. For so, so many reasons.
4) "For the most part I don't need to worry about someone writing code that will run on version X on platform Y" - sure you do. You cannot use 'const' or 'let' in Safari/iOS. You can in Chrome. That's just the tip of the iceberg. There are dozens of such mismatches - and it's a fragmentation nightmare.
Now - I agree with your point about 'competing versions' hey, that's great. But they are 'not the same platform' - which is totally destructive.
2) There are aspects of prototypes that JS makes much worse (mainly the whole "this" clusterfuck), but the base is pretty sane and easy to understand. But at that point i'm not even talking about javascript any more, so I guess you are right here too.
3) I still disagree with you here. Yeah, there should be a way for the stdlib to do simple low level things (like isNumber()), but for others "one true way" isn't the best. I'd love a better stdlib, but I don't want something like Go's stdlib. I'd rather the language define a "bare minimum" and let libraries take over the rest. Now, as with anything in life this should be taken in moderation, if there are massive gains to be had by including something, then it probably should be included.
Maybe this is stockholm syndrome setting in, but I'd rather have the choice of implementation of something in-language, because there are so many different engine implementations.
4) I was more speaking of things like a python library that only runs on 2.7, or a java application that only works on 6. For the most part, those things just don't happen in javascript. Yeah, you need to not use newer features until they roll out everywhere, but once they do, you are safe in using them for a pretty damn long time. In your example, you can't use const/let right now because safari is the last big holdout here. iOS 10 was just released, and with it Safari 10. In another month, i'd feel comfortable using const/let without transpiling it, and I won't need to worry about it again.
But another benefit of multiple different implementations is they are free to optimize for different things. For example, Espruino is a JS engine that runs on microcontrollers and is EXTREMELY low power. Chakra (Edge's engine) shoots for really fast startup speed. V8 is pretty much the king in terms of raw execution speed. Contrast this with the Java way of having a million settings, knobs, options, and flags in the engine to tune the system the way you want. Yeah, you can do that, but most don't because of the complexity and risk involved. And there is only so much that you can do while having to support every option in the same engine.
Like i said earlier, i'm not sure if it's stockholm syndrome taking effect, but JS is by far my favorite language, and despite all it's flaws, issues, problems, and mistakes, it's also the language i'm most productive in. And with ES2015+ it's only getting better. (although i'm dreading the time when modules start getting into implementations, and how they conflict with current solutions, that's going to be a NIGHTMARE in just about every way).
Every language has that. There are different JVM's, different C/C++ compilers, different python interpreters.
JS is not 'at any advantage' here - and again - the drawback is the ridiculous fragmentation we see across browsers - which is ... bad - at least compared to other languages.
For all it's issues, JS has mostly moved past that. It's pretty rare to see a javascript program or library (that's not just a tech demo) that only works on one implementation. Hell Microsoft released a node.js fork that runs on chakra, and to my surprise every single one of our node applications runs on it without a single change or hitch. (i haven't looked up if this is "normal" or if i got lucky though, so take it with a grain of salt).
Now obviously it's not perfect, and we should strive to be better, to fix these issues, but it's not like javascript is in some unprecedented scenario here. I actually think that the IE6 days have pushed JS to fix a lot of the problems that are plaguing other languages in this area.
(!isNaN('100') && isFinite('100'))
Negation (!) before isNaN()
(!isNaN('100') && isFinite('100')) === true
My check would treat '100' as a number, so if i did something like this it would break unexpectedly:
var num = '100'
if ((!isNaN(num) && isFinite(num)) === true) {
console.log(num + 10)
}
You'll get "10010" printed to the console.There's no way on earth we'd be arguing about such a ridiculously trivial thing for most other languages.
Nobody should have to look any of this up.
Yeah, we work around it ... but it drives me crazy. :)
Source: Did some Java EE consulting here and there.
Learning by rote is stressful since your mind has to retain effectively a bag of (to it incomprehensible) technical trivia. In contrast, first principles are compact and generative, and such a grasp also informs your intuition so you can actually make educated guesses and jump in the deep end when picking up a new stack. Same principles apply to learning programming languages.
The biggest headache in picking new stacks today is the current trend of technical neologisms, so a bit of initial squinting (for recognition) is required.