Hacker News new | ask | show | jobs
by gaigepr 4441 days ago
"...but nothing beyond that. As long as Node.js exists in this world, I can't truly hate anything else."

I found this hilarious. I am also rather underwhelmed (to be nice) with Nodejs and a little bothered at its wide adoption.

I have also been learning racket recently; my formal language and functional programming class uses it. I had some previous experience with common lisp but the raw nature of scheme still pleasantly surprised me a little bit.

EDIT: From what I remember, javascript was "inspired" by scheme. Obviously that when well...

3 comments

I keep flipping back and forth, thinking I don't get it, then thinking others don't get it. Single-threaded JS with callbacks. OK? What am I missing?

The only thing Node has going for it is a lot of networking libraries. It's not fast, the async style leads to callback hell, JS is a terrible language, and their package management system is slow and bloated (or at least the packages are)[1]. Yet people think it's some new kind of thing that's just so awesome, despite MS doing server-side JS in the mid-90s.

Sure, people can use whatever makes them happy. I'm just confused as to why anyone is particularly impressed with Node or JS.

1: Seriously, to automate builds, I ended up saving the node_modules directory then symlinking it in to the build environment. Otherwise a simple CSS/JS/etc. grunt build took 15 minutes instead of 1. And it seems every module pulls in its own copy of dependencies, so you end up with 300-character deep paths. There's no apparent reason it needs to be like this.

Straight from the horse's mouth:

"Node is popular because it allows normal people to do high concurrency servers. It's not the fastest or leanest or even very well put together - but it makes good trade offs in terms of cognitive overhead, simplicity of implementation, and performance. I have a lot of problems with Node myself - but the single event loop per process is not one of them. I think that is a good programming model for app developers. I love Go so much (SO MUCH), but I cannot get past the fact that goroutines share memory or that it's statically typed. I love Erlang but I cannot get the past the syntax. I do not like the JVM because it takes too long to startup and has a bad history of XML files and IDE integration - which give me a bad vibe. Maybe you don't care about Erlang's syntax or static typing but this is probably because you're looking at it from the perspective of an engineer trying to find a good way to implement your website today. This is the source of our misunderstanding - I am not an app programmer arguing what the best platform to use for my website--I'm a systems person attempting to make programming better. Syntax and overall vibe are important to me. I want programming computers to be like coloring with crayons and playing with duplo blocks. If my job was keeping Twitter up, of course I'd using a robust technology like the JVM. Node's problem is that some of its users want to use it for everything? So what? I have no interest in educating people to be well-rounded pragmatic server engineers, that's Tim O'Reilly's job (or maybe it's your job?). I just want to make computers suck less. Node has a large number of newbie programmers. I'm proud of that; I want to make things that lots of people use. The future of server programming does not have parallel access to shared memory. I am not concerned about serialization overhead for message passing between threads because I do not think it's the bottleneck for real programs." https://news.ycombinator.com/item?id=4310723

> The future of server programming does not have parallel access to shared memory.

Yeah but it could be IO parallelism. There could be two instances of callback chains of sequence C1->C2->C3 started such that the the second starts before the first one finished. As in C1->C2 ran then C1 gets called again. If in those callbacks you update a data structure (a database record?), you now accessed that data in parallel. So you have to protect against that with some kind of a lock/mutex. Yeah context switching doesn't potentially happen at every assembly instruction, the granularity is much higher, but it is still there.

There's some need to synchronize, but hot damn is it simpler when you're dealing with sensible blocks of high-level statements than when you're dealing with out-of-order parts of assembly instructions.
That's true, but personally I still don't find this model ideal because the synchronization points are implicit. The cleanest concept I know of for dealing with synchronization is transactions.
If you don't want shared memory... then don't use it. Other languages are not stopping you from copying objects and using a message passing system.

And it seems rich to complain about syntax when the language of choice has "function" as it's lambda operator.

Such a wonderfully confusing and self-contradictory quote. I love it.
Why do you think it's self-contradictory? I found it fairly stable.

I think the most important line for me is about wanting computers to be like lego blocks. I think that's an admirable goal and I think that if Node as a community of programmers and projects owned that more ("We're Mindstorms, not NASA, here!") it'd get a great deal of love from the rest of the community.

Sadly, that probably won't happen since Mindstorms sounds diminutive and no collection of people has an ego so in check.

Here are some of the bits I read as inconsistent.

"Node is popular because it allows normal people to do high concurrency servers." vs "If my job was keeping Twitter up, of course I'd using a robust technology like the JVM." ==> So Node is not actually good for high concurrency servers?

