The fact that JavaScript and the web platform kind of sucks while at the same time being "unavoidable" is why it's so good.
It forced a lot of very smart people and a lot of eyes onto the platform to try and find solutions within the extremely restrictive "box" to these problems.
How do you solve the API issues when you don't control the platform?
How do you solve for perf when things can't be installed?
How do you solve the API when you can't force people to upgrade?
How do you solve the language when you only have one language as a compilation target?
Out of these we got React and other vdom style view layers.
FP paradigms got into the mainstream.
It exposed the mass to newer type system features
We got a toolchain that while complex, can do almost anything.
We got some test tooling that are ahead of other mainstream languages.
And every last bit of these went through tons of iterations (sure, javascript fatigue, whatever), and have had an immense amount of eyes on. You totally can look at any of the things I pointed out and say "Language X did it first!", but no one forced Language X on so many people, while JS was, so these things got a lot more exposure.
In short, I love the JS ecosystem precisely because it sucks so much.
These are why I dislike the javascript ecosystem. It's like a giant game of codegolf -- solving problems that shouldn't be solved overcoming constraints that shouldn't be imposed using creativity that ought to be spent on the big picture.
"Very smart people" are great at twisting and stretching and finding the most optimal possible solution within the restrictive box that you give them. But they're not always great at stepping back and asking bigger questions:
* Why was the box put there in the first place?
* Doesn't my solution defeat the point of the box?
* What are the alternatives to the box?
* Is it possible that I'm wasting tons of time and energy on a problem that would be trivial outside of the box?
The questions you ask are great, but slightly less important when you add the fact that everyone has the box already, and getting them to use a new box has been tried incessantly over the years, and yet here we are with the same old box.
Tl;dr -- pragmatism is why the web ecosystem is eating the world, not optimal design.
There are three players in the game right now all of whom can push updates to the vast majority of their user base very quickly. This isn't a problem like it was back in the day. Now it's pure stubbornness.
See also, Excel and VBA in corporate America. Will companies let employees install language environment X? Probably not, but they'll have access to Excel with VBA.
The more time goes by the more I feel crazy for missing whatever would motivate people to use js for anything more than is strictly necessary. Single threaded server??? I mean come on man, I understand you don't need parallelism for a lot of use cases but even if that fits your situation why javascript? It can't be that hard using a different language. I refuse to believe that.
My day gig is nodejs. I was interested in the problem space, didn't think too much about the stack. How bad could it be, right? Oops.
The worst aspect of nodejs is code construction (craftsmanship).
Whereas Bill Joy said of Java "Allows you to think both In The Big and In the Small, at the same time." With nodejs, not only is there no Right Way, there's not even a Good Way. You have to mind all the details, plus quite of a few new ones.
Frankly, I'd rather just write 'C' again. If I have to care about the fiddly bits, I'd rather the language not fight back.
My team spends a lot of time mitigating memory leaks and back pressure (bufferbloat due to thread/task starvation). I haven't done this kind of troubleshooting since my 'C' slinging days.
And this is apparently acceptable.
I find the current state of affairs (emperor has no clothes) appalling and baffling.
My take on this (I have had the same experience, fwiw) is that it is like the well-known story of bridges falling down due to experienced engineers retiring (Tay Bridge Disaster, Tacoma Narrows Bridge for example). A new generation of folks who actually believe that "Single Threaded is a benefit" arrive on the scene and make a bridge that falls down..
Single-threaded isn't a benefit, but in a world where multi-process isn't a problem, a lot of that is blunted. Granted, for problems that are both compute- and IO-heavy, something like the JVM makes much more sense (so just use it--duh, right?). For throwing bytes over a wire, something like Node is really, really easy and really, really effective. My biggest beef with it is the weak libraries for talking to RDBMSes, that's about it; my API tools of choice remain Ruby/Grape/Grape-Swagger because ROM is so much nicer than anything I've seen in Node, but that's really about it.
Like I said upthread, I used to dunk on JavaScript a lot, but it doesn't make sense nearly as much as it used to, to me.
Huh? Of course it has some benefits. Unfortunately everything is just trade-offs. A benefit of single-threadedness is that you don't deal with the certain pitfalls of multi-threadedness.
Seriously, use Erlang or Elixir and have both concurrency and ease of programming and debugging relative to Node.js. Spoken as someone who has created multiple Erlang projects with close to zero unintended downtime for months or years in production.
I like what I've seen of Elixir. (As a Rubyist by habit, I should.) But it doesn't do what Node does:
Use JavaScript.
We can say 'til we're blue in the face that that doesn't matter (and I do, as a Ruby/Grape guy for APIs), that matters. Lowered impedance mismatch is a thing. I use Ruby because I'm still more productive there--but that's a library problem (RDBMSes), not a language problem.
Node really is good-enough. I'd go for either a JVM or a BEAM-based solution if I was building things where there were significant and meaningful losses on the table if I fucked up, but for most things? Nah. Just...not important enough.
If you are dealing with a single-threaded, non-concurrent problem, yes, that's true. Node isn't that. In my experience, the pitfalls of multi-threadedness are more around concurrency than they are parallelism, so that tradeoff strikes me as largely a false one.
I'd say the exact opposite. Race-conditions in parallelism are where the classic problems lie.
We aren't going to agree here, but you sounded like you thought your position was axiomatic or something, and that's what I disagree with. Meanwhile I am content that we may have different preferences, that's not a problem.
The problem, in every case I can think of (and it intuitively seems true), is continuation, whether it's done in software with coroutines or in hardware with process scheduling/threads. Which is a concurrency problem rather than a parallelism problem, which then expands to "are problems of linearizability concurrency or parallelism?". Which might be a more settled way to answer the question in a CS manner.
Can you describe a race condition that cannot be replicated on a single thread with either preemptive or cooperative multitasking/coroutines? I'm racking my brain and can't come up with one. If your coroutines are deterministically given time, then I guess you can avoid race conditions, but "are my coroutines deterministic" seems like a really difficult thing to conclusively prove in all cases (like, just add network I/O latency), and the conceptual barrier remains the same whether they're deterministic or not.
(Edit: a friend just noted the possibility of writing to memory/disk and reading halfway through, and if you don't have atomic writes that's true, but you can have preemptive, single-process multitasking that interrupts mid-write; that's why we have file system lockfiles, isn't it?)
I use node-async-locks when writing JavaScript sometimes if I have to deal with shared state, because, hey, I might have to await something and come back to this later. (Obviously I try not to, because duh, but sometimes you're stuck with it and can't immutable-all-the-things. So you define a critical section and do your thing.)
I used to love to idea of a global interpretator and/or a single thread (coding without concurrency). It was great until it wasn't. Learning Elixir helped me get over that.
The thing is : it isn't an "idea" at all. These projects ended up with a big lock, or not tolerating reentrancy due to history -- they were developed at a time, and in an environment where there were no threads (or where support for threads wasn't of interest to the developer). It's just a bug. Not an idea, not a benefit. All the talk of it being the best way is nonsense invented after the fact to try to justify something that's just broken.
> Frankly, I'd rather just write 'C' again. If I have to care about the fiddly bits, I'd rather the language not fight back.
Instead, you'd rather the language be written with conscious land mines in it?
Like, I have a history of dunking on JavaScript. (Though, to be fair: ES6+ is better! It's a lot better. I kinda like it.) But C is unsafe as hell. The list of people who should be writing C is super short.
If you're running into memory links in Node, that points to bad native code or handles that are never getting removed. That's not something easier in C, unless you also like buying yourself double frees that you have to worry about. And backpressure is an architectural problem--it doesn't go away in another language, the ephemera of it just makes the problem surface in a different way.
Maybe what you're writing isn't appropriate for Node. Much of what I write isn't--if I start seeing buffers, I start reaching for another ecosystem, usually the JVM. But that's a far cry from a meaningful criticism of Node for what it's good at. Use what's good where it makes sense. Use other things where they make sense. Revisionism to have C make sense, in 2017, when we have modern, clean C++ and Rust both and Go if you really don't actually care about type systems, makes me really skeptical.
We have a handful of stupid simple http servers. We use express, redis, aws-sdk, pino, misc. Responses are mostly JSON.
The http-request module has given us the most fits. I question that any one has ever used it for more than toy problems.
The redis module is also an engineering marvel. I gave up trying to add a rate throttling shim. The goal is to limit the number of concurrent requests. Because when our app is under load, we're not processing redis responses fast enough, so redis server's outbound client buffers grow and will eventually OOM ABEND the server. So I wrote our own stupid simple redis thing using async.queue as a poor mans thread (task) pool. Trivial. Eg my REPL parser is 1/3rd the size of node-redis-parser. Works great. I keep thinking I must be missing something.
From my reading, hapi (successor to express) does an inbound backpressure thing. I'll be trying that out asap.
Much as I hate Spring, AOP, jedis, annotations, jaxrs, log4j... I've never had these kinds of nuts & bolts problems. Now I kinda miss the elephant gun approach.
PS- I can only assume the on drain event strategy was someone's idea of a practical joke. Maybe its a uvlib thing.
"I find the current state of affairs (emperor has no clothes) appalling and baffling."
JS is the only language on the browser after Java and Flash were killed off.
Brendan Eich created JS.
Brendan Eich runs Mozilla.
No new browser language occurs unless the big players (including Mozilla support it)
Mozilla have killed all attempts to add new languages to the browser.
Q.E.D. - language monoculture due to one creator forcing his creation on everyone and denying anyone the chance of doing things differently.
At least Web Assembly offers some hope for a sane future where we can actually choose the right tool for the job rather than the only tool for the job.
Node is single threaded, in the sense that your code runs in a single thread. Your code assigns microtasks, to be executed later.
Basically, if you write in Node JS, there's no concept of a thread. The thread API is not visible or accessible to the developer.
This forces you to think from the ground up about asynchronous operations that would take some time to complete - file opening, network requests etc., and have you group all tasks dependent on that time-consuming task, separately.
In Node, you are not supposed to block the event-loop that runs in that single thread and queues the tasks.
Node JS has shown over the years that it scales well (maybe not as good as Go or Elixir, but enough for most use-cases).
Node also offers lot of great tools, that can be easily added to your project via NPM / Yarn. The Node ecosystem has a solution for virtually any task you might need to do repeatedly in a project.
Just to be clear, I am not saying Node or its ecosystem is perfect. There's always room for improvement.
What I am saying is that what appears as an obvious flaw, is not really a flaw. The language allows other approaches to solve the problem.
Using non-blocking IO is a very old trick. Even nginx does exactly this, and it's written in C. The ability to use non-blocking IO does not make a language unique in any real fashion.
This is the key. And it reflects poorly on them for that. Syntax is the easiest part of a language to learn. The nuances of behavior is the hard part - and those nuances change as you move from the browser to the server; what makes good browser code will not make good server code.
In reality they shunned a ton of knowledge and community support to keep a particular (and particularly mediocre) syntax. Even today, years after Node has reached popularity and many lessons have been learned, developers with no experience outside the browser think they can write perfectly good server code, simply because they know the syntax. Never mind that all of the design patterns change. Never mind that the core libraries they use change. Never mind that they suddenly have to be cognizant of how much CPU time their code takes.
> Even today, years after Node has reached popularity and many lessons have been learned, developers with no experience outside the browser think they can write perfectly good server code, simply because they know the syntax (...)
This is really true and it's sad, because it leads to more security problems on everyday software.
Beyond the syntax, an event loop is conceptually simple in a way that other models often are not. (For example https://news.ycombinator.com/item?id=11555866 had a how to Python async and I found it a bit confusing compared to js).
It has nothing to do with the language, there were other serverside javascript frameworks before node; they didn't take off (e.g. Narwhal).
Node's success has everything to do with the environment itself in combination with the language. The node runtime, the associated stdlib, and most open source/3rd party modules have been written for a non-blocking runtime from day #1. The same stuff can be achieved in plenty of other languages/stacks (e.g. Python + Twisted), but you have much more work to do validating that every single library you use plays nice with async io, sometimes you have more event loop housekeeping responsibilities, etc...
Node's success has everything to do with the environment itself in combination with the language.
Let's be honest: it is nothing to do with either of those and purely a matter of fashion. In a couple of years at most there will be a new new thing and everything will revert to version 0.1, keeping everyone busy but making no actual progress. Gotta soak up those CPU cycles the hardware people are giving us somehow right? Can't let the users get any of that speed for themselves!
After two decades in this industry, I've come to the same conclusion. Developers may use logic in coding, but trend-wise, we're bunch of herds following whatever others are doing. We forget whatever lessons we learned previously whenever something new comes out. It's good to see there are others who see insanity in it as well.
There is a logic to following trends, but it has nothing to do with the problems being solved and everything to do with remaining relevant in the workforce.
I agree with this. I've seen the same but the core problem is we don't learn from others mistakes: we prefer to rely on our own tool-making skills to demonstrate increased facility while making similar mistakes.
The thing missing in developers that I have decried over and over in this devop/agile movement is that SAs had discipline and an ordered idea and that developers exist to perturb the norm to better effect. The two ideas are not readily reconcilable.
You have it all backwards. Fashion is the reason you hate it, but before it was fashionable it was not. I get that you're bitter and angry, but you do yourself no service by sticking your head in the sand and willfully ignoring the forces that drive popularity.
I'm frustrated that better stuff doesn't win in the market as well, but I've been a web developer 20 years and Node's appeal was pretty obvious and exactly as the GP states. Without that it would not have gained traction to become fashionable.
And nobody really wanted to do these message passing single threaded event loops in other languages, because they could just learn how to use threads instead.
The real innovation that the Node environment and the Javascript language offered is one of marketing to developers who did not know better. Because there were no I/O paradigms in Javascript, one could be created to support this way of doing things, and there was no competing paradigm that people could point to in Javascript to say "Why would I do this when I could just use threads? It's not that hard."
With that out of the way, the floodgates opened, because once the first few people started adopting it because they did not understand threads, it was only a matter of time when "front end" people adopted it, because they did not know any languages other than Javascript. And thus, the current fad was born.
> In Node, you are not supposed to block the event-loop that runs in that single thread and queues the tasks.
well, sure, but ten years ago it was already a given that one would just spawn one event loop per thread and have them communicate with messages, so why is it so hard for node ?
I/O is not going to be any faster by having more threads. More threads are not gonna give you more RAM either. And CPU-bound tasks are only faster if the OS you are running in exposes multiple CPUs.
With VMs and containers with focus on horizontal scaling (many relatively small machines) that is not the case either. Effectively the message-passing communication between threads still exists, but has moved outside the service: done by a load-balancing HTTP router and/or a message broker like RabbitMQ. Another example is when using out-of-process persistence like with Redis.
> I/O is not going to be any faster by having more threads.
That's not true on NUMA systems with multiple CPU sockets. You should have at least one thread per NUMA region for optimal results. Critical for example for running multiple 40 or 100 Gbit ethernet adapters.
Then again, you probably aren't going to run Node.js on those systems, at least not for handling heavy I/O.
As far as I can tell, Node.JS actually does use multiple threads for I/O, both for for networking and filesystem operations. But this implementation detail is not something programmers using it needs to think about.
> I/O is not going to be any faster by having more threads.
the world doesn't revolve around making HTTP servers. Maybe you aren't writing apps that do parallelizable serial computations but please don't generalize.
Sure it does. Ask a direct question get a direct answer.
Backend and file systems, network and systems middleware do not need the abstraction model and overhead of a language designed to add dynamic content to fucking WEBPAGES because
it can and it seems easy.
>Backend and file systems, network and systems middleware do not need the abstraction model and overhead of a language designed to add dynamic content to fucking WEBPAGES because it can and it seems easy.
Well, file systems nobody writes in JS, so that's irrelevant.
As for "network and systems middleware" depending on what it does it can be a great fit for JS and especially Node, which is a lightweight logic layer on top of libuv.
Too literal. It's the file system syscalls translated into node which are the problem. Anytime you have the potential to block you lose the relatively clean event loop and enter libuv which is a thread provider.
'Lightweight logic layer on top of libuv': well if I can design, predicate and tout my language on 'event' orientation but then when it needs to do something else it becomes a thin logic layer over the hosts threading model: that's just a win!
>well, sure, but ten years ago it was already a given that one would just spawn one event loop per thread and have them communicate with messages, so why is it so hard for node ?
This is exactly how backend Node.js development is done. The tradeoff is that processes are used instead of threads, which uses more memory but is magnitudes easier to work with than traditional threads where mutable bits of memory are shared.
Sure, Rust solves these problems but Node still has a place in the world: it is established, easy to pick up, and can share code with the browser. A decent solution to modern web development complexity.
Personally I have no real objections to JavaScript as a language but somehow I get the feeling that, in many situations, NodeJS is more a problem than a solution. I.e. JavaScript and NodeJS are two different things and I think they shouldn't be treated as the same thing (i.e. NodeJS is JavaScript and vica versa). NodeJS could have been shipped with a different language (Lua?) but I guess NodeJS surfaced around the same time Google released their V8 engine, so...
To me it seems that NodeJS solves a very specific problem; handling many simultaneous persistent network connections (i.e. websockets). I can't help thinking of NodeJS as fundamentally being a programmable socket server. I.e. its purpose is to solve a network problem, not a business logic problem.
The problem for me, when I work on large(r) apps that run in NodeJS, is that there is a certain "mental overhead" associated with it. NodeJS has this non-blocking IO, event driven architecture for a very specific reason which makes total sense when you solve IO problems (such as handling many simultaneous network connections) but this behaviour somehow seems to trickle down into business logic. With NodeJS I find myself writing non-blocking, event driven business logic because the environment in which my code runs dictates this. Somehow that doesn't make sense to me. To me business logic is inherently synchronous.
Now there are some really clever ways to compensate for this such as the Promise and with never versions of JavaScript there are even new language features to help battle what was originally known as the "callback soup". However, no matter how clever and admirable each of these features are, to me they seem to compensate for a fundamental problem in the run-time environment (NodeJS) that actually makes it not really suitable for anything CRUD and beyond.
For the millionth time: It is not accurate to refer to it as single threaded.
The language is non-blocking, so any asynchronous tasks (DB read/writes, disc I/O, cache, http, etc) will immediately jump to processing the next request the moment it is not doing blocking computation.
Depending on how many threads you can get going at once, you may be able to achieve comparable performance doing threading, but nonblocking is basically leaving 0 time on the core wasted and limited to the speed of the event loop.
And then on top of that, clustering module is used to do the same thing on every core.
It is accurate to refer to it as single threaded, because it executes with a single thread. "Non-blocking" is an orthogonal concept to the number of threads being used.
You can have "non-blocking" and multiple threads at the same time.
I just tell myself it's because the sales pitch is so appealing: learn, and use, one programming language on the front end and back end of your web site.
I've never written anything on node.js, but that's the only argument that's ever given me pause.
Favorite node / libc impedance mismatch is the stat() call. stat() returns an inode, which is a 64 bit integer. But JS doesn't have 64 bit integers, so it just gets rounded to the closest representable double. So node will sometimes identify two different files as the same file.
>To me, the fact that Node has to add a library with custom semantics just to allow a basic 'open' on a file handle is a huge warning flag to me
What do you mean? The fs module shipped with node is pretty much just a wrapper for libc. Hell, it even links to the open(2) manpage in the docs for usage information.
That JavaScript was not designed to work as a *nix (or Windows for that matter) server language. And that any attempts to make it work as a server language are going to include some major workarounds to fit that round peg into a square hole.
You can still make it work; but you can script a web page's interactions in C as well. That doesn't make it the right thing to do.
I'm not a particular fan of JavaScript on the server these days, but when you have a large number of developers who know JavaScript from the front-end world and a language ecosystem that's quite large and relatively robust, I would argue that doing those "major workarounds" (which aren't so major, really) to make server-side JavaScript an accessible option at least very closely resembles the "right thing to do".
Should we collectively eschew what's possible due to individual language gripes?
While I think we agree on points, I also feel like your argument is kind of an overgeneralization. There are knowledge points specific to Node, but developing good code for the browser has similar land mines (referring mainly to asynchrony here) as developing for the server. The problems that exist at the language level, and best practices, are generally applicable to both the server and the browser.
As far as libraries are concerned, it was never my experience that the landscape changed drastically from one to the other. Most of the libraries I look at/use for the front-end today advertise themselves as both for Node and for the browser.
No. We should collectively evaluate competency and correctness of a developer and language for it's best purpose as in any adequately run job interview.
> collectively evaluate competency and correctness of a developer
I'm sorry, is this a dig at Ryan Dahl, or of JavaScript/Node developers in general? I'm having trouble understanding what point you're addressing with this comment.
As for evaluating languages for their "best purpose", I think that's a very complex discussion that doesn't necessarily yield a best (or cost effective/productive) result. And certainly, as we've seen routinely evidenced, using a different language on the server is no panacea.
I'm sorry, what don't you understand?
Complexity is best discussed by those who introduce it.
To be clear: I said js is misplaced on the 'server' side
and is a wart in general when applied in that context.
Any educated comment on these sentiments?
Without clarity on the sentiments themselves there's not a lot to elaborate on without simply fumbling in the dark. If the concern, though, is that, in Node, you live and die by an asynchronous event loop, I'd say that's not a small footgun. I don't think that's in dispute. I'd also say that the presence of footguns doesn't, by itself, disqualify a language from being used in any particular context.
As for JavaScript being a wart, I don't really agree with that sentiment. I think that's attributable to some pretty strong and level-headed language evolution making what was once a very blunt scripting instrument into something somewhat reasonably suited to larger-scale applications.
JavaScript is objectively, demonstrably a badly-designed, error-generating language for which countless libraries, generators, and higher-level languages and frameworks such as Elm and TypeScript have been created to compensate for its shortcomings - and it most especially does not belong on the server side.
It is the poster child for the "If the only tool you have is a hammer..." maxim.
Its appeal derives almost completely from its presence in probably every major browser, where it was placed for DOM manipulation and was stressed way past its design envelope over time, leading to the increasingly dystopian web development landscape we progressively inhabit.
If it is ultimately victorious, it will be in spite of its design, not because of it. Those of us who are old enough to remember will cringe at the pain we endured over the years because of the widely used Intel 808x architecture as it evolved (small/medium/large/huge memory models, and segment registers, anyone?), not because it had the greatest merit, but because of its market penetration.
I really don't disagree on any particular point. I only take issue with the suggestion that it simply shouldn't be an option. In the past I probably would've said the same about PHP, which sits pretty squarely in the same camp as JavaScript for its "victory despite design".
All things considered, a craftsman simply uses a tool to do a job. Often it doesn't involve much fanfare. I wouldn't say that modern JavaScript is quite as blunt an instrument as a hammer, but hey, if you're good with a hammer...
Js is a scripting language that relies on the program being scripted to interact with the outside world. In browsers, this is the DOM and xhr APIs. On servers, this is the node stdlib which lets you interact with the system. The fact that this kind of modularity bothers you is bizarre.
It is a modularity that is an unnecessary point of failure compared to other choices available, and involves poor abstractions for Javascript to use things it was not intended to use.
Kotlin is slowly becoming s language that can do all of that. It's production ready for anything that uses java, js support is coming along great, and their slowly moving towards native.
The front end/back end sharing argument never appealed to me. In practice, how much are you actually going to be able to share? No way it's worth it.
What's finally got me writing way more Javascript than I'd like to is React Native. It's by far the easiest way I know of to share code between iOS and Android, it papers over a lot of Android's irritating/broken UI bits (introducing others, but overall improving the situation), and you actually can share much of your code (practically everything but the UI layer) with a web client—and even... spits... Electron. RN's performance isn't even terrible, especially compared to cross-platform mobile frameworks that have come before it (and to Electron spits)
Hopefully Webassembly will save us in another couple years, and we'll be able to do the same thing in any of several much better languages.
[EDIT] though definitely keep your sanity and use Typescript. I'd have probably jumped off a bridge by now if I were having to do all this in actual JS, of any flavor.
the front/backend sharing stuff matters more these days with server side rendered apps, but I've used nodejs plenty for this lifetime and have no plans to touch the stuff again for serious applications
I think most of what you share is the effort needed to learn the language.
Also, it 'helps' if both server and client are single-threaded, because then, you can use similar solutions on both server and client (even if they sometimes aren't the most pleasant approach for solving your domain)
I hope that Web Assembly will take of and get a decent interface to the DOM, allowing developers to pick other languages in the role that JavaScript now has.
You should try. I come from a traditional Java shop, and a year ago wouldn't have thought of doing anything serious with Node JS.
Today, I do front-end React stuff as well as back-end servers with Node JS. I have been happy with it so far.
With some type-system like Flow or TypeScript, you can manage huge projects in Node JS.
I happen to like the community, CLI tools written in Node, and the plethora of open source libraries built on top of Node.
This also has a downside. Your libraries can get outdated quite fast, you would have to keep up with new language syntaxes etc., and remember which syntax is supported by which version of Node etc.
But so far, I think Node is headed in the right direction.
With ES6, JS became a really nice scripting language. Personally, I'm glad to see more and more projects that use javascript outside of web browsers and I've also added V8 to my most recent C++ project. The only major drawback in my opinion is, that it's not statically typed.
The deeper problem is that JS is not strongly typed. Typescript gives you static type checks but the runtime is still weakly typed and will still do all sorts of weird type conversions.
Theoretically, to what extend could the weird type conversions be prevented with the use of a strict linter? My intuition would be all, but I haven't thought much about it.
Once code reaches a certain complexity level (and mind you, the threshold is rather low), you'll need dynamic generation of code and data (or else, write 10x the amount of lines of code). For this to happen in a safe way, you really, really, do need the runtime to be strictly typed.
Are you making this claim about JavaScript or as a general statement? I've probably written less than 1000 lines of JS ever (and that only for hobby projects), but I would strongly disagree with this statement as applied to C++, Java, etc.
I'm sorry, I'm confused by the way you expressed that. The argument was you need strict typing for large projects. C++ and Java have strict typing. What exactly is the basis of your strong disagreement?
My comment is applied to any language with weak typing. Example: Javascript, PHP, and (sadly) C, particularly when using pointers to void. However, in C it's okay since there are big performance gains when you have full control of the memory.
Strong typing is a start but not enough for my taste. Static typing serves as documentation and compile time bug check, which is awesome to have. I'd like to have both, without the detour over typescript.
What better alternative do you have to TypeScript right now though that you can use practically with existing libraries? Perfect is the enemy of good. TypeScript can capture more complex properties than C as well.
I agree. On the whole, I think JS is a middlingly-nice language. It has some good bits and some bad bits. ES6 brings a whole lot more good bits.
I sometimes think we could do with a bit more thanking-our-lucky-stars that the language that got entrenched on the web wasn't, say, VBScript (which IE did use to support).
The real issue with js (node) as a "scripting language" is the lack of a stdlib. A nice thing about writing a Python script is you know the stdlib is there on your remote machine (since some version of Python is on most systems by default other than windows).
The argument that people always throw at me is that too hard for people to know two languages, well, for frontend devs to know two languages. Now in a perfect world the frontend people who just can't figure out two or more languages would never touch the backend but the world of software now is "that'll do" not "what is the right tool." It's a shame to me really but I'm not a frontend dev for a reason.
> The argument that people always throw at me is that too hard for people to know two languages, well, for frontend devs to know two languages.
This is ridiculous from the point of view any professional developer. I know that this is your point, and I'm just amplifying it. I (and many other professionals I work with) know - and use on a daily basis - so many more than 1 language that it's sincerely baffling to grok a world that promotes "One language fits all". That's without even considering the parlous state of npm and its libraries.
If "frontend devs" are really, truly, genuinely capable of only holding one language in their heads, and that language is Javascript, then we should deprecate the term "frontend developer" and replace it.
I would propose "person who can only be at most half-competent," except that is too wordy and probably too charitable.
> whatever would motivate people to use js for anything more than is strictly necessary.
If that's the primary language you are good at, from coding frontend apps, then it's pretty nice to be able to switch to writing backend code without having to do a language context switch. Muscle memory along with your memory about library methods all just continue to flow.
> It can't be that hard using a different language.
If I'm better at one language than another, it is at least somewhat harder. Why struggle when you can flow?
> If I'm better at one language than another, it is at least somewhat harder. Why struggle when you can flow?
If you're better with screwdrivers, why struggle with a hammer?
JavaScript has a painfully slow runtime. Writing servers requires attention to performance and reliability, which javascript is very poor at. If you want to make a toy service and don't care about any of this, go ahead and use your favourite language. But when you want to make something incredibly fast and reliable (like nginx), you'll need to consider another technology.
>If you're better with screwdrivers, why struggle with a hammer?
Hammers and screwdrivers are not general purpose tools in the way that languages are.
For most things, most languages are just as fine.
It's not like JS is specialized in some very small niche by design -- like e.g. COBOL is.
>JavaScript has a painfully slow runtime.
I call BS. v8 is one of the fastest dynamic runtimes, at 2x of C or so for lots of tasks, and it totally obliterates Python, PHP, Ruby, and co in speed. And since some of the web's different properties are written in the latter 3, it's certainly not speed (which JS surpassed them far in) that's the issue.
>If you want to make a toy service and don't care about any of this, go ahead and use your favourite language. But when you want to make something incredibly fast and reliable (like nginx), you'll need to consider another technology.
Nobody writes "nginx" in JS.
They write the kind of APIs and apps and services that people also used to write in PHP, Python, Ruby, Go and whatever lang.
> I call BS. v8 is one of the fastest dynamic runtimes, at 2x of C or so for lots of tasks, and it totally obliterates Python, PHP, Ruby, and co in speed.
Any proof for this?
EDIT:
According to "The Computer Language Benchmarks Game"
JavaScript fares pretty well against Python [1] or Ruby [2] but not really that great against C [3] or Java [4] in the CPU intensive benchmarks.
>JavaScript fares pretty well against Python [1] or Ruby [2] but not really that great against C [3] or Java [4] in the CPU intensive benchmarks.
Considering is a non-static, totally dynamic language, with all kinds of dynamicity in it, it does totally fine. 10x to 30x faster than Python, Ruby etc, and 3x to 5x slower than C/Java is totally fast.
There's nothing about JS as a language meant specifically to "programatically manipulate the DOM in the browser".
Anything it does related to that is just simple library code and methods on the "document", "element", etc objects -- and that's only when run in the browser where those are available (automatically "imported" let's say). Node doesn't even have the "document" object.
And the "Browser API" was invented to do what, exactly? And by what mechanism was said API exposed to developers? And whose cocktail napkin was the specification written on?
JS JIT were already many times faster than PHP5. There's no comparison to the complexity, quality, resources and top-notch teams in play in JS JITs (just consider the vendors making them: Google, Apple, Microsoft and Mozilla) and PHP.
> If you're better with screwdrivers, why struggle with a hammer?
Not a great analogy. A more accurate analogy is switching from one very big toolbox to another very big toolbox. If you are used to one and know where all the tools are, and they have been used so much that the wood perfectly fits your hand, then it's just going to take some time to get used to the new toolbox. I'm not saying it's a hard rule and you should never consider another language. I just answered the question of why someone would want to use javascript on the backend. It's not the only factor, but it's a factor.
Imagine we have carpenters and brick layers. Two distinct jobs that maybe have some overlap of tools.
We decide that we have a lot more carpenters than brick layers, so we'll take a carpenters' toolbox and add a few brick layer inspired tools to it (but they're not necessarily the same, and some of the tools that can overlap maybe aren't quite as specialized, nuances, nuances, etc.).
Now, we can tell our managers that our problems are solved.
All of our carpenters can now do masonry work.
The root problem of all of this mess is that both of these domains are different. Problems and solutions in the front-end tend to be different than in the back-end.
Management is sold on this "everyone is an interchangeable cog now" fantasy they have been chasing for decades and crappy decisions are made. We end up with most developers not really learning at least one of the areas of the full stack very well (and not learning both if they are really striving to under-achieve...).
Note: This same thing happened in Java before NodeJS, but in reverse. Back-end developers refused to really learn web development and so we ended up with misguided solutions like GWT and virtually every other high level Java web framework/library.
Perhaps I haven't run into the right people, but mostly my experience with other JavaScript devs is they don't even know the fundamentals really (they don't understand scope rules in JS, they don't really understand weak typing, they don't understand JS is single threaded, they don't understand closures very well, etc.). I don't know if this lack of understanding is due to a lack of experience programming at all, or just not really learning JavaScript (many non-JS devs are forced to learn enough JS to get the front-end working -- or at least seemingly working).
The thought of lowering the bar on development even further is frightening (Johnny did some web development last year, I'm sure he can transition to writing our back-end API since he knows JS). I'm all for anyone learning and improving as a developer -- and sharing in my passion. What I hate is this false confidence more and more people seem to have with everything and the problems it causes (they don't bother to learn the tools they have or the tools that came before them, they are too lazy to learn a new language/framework/library, and they have extreme NIH syndrome).
Javascript as a language and ecosystem has evolved quite dramatically during the last years. Its not perfect though: it lacks features and ecosystem is still not in the level of maturity of other platforms, but is definitely going in the right direction. Regarding the single threaded server, its an architecture used before JS exists, and used by many other platforms/systems. Just to give you an example, Nginx workers are single threaded.
In Nginx you're not doing computation, just passing IO thru between file system, external processes (i.e. PHP via fpm) and the network. If Nginx ever is CPU bound there's something bad happening.
As I mentioned PHP: In PHP each worker is single threaded, too, but you can scale by having more workers in isolation.
You've hit the bull's eye! Yes, and you're also not supposed to do much computation in Node JS code.
Some addition, subtraction is fine. But Array iteration, JSON encoding-decoding and similar CPU bound tasks could block the event loop.
You can perform them asynchronously, or forward the request to some remote service that's better at doing these computations for you and return results (maybe some service written in Python or a database)
What computations do you do in a webserver which hosts a REST API? Most of it is simple CRUD connected to a database, possibly with an auth layer on top, which is pretty much what you describe, passing IO through to a database and back.
Compression, hash computation, regular expression routing lookups, parsing text, building and serializing datastructures, reading and writing caches; I could go on.
Sure, JavaScript (and Ruby and Python) are usually fast enough with modern hardware - but we can't pretend there's no cost.
deserializing data structures is a great example. JSON.parse is SLOW. all it takes is a bit of bad code that doesn't do any checking of input size/etc... and if an authoritative source starts sending larger payloads than usual, your node process is horked. Granted, that's not a problem remotely specific to node, it just has a bigger effect in a node env.
Does HN think putting 2-15KB JSON blobs in a Postgres DB running on Docker on a router is a good idea?
Oh, and the table stores log data, so there's about 2 million rows after 5 days uptime. What do you think?
EDIT: This was not entirely related but it goes to the notion that it seems like a lot of myopic decision-making has somehow become even more acceptable and I would say this leads to dumb situations as above, and Node.
PHP isn't exactly the best alternative to compare node to; it was pretty much designed specifically to live in an Apache request-response cycle. It's not hard for most things to beat it in contexts outside the one it was intended for.
I don't think it actually is going in the right direction, they've screwed up loads of things.
Things like getter/setters and object initializers. And don't even get me started on Web Workers, which basically seem to be dead on arrival. The Web Workers design is so shockingly bad and not fit for purpose that I don't understand how anyone signed off on it.
Some bits of the new js are in the right direction, and those are the things that people talk about and are getting used, but lots of things were definitely not.
>The more time goes by the more I feel crazy for missing whatever would motivate people to use js for anything more than is strictly necessary. Single threaded server???
There are a lot of knowledgable people commenting, but it's starting to seem like they haven't familiarized themselves with the tools available within the NodeJs base.
To another point, I could put the time into writing a server and back end application in Go or Rust or C++ or whatever, but it would take (at least me) 10x as long to build out the application I need as it does to pull express into a project and build out a server, back end computations, file manipulation, authentication, and roll a MongoDB store with a fully-fleshed out front end (even if it's not so stylish).
Mind you I work in an enterprise environment where these kinds of things are required to serve maybe twenty people and run on a single multi-cored machine at any given time and not tens of thousands users.
It's a fantastic tool that works from small to mid-large projects, and would serve as an excellent prototyping and MVP-dev environment for even the naysayers who are probably more skilled than I am in other areas.
The problem with Node is it's unsuitable for a whole class of server applications - you're going to run into trouble whenever you need to maintain serial access to a single resource. Whereas in Java you'd have some sort of token that gets "taken" by different threads, there's no clean way to do this in a multiprocess Node environment.
I feel like it's less Javascript that's eating the world and more Node and NPM.
It seems as if it's impossible to publish a Javascript project without taking for granted that the developer has, or even wants, a package manager with dependencies, arbitrary toolchain and transpiler along with it.
Maybe I'm just a dinosaur for not wanting my "build process" for javascript to be more complicated than including a script tag. That's probably what it is.
The way to look at it, is that browser is a target runtime platform.
When you write code in a team, you optimize for readability, maintainability etc. You spread your code over 5 directories, 50 subdirectories, 3000 files.
When you want to run this in a browser environment, it needs to be optimized for delivery - faster download, less time-to-be-interactive. You need to split your JS codebase as per routes in your app, and load chunks as per user demand.
Not just JS, you'd have to compile and inline your CSS, base-64 encode your images to data-urls, generate image stripes.
Before all these, you'd have to lint your code, and run unit tests on your code.
I fail to see how you can do all these with just a script tag. You need some sort of a compiler / transpiler; and a task runner that gives you a handy interface to these.
The package manager has no dependency, other than the Node runtime itself.
As for arbitrary toolchain, the metadata is codified with semantic versions in your package.json. You're one install step away from downloading all the necessary packages.
One thing I think lot of Node project misses, is to not add which Node version is to be used. It's not because it's impossible to do that - there are two well documented ways to do that (via .nvmrc and "engines" entry in package.json)
The fundamental issue is that the overwhelming majority of interactive websites today don't actually need to be interactive, and may even be better off as old-fashioned HTML pages served by the server.
But people love over-complicating stuff, and when the end result is complex the toolchain has to be complex too, not just for one person but the whole team. Then you end up with developers who spend more time wrestling with webpack et al than working on actual features.
Can you list any examples? My hunch is that there are good reasons javascript is included on most sites where it is found.
Some of the incentives fueling this trend could be viewed as undesirable (e.g. monstrous ads on news sites as a desperate bid for profitability), but that doesn't negate the fact that the incentives exist, and aren't simply "people love over-complicating stuff".
Most of the web is so-called "content". Formatted text, images, video, audio. These require very little interaction. If you don't have user interaction and are just serving content, you probably need very little javascript. So I would say most major news sites, weather sites, etc. are examples.
To illustrate, hacker news and reddit work fine with javascript disabled, and the javascript they use is simple and just makes some interaction like voting work nicer. Even amazon, which is a pretty bulky and interaction-heavy site, works quite well with javascript disabled.
As for incentives vs over-complication, there's an interaction there. The incentives are to put some fancy whirly whingding on your website because it looks flashy and your target audience has (according to you) fast internet connections and web browsers. The incentives are to do this with the minimum of effort even if that means serving multiple-meg, javascript-heavy pages that don't even have any interaction.
In my experience, even conventional form interactions like a list view with mass actions can be impossible without Javascript, and then unwieldy without some sort of framework to keep the UI consistent and a pleasure to use for users.
I wish this "the web is over complicated" meme would die. The web at one point was only for hypertext. It is still fine for hypertext but it is now also an application platform and the browser a runtime and app container.
Your solution to the JS ecosystem is to make news websites less interactive. I see why you long for simpler times but I don't see how that fixes things.
For those of us who are building applications we need the complexity. It solves problems that come from the fact that the web has evolved from a hypertext system to an application platform.
The issue is not that "the web is over complicated". The bigger issue is that people are allowing themselves to be brainwashed into thinking that everything is a "web application". Some sites offer benefits as web applications; GMail and Pivotal Tracker come to mind right away as good examples. Other websites like CNN should not be applications and would do end users a disservice by over-complicating things by making them JavaScript based.
One of the trends I'm seeing is that a lot of developers once they have built one web site as a SPA they seem to start thinking everything should be built this way. More consideration should be given to deciding which is appropriate.
I think this sums up the most poignant complaint against the javascript/node trend. It's not that we don't need SPA's. SPA's are awesome. But sites like Reddit and Hacker News prove that they don't need to be implemented everywhere.
>>For those of us who are building applications we need the complexity
I'm not saying don't build applications. I'm saying web applications can be server-only and should not spill over into the client.
Again there are exceptions - things like control panels or consoles do benefit from being SPAs. But in a lot of cases there is also nothing wrong or insufficient or unsatisfactory (from a UX perspective) about clicking a link and having the server send you pre-rendered HTML. JavaScript can still be used as icing on the cake to enhance those interactions, such as by displaying a spinner on the submit button and disabling it once the user clicks it.
I think your point stands, but something feels wrong to me about "you optimize for readability [...] You spread your code over 5 directories, 50 subdirectories, 3000 files."
We need lots of tooling to keep our code readable across a zillion files.
And it is worse than you mention. You rarely get 60 files per directory, and, in addition to the files you want, your package manager and build system add a few zillion of their own that all can break your build in 'interesting' ways.
I felt frustrated by the typical Node toolchain until I remembered the typical Qt toolchain for developing cross-platform desktop apps. I can't remember everything, but here goes.
To compile a Qt app you need:
- the meta object compiler (moc) to add dynamic features to C++ for Qt use
- the Resource Compiler (rcc) to embed icons or sounds as arrays in header files
- the Qt Quick Compiler if you are using QML files for your interface
- the C++ compiler, linker, etc.
This is either driven by CMake, qmake or your IDE!! I see you can use Qbs to generate the CMake or qmake files! I remember learning CMake, make, ant, etc being non-trivial!
Oh, and you were on your own when it comes to dependencies!
I think it's more accurate to compare Node to C++, compare NPM to apt/yum/etc+CMake, and compare something like Electron to Qt.
Of course, your point still stands. But's a tradeoff. C++/Qt has a ton of compile-time bloat, while Node/Electron has runtime bloat (see the Slack client using hundreds of megs of ram). And you can use bindings, like PyQt, where you have Python/Qt and then you get Python's dependency management.
Like anything new-but-different in tech, it's probably a matter of using it for a while until you see the benefits.
I used to prefer a 0-dependency, no-build format for sites. Nowadays if something doesn't have an npm module it's enough for me to not want to use it for a variety of reasons.
I used to install "dependencies" by copy and paste and was happy, but because I didn't know how it could be better. Despite all of npm's woes (which are many) the concept is sound, and not just for JavaScript.
Is that the fork about the one contributor who annoyed some people on Twitter? Because that fork isn't worth paying any attention to; it's not going to go anywhere because it's pure politics.
Oh, this fork isn't in earnest. It's being overhyped because it's a select few people throwing a tantrum about ableism in the absence of any actual malice. There's no actual instability in the platform itself this time.
It gets easier once you get use to it. The output is a plain script tag include. Aot is one of the most amazing things I have seen. I can tell when an app uses it and when it is slow.
I think ES6 javascript is actually a decent language. But the way it's used is terrible. Slow transpilers that give all the disadvantages of a compiled language - but with the type safety of a dynamic language. Asynchronous code that is slightly better with promises and async/await, but horrifying to debug with stacktraces that are often completely useless. NPM with its plethora of low-quality packages - yet it's not uncommon for packages to have hundreds of dependencies. And when you try digging into those packages to understand what they do, because there's no documentation, you find a mess of javascript magic. Globals, nested closures, "coroutines" using yield and function references and a dozen magical libraries that are nearly impossible to untangle. I found the development experience to be slow and extraordinarily painful. I actually find PHP easier to work with (but more soul crushing to write.)
I would much rather use Go or C# or C++ or Java (well Kotlin, because I don't like to write Java) the development experience is just so, so much smoother.
JS has the appeal that it's something a lot of people already have good amounts of experience with. And ES2015+ features add to the learning curve, but also give some much needed aid to existing problems; it's easy to pick up on async/await when you already know how promises work.
Meanwhile, trying to find Go developers can be a challenge. And the learning curve is low, but there's plenty of low-level gotchas like dealing with concurrency and memory usage. (Yes, even in a garbage collected language, this manages to be a problem.)
In Node, you run into less issues because if you have a problem to solve you just npm install something.
That being said, my enthusiasm ends there. Every experience I have with trying to tie a database into Node has been horrible. Also, I think event loop based programming is missing the mark even if it beats out previous methods; I think Go and other CSP based languages like Erlang have the real right answer. I think if we really start seeing huge core counts, it will become apparent that a single thread event loop eventually starts to become a bottleneck. Also, NPM has an insane number of packages, but the quality is extremely variable - much more than PyPI, though I'm not saying everything on PyPI is magically production ready.
I guess what I'm saying is, maybe I should start learning Rust.
It bothers me that I have to agree with this. I watched an NPM install once, and noticed that one particular library was downloaded and compiled somewhere around 40 times (and each compiled version was different).
Think about that for a moment: one library, 40 versions downloaded and compiled to fill NPM dependencies. What if there was a vulnerability in a version of that library - how do I audit that? Can I even fix it myself without hosting my own NPM registry? Bandwidth? Computation costs (a thing again, with cloud computing)? Disk space costs?
It makes me glad we just use Docker; so I don't have to try and make sense of the NPM madness from day-to-day. Just Docker's own brand of madness.
Personal experience: NPM can be mind-bogglingly slow in Windows. In my previous day-job, an NPM install on Windows 7 could take hours, for some reason. That's NPM 3 with about 20 dependencies on a small project.
NPM on Windows also had other problems such as Python path is wrong or C++ compiler is missing.
Then we switched to Yarn. Uncached install took about 2-3 minutes, and cached install would finish in seconds.
Recently, NPM 5 has been released, and it's been competing well against Yarn.
Still a bigger fan of Yarn here. My personal tests have Yarn running a bit faster still, but I also like that Yarn's command syntax is easier. NPM seems content with making a million aliases of everything and it's annoying. I think they even added 'add' from Yarn.
Also, Yarn's run command can be used to run locally installed NPM binaries, not just NPM scripts. i.e., you can do `yarn run -- webpack` and it will run the local copy of Webpack. This is handy imo, and as far as I know NPM doesn't do it.
I like Yarn run, because if I'm running a lint or tests, it errors out with error messages related to the specific process.
If you run via npm run, it would throw lot of extra error messages, making excuses that it wasn't NPM's fault the command exited with a non-zero status etc.; and hiding the relevant error messages.
And as always, you can just run a script as yarn script, instead of yarn run script; like yarn lint:src, instead of yarn run lint:src.
NPM does it only for a few common ones.
Also, Yarn run picks up right node version from .nvmrc - you don't have to run an nvm use and switch to it.
FWIW npm 5 comes with npx [0] which basically does similar things. If you run npx webpack it would use the local copy of webpack or even install one run it and discard it.
That's not the same thing. Npx is for running commands you install from npm, and yarn [command] allows you to run scripts defined in your package.json file.
Most of these examples aren't "moving off Java to Node" as the post tries to conclude, it's simply breaking out the view layer to "a right" tool for views. If anything, it's simply adding a supplement to existing systems.
In many large orgs devs still use a homogenous tool for the existing systems (e.g. my guess is at Netflix all new business logic services are still Java based to plug into the Spring+NetflixOSS stack).
Python is still dynamically typed, though at least it is less weakly-typed than JS.
While the benefits of moving any distance away from JS's weak-typing are certainly obvious, why stop at Python rather than a language which is both strongly and statically typed?
They didn't mention anything about typing as reason for switching. They said "It's a really frustrating ecosystem to work in, all the deps, toolchains, build process is extremely fragile." They switched to python for the ecosystem and tooling.
JavaScript tooling is notoriously complicated on the front-end, not the back-end. And I doubt they're saying that they switched to Python on the front-end.
The distinction was that cdnsteve was motivated to switch to Python due to issues with the toolchain and build system, not that JavaScript was weakly-typed.
> JavaScript tooling is notoriously complicated on the front-end, not the back-end. And I doubt they're saying that they switched to Python on the front-end.
You have a good point, though you still have to pull in dependencies and deal with NPM when running JS on the server-side (especially if the server is doing non-trivial stuff). Idk, maybe an approach with server-side rendering using Python did away with much of the JS usage which made things nicer.
Right. The following could be written as "Netflix uses Node to render React components" which is pretty much a given.
> Java still powers the backend of Netflix, but all the stuff that the user sees comes from Node. In addition to Node, Netflix is also using ReactJS in their stack.
Javascript is eating the world because so much stuff runs through the browser these days and javascript is a given to be available.
That alone will effectively stop the world from migrating away from JS. More and more people will give NodeJS a whirl, confident at very least that JS isn't going anywhere for quite a long time.
It just creates a cycle where you're going to see very little slippage in JS usage and most of the time ever increasing usage. It won't be this way "forever" but we're probably a decade away from peak JS.
The other day I managed to freeze my computer -- such that I did not even have access to the SysReq key, by stupidly running
while (true) { var d = new Date; e.textContent = d.toLocaleString(); }
I immediately realised my stupidity, and closed the tab. Shortly after, my mouse froze up, then my keyboard access, and eventually my entire access. Rather than just freezing Xorg as I had initially suspected, it froze my entire computer access. No SysReq, no switching to a tty, nothing.
I was an idiot, but at the same time, an unprivileged process should not be able to consume resources like that without a dæmon coming in and pausing/killing it. And the Javascript should not have been allowed to execute once I had closed the window.
I tried your code snippet on my inferior Windows OS and inferior IE Edge browser. The tab stopped functioning. I opened a few other tabs and continued to work. Eventually IE showed a notice that the tab had stopped responding - I had the option to close the tab or recover the webpage. I clicked 'recover webpage', the page was refreshed and I could continue using it. Truly, Javascript is eating the world.
Or perhaps the language has nothing to do with your problem.
Do you deny that implementations are part of the language? If the Javascript specification left this out, what other implementation gotchyas exist for them to exploit?
C explicitly states what an implementation should and should not do. The same with C++, FORTRAN, and other standards. Javascript is a standard written by committee. So why can't it tell implementations what is good behavior and what isn't? Other languages do.
I think there's a distinction to be made between the language spec (e.g., interesting Javascripty details like what is the result of `"" + 1`) and integration issues like what to do when the browser window detaches, how many threads the browser will devote to running Javascript, what to do when some of those threads appear to be blocked, or how should the runtime/VM attempt to recover from deadlock or OOM.
The implementations are what matter. They're the only thing that matters. It's the business axiom "Ideas are worthless, it's the implementation that counts" at work.
Ask yourself this: If V8's performance was still at 2010 levels, would Node exist?
And if some other language were the one which had been picked for browsers - JavaScript relegated to only running on servers - I wager JavaScript would hardly be used at all.
V8 is a good runtime implementation for a pretty weak language. Personally I don't think node's existence is a net positive for the world. Ask yourself if we'd be farther ahead if the browsers of 20 years ago ran Perl instead. Anyhow, this entire thread already supports the two ideas that (1) implementation is hugely important and (2) not all issues are language issues per se.
Javascript is just the language. Its your runtime environment (browser) that is letting an unprivileged process consume resources like that without killing it.
I would argue that all modern Operating Systems have dark corners and hidden bugs. It is just a question of time until you hit a similar bug on any OS.
I had a similar experience on macOS with Chrome Canary watching a YouTube movie full screen. My laptop simply froze, nothing, except a restart, worked.
Maybe. Callback / promise hell in a language that needs a book like "Javascript the good parts" is probably not eating the world.
Yeah it is cool, npm package system is (was?) one of the easier ones to use. It is a good starter thing for someone who has only learn or done frontend development before. But I have not had a good experience with it on the backend.
I think a few aspects of the language contribute to this:
1. It is relatively easy to comprehend and pick up and play around with.
2. With the advent of node.js, and later electron, it is incredibly relevant whether you're developing web apps, servers, or now, even desktop apps.
3. Some of the newer features, such as arrow functions actually make writing javascript a lot of fun!
JS has come a long way. I do think there are negatives to its popularity but I think it has also probably done wonders in terms of lowering the barrier of entry to get into programming. It's honestly a great language to start out with these days imo. It's easy enough to learn the basics (excusing the quirks of the language that do remain), easy to practice it developing whatever project you want to work on, and, even though it has problems of its own, node is a solid and, again, easy to use (I think it might be becoming clear what aspect here I think is key to JS popularity) tooling system for the language.
It still has its detractors, but all in all I'd say JS is pretty great.
Now, does that mean so many companies should jump to using it right away? No, of course not. But you can see why they are tempted. Because JS code is typically easy to use, comprehend, and manage, and because of its ubiquity it makes sense to use it so that as the composition of a team shifts and changes it's fairly easy to pass work along or pick up where someone else left off.
A key point regarding your first item is that it isn't particularly the language that is easy to pick up - it is that its original "native" environment made it very easy to access and play with. People often start with a bit of JS to tart up their web page, then move to making it even more interactive, and once they start wanting server activity there is now the option of not needing to learn another language for that. The single language server and client side is quite a draw, and with some frameworks where your code is running can actually be somewhat obscured so you don't need to care.
I agree with most of your points, however regarding ease of learning, I think it's one of the more difficult languages to wrap your head around, specifically when dealing with the Asynchronous nature of it. Majority of languages people encounter do not behave that way by default, and visualizing what function is being called where, and why results happen that you weren't expecting. Can quickly become VERY confusing.
I think it's a totally cool language because of it, but it definitely does not have that ease of use for any sufficiently complex application.
Compared to Ruby, Python or even Perl 6, I fail to see how anything in JS can be considered a superior option for scripting. Even for simple things like map/filter, reading a file or parsing script args ES7 scores just average. And I'm not even talking about debugging and error handling.
Does that really matter? The web is the past, present, and definitely the future. There will be less, and less native apps, and more and more web apps. JS is here to stay, and I'm glad big companies are pouring tons of R&D into making it faster, and easier to use.
No, JS is the one constraint we manage because it's the only stuff we got that is common to all browsers.
It's not driving anything, we keep hacking it to make it bearable. I mean, come on, the most popular projects in JS are all projects to avoid writing JS in the first place.
I'm with @mscheutz, JS hasa pretty much become my go-to scripting language. It's pretty great for quickly writing up an automation for simple tasks, and I find it's generally easier on the eyes than a shell script.
I have a hard time believing anybody with a taste of Ruby, Python or Perl 6 would choose JS. Are your a front end coder just using the proverbial hammer to the scripting nail ?
Okay, fine. Lisp was the first programming language with them, and lisp-like programming languages are the only ones still in widespread use that has have had them from the beginning...as opposed to every other random language that eventually figures out that what lisp has is a good idea, and then has to back-patch it into their syntax. I don't get why, since Lisp just comes back again and again and again, people don't just give up and standardize on it, and smooth out the blemishes, strengthen the libraries, and all this language squabbling would just end.
We really need to stop putting Javascript on the back end when there are so many other great options that won't be any different to the front end in most (all?) cases. I think working on full fledged Javascript solutions for the front end that address load time and page size is great. It still amazes me why anyone would use Javascript on the back end willingly.
For anyone who's searching for more quantitative data, there's always the 2017 Stack Overflow Developer Survey [1] which seems to reflect that js (& node) are still growing.
Yes, in a survey that returned that 72.6% of the respondants consider themselves "web developers", it turns out that Javascript usage is going strong.
It is the opposite result that would be surprising.
Javascript isn't eating the world, it's just escaping from its multi-decade browser-only shackles and spreading its wings, which means JS is moving into some niches it previously had no access to. From 0, there's nowhere to go but up! If you're a primary-JS developer it may feel like suddenly the world is at your command, compared to where you could take your skills before. But it's not eating the world and it's not going to, because there aren't any niches anymore for it to conquer that aren't already colonized by other quite good competition. JS itself is nothing particularly fancy next to Python or Ruby. And there are a lot of very important niches that are simply unavailable to it.
If Javascript were something other than a fairly standard dynamic scripting language, it might find itself with some new opportunities. But it's not, and while it was locked in the browser, the other dynamic scripting languages pretty much took over everything that a dynamic scripting language can. I'm sure JS will develop parallels to some of that stuff, it already has, but it isn't going to be growing into uncontested space.
What you build is infinitely more important than what you built it with. If someone writes a better Google the users won't care if it's using Javascript, Rust, or QBasic. They'd still be all over it.
I haven't ever written professional software, but I just took a software engineering course and what I learned is that what technology stack to use is none of the clients business.
I just wanted to share this because I find it amusing til the moment that client went with another company that had "patent pending tech" and AI, it was sad because I knew the other company was just a couple of guys loading data.
I guess the lesson is that sometimes it's hard for people with a technical background to sell because we usually don't "hype" our tech.
ARG! The floating point handling in JS bites (bytes?) me almost daily. I code in JS every day but I hate this number "bug" the most. Having to frob back and forth with "int" to make it not totally broken.
I think this is more reflective of the shift in how code and development teams are being organized rather than JavaScript "eating the world."
Now that many shops have separate back-end and front-end focused teams, a lot of API development is moving to node so that the front-end focused JS developers can maintain the APIs they consume themselves.
Also, while languages like Java are very good at helping large teams manage equally large codebases, deploying microserves and organizing code into smaller-more self-contained pieces make it easier to use things like javascript for individual services.
Reminds me of a 'future' talk about how JavaScript took over the world as a language even though no one actually programmed in. This was because as long as you could transpile to ASM, you could get native performance via JS.
I think it's interesting in its own right to point out that the trendy editors of today implemented in JavaScript are able to edit (and even view) files larger than about a megabyte because they are not any more fully implemented in JavaScript says something – and I'm of course not talking about the framework.
Because it's not opinionated, it all depends. IMO the code base where I work is very complex but it's very easy to onboard new engineers with it. This is due in part to enforcing documentation and code style guidelines.
I think static vs. loosely typed both have their pros and cons but that's the thing that's great about the Javascript community. It's not opinionated on things like this. So if you want statically typed, then you can code in Typescript.
This is in contrast to something like Rails which is super opinionated and doesn't give you much of a choice if you as a developer or even as a company as a whole were to disagree with these opinions.
Also rails is not a language, it is a framework, aka an opinion. Languages should lean towards being opinion agnostic while frameworks by there very nature should be opinionated.
Other than their front-end build process, Node is also used in their user-facing servers. Basically, when your Netflix app makes a HTTP request to fetch any data from its backend servers, the request first hits a Node JS server.
Netflix is behind and uses Falcor(1) for data fetching as an alternative to REST. The backend for this is in Nodejs(2). (There could be other backends in Java too though)
Netflix uses Node.JS in the build process for their frontend. They also use React.JS inside of one of their TV applications, using a custom renderer (that isn't backed by HTML.) They are definitely heavy users of JS.
When people say they use Node for frontend, it generally means for things like Webpack or Gulp, not something running on the end user's computer.
What they don't say in this panegyric to node is that..
1. The language (js) is absolutely horrific.
2. node is single threaded and non-blocking/async in I/O for some operations but when blocking requires libuv and gymnastics.
3. It moves too fast for stability. I've encountered huge memory leaks with node at various versions that are terrible to debug.
4. It is designed to the lowest possible specification for development: web developers.
5. js package mgmt and build tools are a running joke.
Sorry to offend but if you are seriously considering js on the backend then it becomes a valid concern. I don't want a meta-tag junkie with the ability to craft massive markup via whatever interface and IDE deciding what systems behaviors should be. That does _seem_ to be where we are going these days.
There are languages that I like better than JS. However, JS servers power trillions of dollars of business. People who grasp for reasons to hate on JS are a little like people who get into flame wars about video game franchise rivalries. It's symptomatic of deep unmet emotional needs in that person's life.
> It's symptomatic of deep unmet emotional needs in that person's life.
Pretty sure pronouncements like that are the real indicator of unmet emotional needs.
The way this community needles dissenting opinions needs to change. If you don't like the HN flavor of things, the resulting swarm of nitpicking, self-righteous commenters blots out the sun.
Is that really what you're seeing on this thread? Whinging about how horrible node.js and how horrible it is that we're all forced by the government to use it, is the conventional wisdom on HN. A few people disagreeing with CW is not "this community needles dissenting opinions".
Eh, scroll through the comments in every submission that mentions JavaScript (like this one) and you'll see a bunch of people lambasting anyone that uses JavaScript.
"Ugh, why would anyone use it on the server? Idiots!"
"Lol web developers only know one language. Sad!"
As if anybody that chooses a different set of trade-offs is incompetent, not just comfortable with a different set of trade-offs.
That's really very arogant. If people don't like JS, there's something wrong with them emotionally? Jesus wept!
I happen to think there's nothing wrong with being annoyed that in the biggest marketplace in modern IT - the Web - we have ONE option for programming solutions. One! As engineers, I don't think it's unreasonable that we should be able to choose the best tool for the job, not the only tool for the job. That doesn't mean that JS is useless (or that I have emotional problems) but that other languages might be better suited to various tasks.
That seems to a me a plain and uncontroversial statement that doesn't require positing mental defects to explain people who disagree with you.
> People who grasp for reasons to hate on JS are a little like people who get into flame wars about video game franchise rivalries. It's symptomatic of deep unmet emotional needs in that person's life.
To the extent that that's true, I'd say it's equally true of "here is this list of companies that use my preferred tools" articles like this one.
I don't care much what websites use on their back end servers. As long as it keeps my data secure. But my interactions with JS on the front end are almost always unpleasant, so it's hard to be happy seeing JS succeed and proliferate in general.
Why would you ever use the word 'panegyric' instead of article? Maybe you like to purposefully complicate things so that you can maintain your elitism? This might be related to your dislike of JS.
npm and the huge number of dependencies scares me, I remember in WordPress plugins would get hijacked and you would get an update that backdoors or inserts some vulnerability, other than this, I spend 3-4 hours 2 days ago, trying to merge 2 json datasets by doing some averages, and simply could not do it, the numbers were in string format, and it would work for some and get NaN for other, or would just concatenate them as string, I was working in typescript and using "number" was concatenating, weirdest thing ever, I just gave up.
My personal opinion is that what applies to big companies offering "free" products applies in tech as well.I call it the good enough concept.
The product is not exceptional but it is good enough when you consider all things involved (price in case of big companies (it being free) and performance in case of javascript.
So for a lot of people web apps are good enough. They do not need native apps. The same applies to developers. Sure you can avoid transpiling to JS but JS also became good enough for people to just stick to it. And while they were at it they found out it is also good enough on the backend (nodejs) and on the mobile (react native) and also on the desktop (electron).
Only time will tell if it is or was the right choice.
Sorry to say this, but this kind of statements don't really add anything to the discussion. _Only a sith deals in absolutes_.
Recently, JavaScript has adopted lot of language feature from C#, Ruby etc., that make it really useful for most common tasks. And the community moves really really fast, hence adoption of new language syntax is quite fast.
JavaScript has some killer platforms / apps, that are being used in production by high-traffic companies.
You can do cross-platform Desktop app in Electron (Slack, VSCode, Atom etc. are written with this).
Front-end build tools are written in Node JS, and they do lot of heavy lifting as well. Babel is a transpiler, Webpack is a bundler.
These days, native mobile apps (not hybrid apps) in JS are also gaining traction, via React Native.
From open source communities to big behemoths are behind this.
I would like to hear what about JS turned you off so much?
> Recently, JavaScript has adopted lot of language feature from C#, Ruby etc., that make it really useful for most common tasks. And the community moves really really fast, hence adoption of new language syntax is quite fast.
I wasn't aware that a platform's ability to move fast was now a feature. Sounds more like a moving target, honestly.
I want stable tools that let me do things quickly. In the current JavaScript ecosystem, you have the "do things quickly" part without the stable part. It's really easy to get bogged down in the mud. My guess here is that with the increasing industry tendency to move on every <2 years, everyone is building their shaky house and then getting out before it crumbles with them inside.
It is an interesting example of how a camel is a horse designed by committee.
And basically the reason we have JS is because we can't agree on anything else. So JS is what we've got.
But you should take JS seriously, because it's what we've got. It's not going anywhere. And it powers the Internet. And for right now the Internet is the end all, be all, technology.
It forced a lot of very smart people and a lot of eyes onto the platform to try and find solutions within the extremely restrictive "box" to these problems.
How do you solve the API issues when you don't control the platform?
How do you solve for perf when things can't be installed?
How do you solve the API when you can't force people to upgrade?
How do you solve the language when you only have one language as a compilation target?
Out of these we got React and other vdom style view layers. FP paradigms got into the mainstream.
It exposed the mass to newer type system features
We got a toolchain that while complex, can do almost anything.
We got some test tooling that are ahead of other mainstream languages.
And every last bit of these went through tons of iterations (sure, javascript fatigue, whatever), and have had an immense amount of eyes on. You totally can look at any of the things I pointed out and say "Language X did it first!", but no one forced Language X on so many people, while JS was, so these things got a lot more exposure.
In short, I love the JS ecosystem precisely because it sucks so much.