TL;DR: JS with a ton of make up and tooling to not write JS is not as horrible as it used to be.
Well. That doesn't make it awesome either.
You just traded some problems for others.
Like the damn source map never working correctly, the build time being longer and longer, and the never ending list of plugins you expend every day after stumbling on yet another small-minuscule-not-that-important-I-swear detail.
The tool chain you spend more and more time on, despite all the "5-minutes" bundles provided by facebook or on githubs.
Explaining things to new comers has never been as difficult as it is now. Teaching is a pain.
Choosing your stack is a dangerous bet, and the odds and steaks are changing all the time.
If you opt-in for a flux architecture, you will soon write Java-as-in-the-90 on the frontend instead of Javascript, with so many adapters and design patterns as layers you will become angry.
If you don't (you-totally-don't-need-redux-to-use-react-guys) then most documentations and tutorials will not answer your questions, and you are own your own solving every single problems. Even the simplest ones, like redirecting on a route after data changes and closing a panel at the same time.
"Libs, not framework" means you need to relearn everything, rewrite a lot of code, tests and doc and renew maintenance for each new project. Meanwhile nobody agree on what a the proper stack is.
JS, despite all the paint on the rust, still has the old gotchas. This is still weird. ";" is still auto inserted. "==" still compares like nothing else. Errors come in different so many different forms it's not funny. Basic maths assumptions like commutativity are out of scope. Still no namespaces, but instead we use monstrosity like webpack and incompatible import systems to encapsulate things. Stdlib still doesn't have essential things like hashing, string/date formatting or encoding. Even basic operation like removing an element from an array using an index is a pain.
No, I'm sorry, JS has not become awesome. We just arrived to a point were we accepted we have everything to built with it and agree to pay the huge price for it. That's all.
Projects like vue.js makes me think there is still hope we end up with elegant tools from people who care. But right now I just embrace the madness and make money with it: all those poor customers don't realize the trap the current mindset lead them to, and I have so many solutions to the problem they should never have had to sell them.
>No, I'm sorry, JS has not become awesome. We just arrived to a point were we accepted we have everything to built with it and agree to pay the huge price for it. That's all.
Yep, this is the crux. ES6+ has finally made JavaScript look more or less like the languages we were using in the mid-90s, so I appreciate that, but it's not like it's some glorious boon to the developer community.
Any gains from the new semi-tolerable semantics are quickly overwhelmed by requiring layer-upon-layer-upon-layer of crap, including hundreds of dangerous random modules from GitHub to compensate for the virtually non-existent standard library and a "build pipeline" that consists of several unrelated runners, bundlers, transpilers and transformers to make code that's actually usable in real environments.
JavaScript is a tragedy for the development community from start to finish, and its increasing prominence should disabuse us of the notion that development is dictated by meritocracy or any such fantastical nonsense like that. Marketing and groupthink have just as much pull here as anywhere else (if not more because so many of us egotistically believe we are immune to it).
Everyone complains about the build tools, but they simply haven't thought through the issues.
Let's say you were writing the web using Python. New browsers run v3.x, but old ones run 2.x or even 1.x. Further, features in newer versions of v3.x won't work on older versions of v3.x. New browsers could include all three runtimes, but old ones would be SOL.
How do you use v3 features and target v2 or v1? You must transpile knowing that newer browsers also have v2 and v1 engines included too.
You have hundreds of Python files in your system. Delivering hundreds of files is simply not practical on HTTP/2. You combine them and now you have webpack.
What about libraries? As big as the standard lib is for Python, it doesn't do everything. You use pip or conda and now have npm/yarn.
What about code consistency? The solution is pylint.
What about testing? Add that to your chain as well.
It's the unique issues of the web -- NOT Javascript -- that makes the build pipeline what it is. Until a few short years ago, these things weren't even possible. Today, if you know node/npm, webpack, babel, and eslint, you know the overwhelming majority of build processes.
I'd finally add that make, Jenkins, etc are far more complicated to learn than the JS systems.
The original crappy design is definitly a problem with JS: the typing/testing, the lack of namespace import, the emptyness of the stdlib. Half of the problems we have today are directly correlated with this.
Most of our tools are not here to make things better, but to avoid sucking too much.
So yes, forward compat is an issue. But that's hardly the one I'm complaining about. I'm really ok with not being able to use spread, but I can live with it. I'm not ok with having to use npm + webpack to download, install, isolate and bunddle a remote lib to do a leftpad.
I'd say you have one. If you had one before, you didn't know what really happened when you went `var that = this;` and aired your opinion about how `this` is being stupid. So you got the arrow function, where `this` acts the way you expected before, when you said it was stupid. You can't complain about both.
The scoping of `this` has never really been too hard to understand. I learned it my first week doing JS.
Agreed, I stopped recommending React to beginners. I still love it and think it's the future, but in the sense that it's the new low-level. Eventually I think it will be standard to compile futuristic, high level, built-for-apps languages into React code. But for now, makes sense to just use a batteries-included framework. I don't know what the most sure shot is there though. Ember? Vue?
Mithril. Much simpler than anything else and batteries included. It's a great way to get beginners into front-end frameworks and gain knowledge that transfers easily.
Mithril is nice. W.r.t. going for batteries included, it's still a bit minimal for my taste. Personally I would lean towards something more dogmatic, in the spirit of Rails. For example, things that I would miss from Ember: ember-data, models (with relations), controllers, opinions, integrated tooling, etc ... But Mithril looks cool I've been meaning to play with it too. You're right that skills gained from learning Mithril will be more widely applicable to general front-end dev than Ember.
Rails is great, but where it really shines is server side apps, content sites, blogs, CMSs, etc .. If you know you're building purely a SPA, Rails isn't really the right tool for that.
I'd argue that more than half pure SPAs do not need to be SPAs, and can be written effectively in Rails with someone who knows it well, in less time, with less bugs, and more test coverage.
If you insert the semicolons yourself and don't depend on the auto insertions, you don't have to worry about the edge cases where the lack of a semicolon would introduce a bug.
"==" still compares like nothing else.
Use === if you want to be explicit.
Errors come in different so many different forms it's not funny.
I agree, but this is only a problem with new API's like service workers, what where they (TC39) thinking when introducing unspecified errors !? That can't even be detected !! There's already a convention to use err.code to specify type of error, use that please!
Basic maths assumptions like commutativity are out of scope.
The commutativity is the same like in classic Maths I think, it's just he floating point errors that mess things up.
Still no namespaces, but instead we use monstrosity like webpack and incompatible import systems to encapsulate things.
The module system (require) in Node.JS comes from user-land, and can be implemented in pure JavaScript, so you can use it in the browser too!
Stdlib still doesn't have essential things like hashing, string/date formatting or encoding.
We have .toString, parseInt, atob, btoa, etc. The rest can be implemented in user-land: var md5 = require("md5")
Even basic operation like removing an element from an array using an index is a pain.
I think it's fine. If you use a named list {} you can "delete foo[bar]"
Besides, JS is the only language I know where half of it is recommended to not be used.
> If you insert the semicolons yourself and don't depend on the auto insertions, you don't have to worry about the edge cases where the lack of a semicolon would introduce a bug.
But that's not the point. The point is my students will forget the semicolon in some code that is not properly checked, and it will work. Most of the time. Until it doesn't.
> Use === if you want to be explicit.
No shit sherlock ? But again, half of the language is forbidden. And you know somebody is going to write != instead of !== one day, tired.
> The commutativity is the same like in classic Maths I think, it's just he floating point errors that mess things up.
Nope. Nope. Nope. Nope.
$ node
> [] + {}
'[object Object]'
> {} + []
0
> We have .toString, parseInt, atob, btoa, etc.
Come on, you never used Java, Perl, Ruby, Python? Any language with decent string formatting ? That doesn't need a leftpad dependancy ? That can format date without importing 34ko of moment.js ?
> The rest can be implemented in user-land: var md5 = require("md5")
And then you get the current 3Mo pages we all hate. Are you even serious with your arguments or is it trolling ?
> I think it's fine. If you use a named list {} you can "delete foo[bar]"
A mapping is not a list. It doesn't perform the same. You can't push and unshift. You can map on it without Object.stuff. Length is a costly operation. Concat without spread is a pain. And how do you get the "next 3 elements after the 2nd" ?
> JS is the only language I know where half of it is recommended to not be used.
Jamie Zawinski (who else) about C++ in 'Coders At Work': When you’re programming C++ no one can ever agree on which ten percent of the language is safe to use.
> And how do you get the "next 3 elements after the 2nd" ?
.splice(2, 3) (am I missing something?)
> > The rest can be implemented in user-land: var md5 = require("md5")
And then you get the current 3Mo pages we all hate. Are you even serious with your arguments or is it trolling ?
md5 node lib is 32kb unbundled. If you meant 3Mb pages that's ridiculous. Modular necessity at the hands of the user is good, and it's something that's been present in every project i've worked on in a less granular fashion than modern npm-driven apps can deliver.
well, objects are not iterables... ??? unless you decide you want them to be, in which case you can make them such and design them in a way that they work as such?
The least elegant way is Object.keys().map(key => etc) which is really not that hard to work with
edit: it's a phony premise to begin with actually. Iterables have order, objects have mapping. I am less experienced with other languages so I probably don't understand OP's statement clearly. I just think OP's context is lazy thought rot about what's becoming a fairly elegant language. BUT I'm a noob.
> Besides, JS is the only language I know where half of it is recommended to not be used.
That's what you get for having backward compatibility I guess. If the standards committee would break my old code I would probably quit and start a sect. I would call it "ReactReduxReduce" (RRR).
> The point is my students will forget the semicolon in some code that is not properly checked, and it will work. Most of the time. Until it doesn't.
Some people prefer writing JavaScript without semicolons. How do they not have bugs all over the place ? :P
> Some people prefer writing JavaScript without semicolons. How do they not have bugs all over the place ?
The same way that people who write with semicolons avoid lots of bugs: linters and transpilers and tests.
That said there is only one rule to remember when not writing semicolons, the easy to remember "winky frown" rule: all frowns must wink if they start a line/statement. ;( ;[ ;`
Our projects' linting rules specify no semicolons, except when necessary; this means that we will _very rarely_ write something like this when we want to iterate over a small literal array:
;['foo', 'bar'].forEach(function (f) {
it(`has an ${f} field`, function () {
expect(......)
})
}
That said, we tend to use that construct extremely rarely, such as in a few test cases where we are doing the same kinds of things on two groups of items that need different descriptions.
It's amusing how my karma went up and down depending on whether the given person had understood the joke or not; eventually normalising at exactly 1. Nevertheless - I can't blame them as there is no way to tell the irony on the net.
Who I can blame is the original parent of this post who was quite confidently stating that omitting semicolons never causes any issues in his code (which is either a statement bounded by scale at which it works for him or it is not error-prone only in specific situations); and then just edited it so that it did not contain that specific line.
>Besides, JS is the only language I know where half of it is recommended to not be used.
Then you probably have never heard of the most successful (by the number of infrastructure written in it with amounts to almost everything in commercial OSes, network services, Google's search backend, most games, most commercial applications, databases, compilers, the JVM, all browsers, etc) -- C++. Where "half of it is recommended to not be used" also.
>No shit sherlock ? But again, half of the language is forbidden. And you know somebody is going to write != instead of !== one day, tired.
No shit, Einstein. That's why people use linters. In C you can corrupt memory with a stray ++ or alter flow with = instead of ==, fuck things with & instead of && and more. If we threw languages because they allow for errors, we'd have no language left.
>Come on, you never used Java, Perl, Ruby, Python? Any language with decent string formatting ? That doesn't need a leftpad dependancy ? That can format date without importing 34ko of moment.js ?
So? You've never heard of a language without "batteries included"?
>And then you get the current 3Mo pages we all hate. Are you even serious with your arguments or is it trolling ?
Are you? Before the problem was that there's no hashing support, now that hashing support is third party and makes pages bigger. As if a language should include everything in its standard library. I assure you most of the "3MB pages" is assets like images, not JS.
C++ also gets a lot of hate for half of it being forbidden to use.
"If we threw languages because they allow for errors, we'd have no language left."
Correction: we'd have Ada, some of those "prove your program is formally correct" metalanguages, and possibly Rust. Probably some others with which I'm not familiar.
It's a cargo cult/myth that was circulating from back when I was in university that Ada is some super fault tolerant language because they use it for rockets and stuff and because they designed it to be super secure.
It was indeed designed to be more secure than C and to be an official government/military use language, but no "super secure" and allows for errors just fine.
Besides, they do rockets in C just as well (with certain rules).
Although the source of the Operand Error has been
identified, this in itself did not cause the mission to
fail. The specification of the exception-handling
mechanism also contributed to the failure. In the event
of any kind of exception, the system specification
stated that: the failure should be indicated on the
databus, the failure context should be stored in an
EEPROM memory (which was recovered and read out for
Ariane 501), and finally, the SRI processor should be
shut down.
In any case, I'd argue that converting a 64-bit float into a 16-bit integer is a much different class of problem from mixing up assignment and comparison operators. But yes, you're right, even Ada is not perfect.
"Besides, they do rockets in C just as well (with certain rules)."
Yes, they do. Those "certain rules" are codified in the MISRA C standard (or derivatives thereof, like with the JPL and JSF coding standards). Said standard is way more strict than the sort of thing normally implied by "C programming".
>In any case, I'd argue that converting a 64-bit float into a 16-bit integer is a much different class of problem from mixing up assignment and comparison operators.
Is it though? Because in the end it's the same issue of conversion between types (coercion vs casting, but still).
A linter solves 100% of the "issues" you describe related to ASI and type coercion. Every single major editor or IDE has support.
> [] + {} '[object Object]' > {} + [] 0
The first case deals with an array, an object, and a concat operator. The second case deals with an empty code block, an array, and a unary math operator. None of that has anything to do with commutative properties because neither unary operators nor string concatenation are commutative in ANY language.
> Come on, you never used Java, Perl, Ruby, Python? Any language with decent string formatting ? That doesn't need a leftpad dependancy ? That can format date without importing 34ko of moment.js ?
The standard date object sucks, but that's no huge wonder because they were required to make it behave like Java (it even has an old Java Y2K API bug where it returns only the last two year digits).
We used to have horrible proceedural, class-based math libraries. Next we moved to underscore. That was replaced with a much faster lazy libraries. The current trend is toward even faster transducer-based solutions with more functional options as well. Which would be the correct language standard?
Having been bitten by bad APIs in the past, there's been reluctance to move too quickly in adding extra APIs to the core language. I think the current solution of adding good primitives and leaving the rest to good libraries is an ideal solution (after all, JS can add things, but old mistakes are forever).
> And then you get the current 3Mo pages we all hate.
We had a multi-MB page. Tree shaking got rid of most of it. Moving the biggest libraries to shared CDN versions that lots of sites use gets rid of a lot of load time as well. Using webpack to chunk your site also reduces the payload to a manageable size.
> A mapping is not a list. It doesn't perform the same. You can't push and unshift. You can map on it without Object.stuff. Length is a costly operation. Concat without spread is a pain. And how do you get the "next 3 elements after the 2nd" ?
A sparse list uses a map (in fact, Array is defined as a special case of a standard Object -- JITs simply optimize to more efficient data structures when your data allows). Further, if you start deleting in the middle of a list, it will not be optimized past a linked-list anyway (in ANY language).
If I were needing to do a bunch of item removal, I'd use this.
var removeNth=(x,s)=>x.splice(s,1); //a bit faster
var removeNth=(x,s,e=s+1)=>x.splice(s,e-s); //a bit more flexible
Array.prototype.removeNth=function(s,e=s+1){this.splice(s,e-s)} //a bad idea, but possible
> If you insert the semicolons yourself and don't depend on the auto insertions, you don't have to worry about the edge cases where the lack of a semicolon would introduce a bug.
I think this is not correct. It will still insert a semicolon where you don't want one. It's not like there's a compiler flag to turn insertion off.
I just tried to get the linter (JShint) to break some valid code, but it didn't. So you can actually rely on the linter to insert the semicolons for you. It would be interesting to find out if there are any cases where the linter will insert the semicolon in the wrong place.
No. If it's missing it's inserted obviously. That's why you shouldn't omit it.
Here are the rules for parsing if you're interested
When the program contains a token that is not allowed by the formal grammar, then a semicolon is inserted if (a) there is a line break at that point, or (b) the unexpected token was a closing brace.
When the end of a file is reached, if the program cannot be parsed otherwise, then a semicolon is inserted.
When a "restricted production" is encountered and contains a line terminator in a place where the grammar contains the annotation "[no LineTerminator here]", then a semicolon is inserted.
> If you opt-in for a flux architecture, you will
> soon write Java-as-in-the-90 on the frontend
> instead of Javascript, with so many adapters
> and design patterns as layers you will become angry.
That's not necessary. It depends where you're working.
I agree that teaching the complete stack is a pain. I guess there is `create-react-app` to help you there, but its scope is very small: you're not going to get static typing for example.
Well, if you want routing, you need a provider, and if you want to pass your store to a component, you need a container, and if you want to react to store change, you need a reducer, and if you want to make async action with your store...
There is an "-er" somewhere at every step.
You pass callbacks here and props there, and then reference them the other way around. And then you plug stuff in your componentWillReceiveProps, or is it in compomentWillMount or componentDefinitlyDidMountISwear ? But wait this is a new style class, so you have to call super(props) in constructor insteat of getInitialState unless you have a super Esx plugin but then remember that your onClick callback need to rebind this otherwise you'll get 'attributeOnThis' is undefined somewhere in your bundle and you'll have a fun time.
When you come from flask, Django or Ror, having to deal with such API feels like going back to before the 2000 bubbles, where corporates tried to port their knowledge to the Web.
I'm sorry but a `reducer` isn't a 90s-era Java concept at all [0], and you don't actually need to use any of those other things. This is beyond ridiculous.
You write syntactic sugar <div className="foo">abc</div> to turn into React.createElement('div', {className:'foo'}, 'abc') which generates an object {...stuff, tag: 'div', attrs: {className: 'foo'}, children: 'abc'}. Your final object is then compared to the previous object and any differences are manually written to the DOM in an efficient order.
My biggest problem is "the complete stack." Which one? How many months will it be the blessed way of doing things?
As soon as I get some work outsourced, here it comes yet another build system and yet another complete stack I have to get expert at.
Javascript lacks a standard library (a mistake from the beginning) as well as standard tools (can't blame Netscape for this, but today we could totally come up with something more definitive.
If JavaScript had a standard library from the beginning we would be replacing it now because it wouldn't support Unicode or promises or async or whatever is coming next.
The w3c cannot break the web. Once something is in the language a certain way, it stays (technically, there have been a couple small breaking changes, but the fact that you don't hear about them speaks to their size and impact)
We don't have precognition. It is not safe to pick a brand new framework for an important project right away, we have to wait a bit first to make sure it is being maintained well.
Note that that has nothing to do with math. It has to do with braces being used for both blocks and object literals.
Of course, I'm not too happy about the automatic coercion of everything and anything to either strings or numbers, but if you want consistency, try parentheses, or a + [], where a = {}.
plain old javascript is perfectly fine. es6 is better. if you can't write good apps with js it is because you aren't a good programmer and you wouldn't be able to write good apps in any language.
Well. That doesn't make it awesome either.
You just traded some problems for others.
Like the damn source map never working correctly, the build time being longer and longer, and the never ending list of plugins you expend every day after stumbling on yet another small-minuscule-not-that-important-I-swear detail.
The tool chain you spend more and more time on, despite all the "5-minutes" bundles provided by facebook or on githubs.
Explaining things to new comers has never been as difficult as it is now. Teaching is a pain.
Choosing your stack is a dangerous bet, and the odds and steaks are changing all the time.
If you opt-in for a flux architecture, you will soon write Java-as-in-the-90 on the frontend instead of Javascript, with so many adapters and design patterns as layers you will become angry.
If you don't (you-totally-don't-need-redux-to-use-react-guys) then most documentations and tutorials will not answer your questions, and you are own your own solving every single problems. Even the simplest ones, like redirecting on a route after data changes and closing a panel at the same time.
"Libs, not framework" means you need to relearn everything, rewrite a lot of code, tests and doc and renew maintenance for each new project. Meanwhile nobody agree on what a the proper stack is.
JS, despite all the paint on the rust, still has the old gotchas. This is still weird. ";" is still auto inserted. "==" still compares like nothing else. Errors come in different so many different forms it's not funny. Basic maths assumptions like commutativity are out of scope. Still no namespaces, but instead we use monstrosity like webpack and incompatible import systems to encapsulate things. Stdlib still doesn't have essential things like hashing, string/date formatting or encoding. Even basic operation like removing an element from an array using an index is a pain.
No, I'm sorry, JS has not become awesome. We just arrived to a point were we accepted we have everything to built with it and agree to pay the huge price for it. That's all.
Projects like vue.js makes me think there is still hope we end up with elegant tools from people who care. But right now I just embrace the madness and make money with it: all those poor customers don't realize the trap the current mindset lead them to, and I have so many solutions to the problem they should never have had to sell them.