"I want programming computers to be like coloring with crayons and playing with duplo blocks." ==> The wonderful wonderful thing about Duplo is it composes. Continuation-passing style (i.e. callback hell) is the paradigmatic example of a non-compositional whole program transform.

"Node has a large number of newbie programmers." vs "Node is popular because it allows normal people to do high concurrency servers." ==> Newbies are writing high concurrency servers?

"I'm a systems person attempting to make programming better." and "Node is popular because it allows normal people to do high concurrency servers." vs "If my job was keeping Twitter up, of course I'd using a robust technology like the JVM." ==> If Node isn't actually good for its intended use case how exactly are you making programming better?

I guess that I don't feel these so painfully because I don't think Node is necessarily successful at it's goal, though I believe its goal is admirable. CPS might not be the most elegant way to schedule threads, but it is fairly simple which is one kind of boon.

I'm also pretty sure that high concurrency means a variety of things allowing a distinction between Node High Concurrency capability and Twitter High Concurrency need. If Node allows newbies to achieve higher concurrency than other newbie tools (PHP, Rails) then I think it can achieve that task to some degree.

> I am not an app programmer arguing what the best platform to use for my website--I'm a systems person attempting to make programming better.

What is a "systems person", in this case? I guess it makes sense if you know who it was who said this, but I don't. Is it a programmer working with code for servers?

> I'm just confused as to why anyone is particularly impressed with Node or JS.

Low barrier to entry means anyone who used to animate jumping monkeys on webpages and now write distributed back-end systems (all web-scale of course).

Kids haven't seen anything else. Maybe took C++ or Java in college, then they see a kid with piercings and a messenger bag and tight pants talk about this awesome asynchronous callback-futures-based awesome frameworks. There is really nothing to compare it to. So they are impressed.

Next level up, write a benchmark. Compute fibonacci, compare with Java, hey not too bad. Even faster than Ruby! Clearly this is the framework of the future.

Maybe read some place about how threads are bad and callbacks are great. And so on.

> so you end up with 300-character deep paths.

Hehe, too funny. Actually it just needs to be 260 characters, so 'git checkout blows' up on your unfortunate colleague who happens to use Windows.

=> Low barrier to entry means anyone who used to animate jumping monkeys on webpages and now write distributed back-end systems (all web-scale of course).

There is nothing distributed about Node. It has IO concurrency, that is all.

I was being sarcastic ;-)
You got me!
My theories:

1. Using the same programming language on both sides of HTTP often appeals to a developers visceral sense of elegance, or tidiness, even though it this alone inherently solves no existing problems.

2. It's powered by Googles V8 engine, which means people already associate it with this "super fast JIT" thing that lives in their favourite browser. It must be efficient, right?

3. The crowned alternative is PHP which is slowly becoming Java and alienating, with no disrespect to anyone intended, the less experienced, the "let's just hack a script together" crowd.

1. There is a concrete advantage of shared code.
There are multiple concrete advantages.

I've recently worked on a few web apps which use ClojureScript/Clojure on the the client/server. Prior to that I mostly worked on web apps that were CoffeeScript/Python.

The first difference I took note of was how easy and seamless it was to move EDN structures back and forth between the client and the server. Of course this is a pretty minor difference as it's not exactly hard to pass JSON back and forth from CoffeeScript (or Javascript) to Python.

But then I started using Prismatic's Schema library. Schema is essentially a lightweight (gradual/optional) type system. Schema is written in cljx which means it works with both Clojure and ClojureScript. This means I could write my schema definitions once (also in cljx) and use them on both sides of the pipe. Schemas end up being similar to class hierarchies in an OO language. (So, for example, in one project I had a User schema and a Project schema and Project's had an "owner" fieldthat was a User, etc).

This ended up being really nice because now I still get the full dynamicity of Clojure(Script) but everywhere that I'm dealing with these core "types" I can validate the schemas. So I validated them going in/out of database access functions, I validated them going in/out of the server, in/out of the client, in/out of various specific functions on both the client and the server, etc. Wherever it made sense.

Of course in my old CoffeeScript+Python days there was nothing stopping me or anyone else from writing something like Schema and implementing both CoffeeScript and Python versions but it would be a lot more work upfront and in perpetuity to maintain 2 versions. But be that as a it may, for whatever reason, this type of tool doesn't actually get created that often in more heterogenous environments. (And I would argue they on balance, not as powerful/effective/simple/etc when they are created in those environments).

But honestly, for me personally, I think the biggest benefit of using a single language is just the reduction in mental baggage and context switching you have to deal with. I never found CoffeeScript+Python (or Javascript+Ruby or Javascript+Java or whatever) particularly challenging or wearisome while I was working with them, but having now accumulated a significant number of hours on the ClojureScript+Clojure combo it's very noticeable when I go back and work on old heterogenous projects.

Of course the plural of anecdote is not data, and my experience is definitely biased by the fact that Clojure and ClojureScript are just such a pleasure to work with all around. In the end though, while I'm not personally a fan of Javascript or Node.js, I now fully understand why the people that like Javascript love Node.js for giving them the gift of single language development.

Technical nitpick: Schema does not implement a type system of any kind, but instead a contract system. Typed Clojure would be a type system.

Outside of that (+1) because yes, I completely agree.

Which you can get with far better platforms and languages that compile to JS.

And a lot of the use cases aren't sharing code or even have a client/server setup. Like crappy non-parallel build systems being written from scratch using Nodejs.

This thread's been a bit illuminating. I guess I'm not missing anything technical. Some people like JS I guess and Node exists so why not use it.

How does one share server HTTP-serving code and client DOM-manipulating code?
Facebook's React lets you write DOM rendering code that can easily run on both client and server. The framework discourages DOM manipulation, instead promoting a near-declarative style of stateless rendering. Updates to the client DOM are then done by efficient tree diffing. It's very nice.
Most likely by abstracting both into business concerns which appear in the client (manipulation for implementing a UI) and the server (manipulation for persistence and client-to-client communication).
There's a library called browserify that does it. It's not useful for direct DOM manipulation, but there are other libraries for which it is nice.
You only share the data model between the server and the client.
PHP best practices might be becoming like Java, but the language is far, far, far from anything close as far as I can see.

Again, as far as I can see it's as simple to hack together a script in PHP as it ever was. What's changing about the language that makes it more like Java?[1]

1. I tried and failed to make this sentence seem as non-passive-aggressive as possible. I'm genuinely interested, as it's not something I've come across and I'm by no means a PHP expert.

Last I looked it was class definitions and access modifiers that made it look java-esque. I'm not in the know however.
It's popular because people think other people think it's popular.

There's no accounting for taste, but, it won't last. :)

Javascript is fast enough to be usable on a server, Javascript has grown client-side, and you can share code across both. That adds up to something at least reasonably useful and unique.
Not sure what you're saying with this? That they're fairly equivalent except when you need heavy regex jiggling?
Yeah, but I've basically never seen anybody suggest that Racket is a great language for prod.
Naughty Dog has used Racket as a scripting language in several of their video games for the PS3.
Slightly misleading, they don't actually run Racket on the PS3. IIRC, they created a DSL for game logic in Racket and wrote a special compiler for that DSL.

That's still a good example of a "real" program written in Racket, but it doesn't prove that Racket is a good choice for programs that need all the resources they can get.

Ah, I didn't realize that. Very interesting.
Also, Hacker News is written in Arc, which runs on the Racket runtime. It handles quite a bit of traffic every day.

It's an ugly-ass buggy website, but that is largely to do with the implementation and PG's propensity for live-modifying production sites in the REPL and not the runtime itself.

The one good thing about the packaging system is that each dependency is its own version, so you can easily load different versions of the same package.
I'd have to check again, but I looked for specific versions of a JS file and found it repeated multiple times throughout the forest of node_modules.

If side-by-side is desired, then just suffix the folder with a version name. foo.js-1.1 and foo.js-1.0 can be in the root and reused by every package that needs either.

Maybe it does that and I didn't understand what I was looking at.

It's quite naive about it, so it will copy them over and over again. Supposedly there are tools that make everything in node_modules symlinks to the same files.

It's not exactly an advanced and polished system, but it still has a feature that is hard to get with others.

I also hate NodeJS for its package manager, NPM. I don't understand the way it manages dependencies and their folder. What the hell is 'node_modules/express/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/node_modules/debuglog/'.

As a result, when updating dependencies with npm, a same dependency is downloaded multiple times.

That is a good thing when multiple libraries you depend on depend on different versions of some other library.

See http://blog.izs.me/post/1675072029/10-cool-things-you-probab...

It solves the nasty versioning issues that plague the other package managers like pip and rubygems.

Every package gets the correct versions for all of its dependancies at the cost of taking more hard drive space. Hard drive space is ridiculously cheap so it's a good trade off.

I wasn't going to bother reading the source article, up until I saw this excerpt in your comment. Now it is added to my reader. :-)