Hacker News new | past | comments | ask | show | jobs | submit login

There is an easy sense of superiority that comes with derision of "X" and the authoritative sounding romanticization of idealized "Y" seemingly adds weight to the argument. Clearly these "Y" people are smarter and better than all those "X" people.

Look at all this horrible code! So sad that all these people are not as smart as me. Look at this horrible language! So sad the people that created it are not as intelligent as me!

Really? There is no more "problem" with Node.js than there is a "problem" with any other platform. There is no more problem with JavaScript/ES-(name your flavor) than there is with any programming language. Different languages are different. Different platforms are different. Of course every system has its own problems. Sometimes people who appreciate them call these "tradeoffs" or the superior types call them idiotic.

The cliche´ of hacker news haters is really really really getting old. So here are some things that are actually good.

As much of a pile of hot steaming code as it is, Babel as an idea (AKA transpiling one language to another) is pretty cool. Of course you can do this in other places but its featuring prominently in the JS community leading to an interesting result. The language and its features become configurable, easy to adapt and change and evolve over time and suit to your liking. This is interesting!

Finally as opposed to what others may have said about the community being childish I have found the opposite. I find it to be very welcoming and supportive, friendly and honestly creative. Of course there are lots of negatives, lots of horrible code, lots of mistakes happening. But what is missed in all of this? Theres A LOT of stuff happening that is good even great! It's beautiful chaos! So go on hating, but I see lots of great stuff out there. As one great systems and iOS developer told me the other day "Have you tried Express? Its awesome!" HA yeah. But he just tried it, and loves it!

Oh but look at that callback YUCK! Cmon




No, I think criticism is a good thing. Rants are good. They highlight issues with our current tools and over time that's what leads to progress. Using a plow isn't just different from digging in the dirt with a stick. It's better.

For instance, nulls are clearly a problem. After countless rants we're seeing languages that have better ways to deal with missing or optional values enter the mainstream (Swift, Scala, Rust).

J2EE's original idea to configure a system through separate XML files was heavily criticised for being too bureaucratic. After countless rants we got configuration by convention, better defaults and annotations as part of the source language.

Of course progress is not a straight line and quite often it's not clear what is and isn't progress because there are many trade-offs. But where would we be without a constant process of criticising our tools?


Totally not against solid critique. But it becomes a culture, a signal of intellectual superiority. Which is too easy. You can be, and I have been highly productive in plain ole JavaScript. Same with Java, Same with Ruby, same with Python. Are the language debates irrelevant, absolutely not. But “Node.js is one of the worst things to happen to the software industry” Hey if it is then I fully submit that I'm just some stupid fool that should rage quit the internet and give up because.... Wait no that would be stupid.


Instead of responding to the fact that JavaScript:

1. Has no adequate threading model.

2. Has no reasonable type system.

3. Has better alternatives on the server side.

...you're making it personal, and about the people. Look at your post; you're just accusing the critics of Node of feeling "intellectually superior". That's just an ad hominem attack. And you think that critics want you to rage quit the internet and give up? No, that's not what critics of Node want. Or at least, that's not what I want.

What I want is for people to either acknowledge the problems with Node and fix them (unlikely), or start using better alternatives on the server side, and start investing more in WebAssembly and langauges targeting WebAssembly, so we don't have to use JavaScript any more. I want this because as long as Node/JavaScript are around, I have to either deal with those horrible tools, or not take those jobs.

This isn't about feeling superior, it's about improving my life by using tools that aren't godawful.


1. For an async-first environment, which node mostly is, lack of threading is hardly an issue. Only threading node should ever have is the web worker w/ shared memory & atomic ops that’s already going into the Web Platform[1]. I say this is an advantage.

2. Typescript is great, it even has strict null checking via union types. Way better than the half-hearted attempt at optional typing you’ll find in Python 3. So if you think Python is a good ecosystem, then node is miles better. Sure, it’s not Scala, but on the other hand interop w/ Javascript and Web Platform is seamless. It’s a trade-off, but one that I think is very much worth taking. Also it compiles in seconds, not hours.

3. You can share code w/ client which is actually useful considering web app logic is moving client-side. See: React.

4. WebAssembly is nowhere ready. No idea if using it/tooling/debugging will be any good for anything other than what emscripten enables right now. It’s a very risky investment to be considering that early.

Even if you think WebAssembly will pan out, the languages that will target it already target Javascript. It’s just alternative bytecode, really.

[1] http://tc39.github.io/ecmascript_sharedmem/shmem.html#Struct...


1. There are two built-in solutions to this (as well as a slew of other solutions in modules), the cluster module and the child process module: https://nodejs.org/api/cluster.html and https://nodejs.org/api/child_process.html

2. JS's duck typing is thought to be a "feature" to some and a "bug" to others, so if you think it's a bug, use TypeScript or Flow. They'll give you "reasonable type system[s]"

3. Nice opinion


> 1. There are two built-in solutions to this (as well as a slew of other solutions in modules), the cluster module and the child process module: https://nodejs.org/api/cluster.html and https://nodejs.org/api/child_process.html

Process spawning and threading are two different but related mechanisms. The former is much more expensive and hard to use with optimization techniques like pooling. It also forces message passing for IPC rather than shared memory.

> 2. JS's duck typing is thought to be a "feature" to some and a "bug" to others, so if you think it's a bug, use TypeScript or Flow. They'll give you "reasonable type system[s]"

Nothing that transcompiles into JavaScript can fix JavaScript's lack of a native integer.


Not that this should be necessary, but it'd actually be pretty simple for a compiler to fix #2: transform `const i: int = 3;` into `var i = new Int32Array([3]);` and change future references from `i` to `i[0]`.

No clue what the performance implications would be for really heavy uses of this, but it'd at least be a workable solution if you absolutely required a true integer type at run-time.


asm.js has valid, correctly-behaving integers, and asm.js works correctly on non-asm.js-aware implementations, so the lack of a native integer doesn't seem like a problem.

The emitted code might have lots of "|0"s in it, but I don't see many people complaining about the beauty of their C compiler's generated object code and the lack of native anything-other-than-integers.


> The emitted code might have lots of "|0"s in it, but I don't see many people complaining about the beauty of their C compiler's generated object code

What are the performance implications of that? It's basically adding an extra operation. Also, having been one to dive into intermediate assembly from time to time, there certainly are people who complain about the obtuseness of object code. Particularly since the generated object code is (out-of-order execution notwithstanding) how the CPU is going to actually execute the instructions.

> the lack of native anything-other-than-integers

Um, what? C has native floating-point types on every platform with an IEEE-754-compliant FPU, and probably on some that don't as well. Pointers are also not integers, though bad programmers frequently coerce them into such because most compilers will let them.


Regarding "|0", there are absolutely no performance implications. An ASM.js optimising compiler will recognize these code patterns and interpret them completely differently (it will not execute a bit OR operation, and instead will only treat |0 as a type hint)


If you assign only 31 bit integer values to a JS variable, it will be treated by V8 as an integer (small int, or SMI)


> Nothing that transcompiles into JavaScript can fix JavaScript's lack of a native integer.

Really, who cares? Types are important for the programmer not for the compiler. If I know what I'm doing then lack of ints doesn't concern me.


There are certain classes of programming and mathematics that really need integers such as cryptography and fields that would need big number libraries.


That's totally valid, but they shouldn't use Node.js if that's a mission critical part of the project. Nobody is saying that Node.js is the holy grail, but I see that expectations are that high.


>Has no reasonable type system

I'll bite on this. Javascript's type system is with no question my favorite part of it! JS's object model is incredibly powerful, which is why ES6 classes are implemented basically as syntax sugar, and why so many languages can be transpiled to Javascript.

I also don't think that the lack of threading is as much of a problem as you might think it is. For one, it means you can sidestep a lot of the data ordering problems that you get in a threaded environment.

There's no question that Javascript has shortcomings, but so many of the problems that happen in Javascript come from people treating it like Java, when it's a lot more like Lisp. In many ways, the architecture of Javascript revolves around a very simple, powerful object model in a way that's tough to parallel in most other languages.


I'm guessing he mean't static type system. This is the formal meaning of "type" in programming language theory. What you describe is a system of runtime tags.


Completely agree.

I'd actually like to list the worst things (IMO) to happen to the software industry.

(1) Marketing of computers at boys resulting in a generation of girls being excluded. (2) Software patents suffocating innovators. (3) DMCA & international equivalents (4) Daylight savings time. (5) A generation of programmers being taught that anything other than "OOP best practice" was heresy

I'm sure there are plenty I'm missing.

Does one particular programming environment deserve to be listed with that stuff? Personally I think it's a pretty ludicrous suggestion.


> (4) Daylight savings time.

It's always annoys me whenever programmers complain about time zones and daylight savings time, because of the difficulty and inconvenience handling them in software. It's getting things backwards. Software should model the (human) world* ; the human world shouldn't be changed to model what's most convenient for software.

* That doesn't mean you can't have a simpler model that you translate to/from.


> Software should model the (human) world* ; the human world shouldn't be changed to model what's most convenient for software.

Agreed, but my point is that daylight savings time is a huge human-world complexity that brings a marginal boost to some sectors. There are a ton of negative effects and I question whether there's a net benefit, even before all the software complexity needed to support it.

https://en.wikipedia.org/wiki/Daylight_saving_time#Dispute_o...


Oh man, "OOP as gospel"... If there's one thing that I like about Node.js, it's that it made me actually think about when I should take an object oriented approach vs a functional approach.


Daylight savings time? What's the connection to the software industry?


Dealing with time-zones and daylight savings time (which countries have it and which don't) can be a very challenge and messy problem that is really easy to get wrong.

Heres a pretty good video from computerphile on the subject https://www.youtube.com/watch?v=-5wpm-gesOY


Won't most mainstream languages have a built in library for that sort of thing these days?


Most do, but the problem is less about the library and more about understanding how to use it.

For example, if you want an event to happen in 12 hours, and it happens to be 9pm the day before daylight savings time, do you schedule it using the timezone-aware API (so it happens at 9am, which is actually 13 hours away) or 8am (which is 12 hours, but non intuitive)? What about the event that's supposed to happen every 12 hours in perpetuity?

What happens when the user/device is mobile, and crossing timezones? Which times do you use?

What happens when you're scheduling something far in advance, and then the timezone definition itself changes (as happens a few times a year) between the time you scheduled the event, and the time something actually is supposed to happen? Does the event adjust for the new definition or follow original time?

Luckily for many problem domains, the details around this don't matter too much, but this is just the tip of the iceberg with timezone challenges.


The libraries don't really help with some issues.

E.g. a rather trivial example of displaying a hourly graph/table of some measurement, including comparison with yesterday (because there are daily patterns of fluctuation).

DST means that some of days have 23 hours and some days have 25 hours. The libraries will help you make the relevant calculations, but now you have to make a decision wether the comparison that you make with "yesterday equivalent" of today's 11:00 is yesterday's 11:00 (23 hours ago) or yesterday's 10:00 (24 hours ago).

For another example, accounting of hours worked - you may have a person that has worked 25 hours in a single day, such events break some systems.


They do. The problem is that the rules of DST change over time (sometimes at the very last minute https://github.com/eggert/tz/commit/868f3528a9fd60491439ce45...) and can lead to all sorts of date math bugs when comparing timestamps across timezones.


A lot of them are... not great. Moment.js makes it somewhat bearable in JS, but the native stuff is hot garbage.


Spring forward, fall back!


But not every country or even every part of every country...


DST adds complexity to the already ugly mess timezones are. Timezones are literally driven by real-world politics, and they can be as messy as only humans can invent.

See also: http://naggum.no/lugm-time.html


As well as adding to the already-confusing mess of timezones and date calculations, daylight savings can change frequently, and sometimes at very short notice.

This year, Azerbaijan decided to cancel DST, and agreed the cancellation just 10 days before the scheduled clock change [1]. Egypt cancelled DST with even less notice - just 3 days! [2]

[1] http://www.timeanddate.com/news/time/no-dst-azerbaijan.html

[2] https://www.washingtonpost.com/news/worldviews/wp/2016/07/06...


Hah! You've had a very lucky programming career indeed if you can ask that question in all seriousness.


It has to be accounted for in time and date calculations and that poses a new set of challenges.

It is also just one of many geographical, cultural, and temporal challenges that need to be addressed by any business system relying on accurate international dates and timing.


Time and scheduling are a bit tricky, to say the least. It would help if there were some reasonable assumptions that you can make - for example, a day containing 24 hours. DST makes such assumptions not true.


Wow! You haven't run into DST issues in software yet?! How I envy you! If you work in the industry, you have a lot of fun unintuitive but sort of neat bugs to look forward to!


+1 daylight savings time -- it's behind countless bugs. You can add weird and split time zones to that, too


null?


Yes. Null belongs on any list of things the software industry got wrong.


Should be the first one.


> Rants are good.

Rants get me down. It really is possible to be constructively critical. This author failed.


A good rant should be like political satire, a biting critique using absurdism to highlight the truth of the matter.

A bad rant is usually just impotent rage without wit.


Yeah, but think about how infrequently political satire is actually good and you'll see where some of us are coming from on this.


Have you read the whole page? Just the subdomain is "HARMFUL". The page is a compilation of good and BS critics for any language.


Have to agree (although I'm one to rant)


Rants without proposing any alternative solutions can't redeem any use at all. Their only reason to be is to wrongly make their authors feel smart or skilled.


He proposed list of languages. And really, there's a lot of good languages to use on the servers. JS was never good language and we use it on the client-side just because it's the only language browsers know.


He doesn't explain why... other than ranting about the callback model (which has been in our desktops forever, most event systems rely on callbacks). The quote in the post has also misleading statements, NodeJs does scale in load and performance which is one reason why people use it instead of Python (which was one of the quote suggestions)


That was not one of his suggestions, unless you count stackless python. It was an example (i.e. twisted in python) in support of his point that callback's are a bad way to structure concurrent programming. His suggestions were Erlang and Go which are arguably better approaches in a purely technical dimension to NodeJS.

What his rant misses is that most technical decisions aren't made on purely technical merit for a host of different reasons.


>His suggestions were Erlang and Go which are arguably better approaches in a purely technical dimension to NodeJS.

I would say that it is based on a subset of the technical dimension. Maybe Erlang and Go might have nicer ways to handle concurrency flows but if it doesn't have a library X to communicate with backend component Y then there is a technical reason not to use it.


There is value added in identifying and clarifying a problem. It's partly how we, as a group, find solutions to bigger problems.


Identifying a problem is separate from coming up with a solution for all but the most trivial of problems.


No, J2EE's original idea was to separate wheat from chaff, i.e. good programmers from mediocre ones. Good programmers would then work on containers and mediocre ones would write standardized apps to deploy into those containers, with containers being easily interchangable. In this worldview it's irrelevant whether those standardized apps are developed with lots of XML, or convention over configuration or whatever, because mediocre programmers won't complain.

Now as much as this worldview is flawed, this is just one of the manifestations of an attempt to make software development easier, which is, of course, a noble goal that even Node.js aspires to.


> For instance, nulls are clearly a problem. After countless rants we're seeing languages that have better ways to deal with missing or optional values enter the mainstream (Swift, Scala, Rust).

No they are not. They are a state of an object. What is the problem is a lack of documentation.

One thing I've seen coming up, at least in some code I've looked at, is the @Nullable and I've not seen any complaining about null from those who use this tag.

The idea is to always document when a variable or type can be null. This way you know, with 100% certainty (given a strict type system adherence) that you're not going to erroneously see a null object where it isn't expected.

From this, you have a huge benefit: a performant error state or a better method of representing an issue without throwing an exception.

Riddle me this, how would a Map be implemented if Null was stripped from Java? Should it throw an exception if a key is not found? If that is the case, then you should always need to check for this exception, otherwise you're prone to bugs. You've also increased the execution time of your code by in some a huge performance hit [0] that is more cumbersome.

This is why I think rants are a big problem. They don't describe the opposition to a statement accurately. They are one person's opinions and after reading them, if it all sounds nice, you're usually willing to take it all as fact. "Hey, they're writing an article! They must be smarter then me. I'll take their word for it." As a result, our communities don't really evolve we just spew memes back and fourth dictating what someone else thought.

What really matters, in every sense, is reading a discussion had between two experts in opposing camps. That way you can see both sides of the arguments, their weak points, and make an educated choice on what side to agree with.

That being said, what do you think of my points? Can you address them? My oppinion is that NPEs can be easily avoided by using very simple measures AND null more closely resembles most problems while being more performant and less cumbersome then throwing exceptions willy nilly. I'd love to hear how you feel about this.

Also...

> J2EE's original idea to configure a system through separate XML files was heavily criticised for being too bureaucratic. After countless rants we got configuration by convention, better defaults and annotations as part of the source language.

I'd say that is a good example of discussion, brain storming, and coming up with a much more accurate representation of the ideas we are trying to convey (the use of annotations to configure methods).

[0] - http://stackoverflow.com/a/299315


The problem with null as implemented is that it type-checks as a value of any type. This means that anywhere you have a value of some type, it may be a valid value of that type, or it may be null. If you think about it, this is very odd. What if the number 42 were considered a valid value of every type, such that it were usually necessary to check whether you actually have 42 before using a value? That seems ridiculous, but it's almost exactly how null works.

I'm someone who uses @Nullable and complains about null, so now you've met one of us! The problem with @Nullable is that it's mostly useful when all your code uses it, but the compiler will not force you to do so. It is a Sisyphean task. (But at least Java has @Nullable - most languages with null don't have anything like that.)

In a parallel universe version of Java with no nulls, a Map implementation would return Optional.<Foo>empty(). This seems similar to null, but with uglier syntax, but critically, it is not of type Foo. In order to get a valid Foo, for instance to pass to a method that takes one, you must unwrap the Optional you have and if it is empty you simply can't call that method with a Foo because you don't have one. The advantage here is that this method taking a Foo now knows for sure it has one and does not need to bother checking that assumption. How pleasant!


> Riddle me this, how would a Map be implemented if Null was stripped from Java?

Obviously you would use an Optional<T> (for a Map<K,T>)

See https://docs.oracle.com/javase/8/docs/api/java/util/Optional...


Which would have been a great idea if it had been in Java 1.0 :-(

Alas, the horse has left the barn.

Much like immutability: if it had been the default, with a "DANGER: mutation ahead" keyword required otherwise, that would arguably have been good. But it's too late, now. (Java) Beans, beans, the magical fruit...


Yeah, it's a bummer dealing with backwards compatibility. Don't get me started on guava Optional vs JDK8 Optional.

But at least you can stick to just using Optional and no nulls in new code you write, and only using nullables to communicate with existing libraries.


I mean when people say Nulls are bad I don't think they necessarily mean they are categorically bad, only that allowing every single object in a system to have a null value without any supporting language features requires a lot of discipline. I don't know anyone that's used something like Maybe[String] and felt it was categorically no better than 'null' values, but on some level they are both features that express the same thing. Just one of them is more coherent and targeted.

When people say that null was a billion dollar mistake I don't think they were referring to any possible implementation of a value that indicates nonexistence.


> Riddle me this, how would a Map be implemented if Null was stripped from Java?

Optionals.


Riddle me this, how would a Map be implemented if Null was stripped from Java?

  map.getOrThrow(key)
  map.getOrDefault(key, defaultValue)


So I can either throw an exception and take a speed hit in my performance critical code or I can remove a possible value from my map?


It's not "removing a possible value from your map", it's having your type system explicitly check that you're handling the edge case at compile time. This works in practice in a wide variety of languages.


Maps should do whatever ArrayList does when your index is out of bounds. And so long as null is a value that could be in the collection, lookup should definitely not return null.

If a lookup fails, it is often a bug or a violation of a constraint that you shouldn't be handling. Throw an exception. If a lookup is expected to fail in normal execution, you can use an Optional to mash together a check and lookup in a typesafe way. Lookup failures should not be allowed to propagate as nulls only to be caught as NullPointerExceptions in disparate parts of the code.


Tony Hoare, the computer scientist who introduced null, called it a billion dollar mistake. He's pretty accomplished in his field, and there are better options than null for signifying that a Map doesn't have a particular value, like Option types.


No, I think the real issue here is people taking languages personally, when there really shouldn't be any reason to. It's very interesting that people form such a personal bond with programming languages, to the point where they will refuse to see how they could be perceived as bad, or cumbersome.

Pretty much everyone does it, myself included, and it's one of the more problematic things when it comes to actually discussing languages. People just won't accept that their "baby" (or pet, as was mentioned below) might just be bad.

While elitism isn't great, not all criticism and ranting is done from a "We're/I'm better than you" perspective and most rants aren't directed at people. The people using language X might feel they are, but that's simply their own insecurity showing. I think a good portion of defensive posts show this fairly clearly.

In the end, is it really that surprising that some of the newer ideas are better than old ideas? Why is it only "fair" to say that a later version of X is better than an earlier version of X, but not that Y can be better than X?


> It's very interesting that people form such a personal bond with programming languages, to the point where they will refuse to see how they could be perceived as bad, or cumbersome.

From what I've seen and personally experienced, this happens most often when someone is only strong in that one language. If you've only ever used that language to build applications and someone comes along telling you it sucks, it feels like a personal attack because it would mean you've been doing things wrong or your code/applications suck. It's part of an identity. As people learn new languages and actually gain professional experience with them, that original language is no longer what defines them as a programmer so they no longer need to defend its legitimacy.


Great post; completely agree. I feel a lot of us associate "things" like programming languages with our identity. So if our identity is attacked, we take it personal.

Generally you'd think new ideas would win out on old ideas. But you hope the new at least learns from the old. No need to repeat mistakes. This is the criticism I usually see from BSDs towards Linux or programmers towards Golang. Not that I disagree/agree, just an observation.


I absolutely agree that lots of new stuff is not necessarily better than the old. Particularly when they end up more complicated than what preceded them. I think maybe I overstated the issue of time (what came before, etc.). I should've written it more generally: "Is it inconceivable that one idea/concept/product/language might be better than another?"


> Really? There is no more "problem" with Node.js than there is a "problem" with any other platform.

While I agree in principle, I've been bitten by some incredibly bad node packaging architectural decisions. Just yesterday I was attempting to install tfx-cli in order to CICD our build scripts to our build server - it went as you would expect with npm: MAX_PATH issues. The git clean then failed on all subsequent builds. A problem became unsolvable by virtue of the platform that was used to write it - had tfx-cli been written in almost anything else, this would not have been a problem (I say "almost" because I'm egregiously assuming that at least one other package manager is also broken in this way).

So there's an example of node-specific problem and there doesn't seem to be any impetus surrounding solving it.

> Oh but look at that callback YUCK! Cmon

In defense of Node, it now supports ES6: callback hell is self-imposed for all new code.


> So there's an example of node-specific problem and there doesn't seem to be any impetus surrounding solving it.

??? There's so little impetus around solving it that both sides(npm and Microsoft) have put in significant effort to do it - npm 3 reduced the chance of having a very large path, and preview builds of the .net file api are removing the MAX_PATH limit.

https://github.com/Microsoft/nodejstools/issues/69

https://github.com/Microsoft/nodejs-guidelines/blob/master/w...


Fair enough, I'd strike-through that quip in my comment if I could. Still, this problem needs a bold/breaking fix. I most likely didn't run into this with my dev-testing because I am on a filesystem with reparse support.


Isn't the max path issue an operating system bug exposed because the tool you were using was designed to run on an OS without that bug?


You can't store an arbitrarily long path regardless of OS. EXT4 only pushes the value to 4096 - meaning that encountering this bug on Linux is only a matter of time. The unreasonably small value on Windows merely resulted in this boundary condition failing sooner.

Code merely pushes electrons around, meaning that it has constraints firmly rooted in physics. So no: NPM runs in a universe (regardless of OS) and fails to account for the constraints of that universe by falling into unbounded recursion far too easily. This could have all been avoided by correctly applying graph theory and/or prior wisdom in regard to dynamically loading modules - which has existed for decades. Now we're forced to kludge it with reparse/symlink and that only works on file systems with these features.


are you implying that design decision is good?


There is nothing wrong with using callbacks. Or promises. Or async/await. Or any other abstraction that makes sense for you.


This is a "writing code"-centric point of view. From the maintenance perspective "you" aren't the only person for whom the tradeoffs of callbacks/promises/async-await matter. It also matters to the people who have to come along years later and maintain the software.

So really it's about what abstraction makes sense for the maintainers as well. Not just you.


> people who have to come along years later and maintain

The problem is there is no way to know years in advance what makes sense for those future people. All you have is current standard at your org and/or common sense. Do what they say.

When you choose what the standard is, select whichever makes more sense at the moment. That is kind of my original point.


You may not know their own personal preference when writing code. But you can know what will make their job easier. Strong typing for instance will make refactoring easier. Good perf tooling will make analyzing performance easier and so on.


> There is an easy sense of superiority that comes with derision of "X"

There's also an easy sense of superiority which comes from being actually superior.

> There is no more "problem" with Node.js than there is a "problem" with any other platform.

Well, yes, there are problems with Node.js, to include the concurrency model and the language — as indicated in the article.

> Different languages are different. Different platforms are different. Of course every system has its own problems.

Yes, every system has its own problems, but some systems have fewer or better problems than others, while others have more or worse.

There are continua of languages, platforms & OSes. JavaScript-the-language is a bad language. It's not as bad as INTERCAL, but it's worse than C or Lisp. Node.js-the-platform is a bad platform. It's probably not as bad as the Java platform, but it's worse than Go. POSIX is a bad OS. Not nearly as bad as Windows or Mac OS Classic, but worse than Plan 9.

One has a very limited number of hours in one's life. Why waste those hours in pursuit of anything other than excellence? Node.js isn't excellent; why spend any time on it?


I agree with the general sentiment, maybe not with all the choices of what's better or worse. And this is where the trouble starts: What is opinion and what are facts?

I also agree with your conclusion that avoiding wasting precious lifetime on shi^Wnon-excellence is undesirable. However, given the first problem I mentioned, one can easily waste just as much time trying to figure out what the excellent things to choose are.


There are certainly languages that are better than others. Some of them excel in a particular domain, others do well in other domains. But in general you can tell if a programming language pushes you to write good code or bad code.


Not every tool is the right tool for the job, and finding the right tool for the job is part of doing the job correctly.

The thing that always bugged me about node is the argument that using the same tools on the server as in the browser is somehow an advantage. That idea is not a given.


> The thing that always bugged me about node is the argument that using the same tools on the server as in the browser is somehow an advantage. That idea is not a given.

Not a given, sure. But there's an argument to be made there, beyond the scope of mere programming, as a web-focused company can benefit from having a dev team that is versed on both frontend and backend.


> Not every tool is the right tool for the job

There are not only two jobs: frontend and backend. Saying X language is good/bad for backend..


You are oversimplifying the situation. I used to be a C++ backend developer and that was our stack because we needed return the response as fast as possible.

Nowadays I work as a backend developer using NodeJs and C#. I wouldn't use any of them for the former job and there are good reasons why I wouldn't use C++ for my current job. So there is such thing as right tool for the job even in one part of a web platform


There's more to computing than just websites.


Sure, but name any specific computing related thing that doesn't categorically reside within either frontend or backend. And don't say Javascript.


What is a "computing related thing"? Do transistors count? If yes, aren't they both front- and backend? What about threads? Don't they belong to both, the frontend and the backend of "computing related things"?

I'm not trying to be obtuse here, I genuinely don't understand your request.


What would you call data science/computational data stuff? Not backend, because you often sit and view the results in your R Studio console or whatever while working interactively. Not frontend because you are often directly mutating data structures and storage.


I'm working on an OCR engine right now. We intend to use it to do capturing of data using a mobile phone, but also to do verification of captured data on our backend server. So is this backend or frontend code ?


What about games? Lots of them are frontend and backend at the same time.


Interesting things aren't necessarily good. JavaScript is very difficult to read and maintain, there are dozens of dialects and versions, npm is a complete mess, it's hopelessly single threaded, and we've arguably hit a performance wall optimizing JavaScript in the general case. It is a necessary evil.

If you're going to address the "haters", actually address real complaints rather than make very vague comments about beauty and forum culture.


No. Some languages and platforms are just plain bad. Not everything is equal. Not everyone gets a medal.

Liking any particular language doesn't make anyone a bad or stupid person though. Nor does preferring another make you better or smarter.


The cliche´ of hacker news haters is really really really getting old.

I don't think your rebuttal of a criticism as exhibiting a hater culture is any less cliche.

Until the disgustingly contrived artificial hype, and regular poorly-founded misguided hype are all derided too, the haters persist to balance the equation.

Or, to rephrase my point in a business-friendly way: garnter_hype_cycle.jpg


So for example, the Javascript rules are no more problematic than the casting rules in other languages, they're just different?


No, like my cat likes to snuggle but sheds and my dog likes to play but poops too much. Either way they both deserve a bowl of water and some food at the end of the day. You can get all pedantic and say cats are better or dogs are better but guess what. I don't care, I just like my pets.


> I don't care, I just like my pets.

Their main purpose is entertainment.

Useful tamed animals like cows or horses are compared on much more practical indicators, and critique of a racing horse that "it's too slow and sometimes throws the racer off on curves" is reasonable.

That's why your pet metaphor wasn't applicable I think. also it involves emotions in misleading way. Programming languages won't feel bad when you don't use them.


It's not all gonna be gold.


> I don't care, I just like my pets.

Sure, cats and dogs are pretty good pets, say cats are Go and dogs are Lisp. That'd make C a ferret and JavaScript an incontinent chimpanzee with rage issues which periodically lays waste to the house, destroying anything breakable and slaughtering everything living.


You don't build projects with your pets.


Hence why it was a metaphor.


A very bad metaphor. You shouldn't build a project for a company, using a certain programming language, just because you like that programming language. It's your responsibility to look for and provide the best possible solution to the client and that must involve picking the best programming language for the job. Of course there can be exceptions when a tool/library/framework is already being used.


I think the point of the metaphor was that 'the best programming language for the job' is often rather subjective.


Oh? Could I subjectivly suggest that Javascript would be appropriate for a system with hard real time requirements or formal verification requirements?

Sometimes using a band saw to conduct brain surgery is just completely wrong.


"often subjective" != "always subjective"

It's pretty clear that COBOL would be a bad choice to write a multiplayer online game, and that JavaScript would be a bad choice for an operating system.

As for the far far more common scenario (the one I had in mind) of choosing whether one of Ruby, Python or Node.js might be better for a certain project, the choice between the three is often going to be fairly subjective. You could solve a lot of problems in all three quite well. Trying to decide which one is objectively the "best" is often a waste of time that could be spent actually solving the problem at hand.


A fairly useless one at that. It plays on the idea that people don't consider technical merit when choosing programming languages and the metaphor did nothing but trivialize the idea of objectively comparing languages and their strong/weak points.


I agree that the metaphor was partially useless (perhaps poorly worded) - but it's not much better to think that the issue of choosing programming languages is purely objective. You could spend a very long time arguing whether Ruby or Python was better for a particular task, when the important thing is either of them will do a relatively good job for the task at hand and be a better choice than COBOL.


The fact that two or more programming languages are particularly suited for a certain task has absolutely no bearing on the general usefulness of having conversations about what languages are good for. It has absolutely no relevance to state that; the discussion didn't become more or less valid by that assertion.

Discussions that are prolonged like that become long because people are not actually being _objective enough_.

If you had an objective discussion about Python and Ruby you would conclude that yes, both of these languages have very broad ecosystems and are particularly suited for scripting (and glue work). Python is better suited for scientific computing, etc.

Nothing about the scenario you speculate about invalidates good discussion about programming languages and I don't know what about the scenario makes you think it does.


> Nothing about the scenario you speculate about invalidates good discussion about programming languages and I don't know what about the scenario makes you think it does.

I agree - nothing invalidates good discussion on this topic. My point is that trying to decide the best programming language for a particular task (or trying to decide why one programming language is ill-suited) isn't something that always needs a perfectly objective answer.


> My point is that trying to decide the best programming language for a particular task (or trying to decide why one programming language is ill-suited) isn't something that always needs a perfectly objective answer.

Ok, I hear that. I agree that you have to find a local maximum to settle at in these things. It's about being reasonable and pragmatic, after all.


If you're trying to pull a sled through the arctic, then you probably want huskies, not chihuahuas.


> Babel as an idea (AKA transpiling one language to another) is pretty cool

As a sidenote, Babel didn't invent compilers (yes, that is what it is called) or DSLs.


Node is very similar to continuation passing style which is used primarily as an intermediate representation in compilers. It's typically considered poor for production code because it's very error prone.


>Really? There is no more "problem" with Node.js than there is a "problem" with any other platform.

Javascript's type system really doesn't stand up well to scrutiny. That's more crucial than you'd think - the type system is the foundation the rest of the language is built upon.

I suspect this is partly why javascript cycles through technologies so often. The foundations are shaky.


It's dynamic typing with a prototype-based object model. This type system tends to be very good at iterating quickly and testing out many alternative approaches to solving a problem without committing to a data representation up-front. It tends to be pretty bad at communicating invariants to other programmers or nailing down APIs for other subsystems to build off.

Small wonder, then, that the Node.js ecosystem tends to very good at iterating quickly and testing out many alternative approaches to solving a problem, and pretty bad at communicating invariants to other programmers or providing a stable API for other programs to build off. You tend to get what you ask for.


The problems with the JS type system has nothing to do with its dynamic typing or its prototype model.

JS has unfortunate implicit type coercions, bad scoping rules (not type system related but still crappy), and annoying tri-value silliness (NaNning all over).

I'm a big fan of prototype OO. JS not so much.


There exist strongly typed dynamic languages that are good at both.


Examples?

If you're about to say one of SmallTalk/Lisp/Python/Ruby, then no, they are good at prototyping but have all the pitfalls of Javascript when used on large teams. If you're about to say one of Java/Go, then no, you give up a lot of prototyping flexibility for their explicitness.


This is exactly the intention of optional/gradual type systems. You can prototype away just as freely as with a purely dynamic language. Then when you have learned enough to be more definitive you can start putting in types. Dart is a good exponent of this (I think). Its a fully dynamic language but the compiler will catch the majority of static type errors (for types you define) and you can run it in checked mode during testing to catch other type errors. Typescript also has optional types (without runtime checking) but when I tried it it seemed to be harder to mix and match dynamic/static.


>Python/Ruby, then no, they are good at prototyping but have all the pitfalls of Javascript when used on large teams.

No, they absolutely don't.

>>> "1" + 1

Javascript: 11

Perl: 2

This is the kind of approach works ok for small programs. Where the code that does these implicit type casts isn't too buried.

When it's buried 3 layers down in a dependency used by a dependency used by a dependency, you want this to happen instead:

Python/Ruby: Type error


... And? That's simply "not having unpredictable type-juggling."

It does nothing to communicate invariants or guide API usage at design-time.

Consider PHP, which does have some of those bizarre and frustrating conversions, yet at the same time it also has stuff like type-hints and interfaces that can be used for design-time checking.


>... And? That's simply "not having unpredictable type-juggling."

Literally what this entire thread is all about.

Lots of languages have this issue and it manifests in the instability and indeterminacy of large scale applications in Perl and PHP much as it does in javascript.

Type hinting is, honestly, a pretty poor way of dealing with the problem of turning "1" + 1 into 2, but that's a separate issue.


> [type juggling is] Literally what this entire thread is all about.

No it isn't, that's just what you've been fixated on. Please re-read nostrademons' post, because you aren't actually addressing the issues they brought up, namely:

> It's dynamic typing with a prototype-based object model. This type system [...] tends to be pretty bad at communicating invariants to other programmers or nailing down APIs for other subsystems to build off.

While it's true that Python "fails nicer" than JS, it addresses neither of those two issues about preventing failures.


While I think that JS's loose typing is a little annoying and certainly isn't what I'd build if I were designing the language from scratch, it just isn't much of a problem for me in practice. Type errors in general (either of the implicit coercion variety or the dynamic typing variety) aren't much of a problem. They rarely happen, and when they do, they usually take all of 5 minutes to track down and fix.

I find that the big benefit of types are in documentation. They are executable, explicit, compiler-checked documentation of the programmer's intended usage. Without this, it becomes much harder to read through and comprehend a large codebase that was mostly written by other people. It becomes even harder to change it.

I like Python, I like Javascript - but they have their uses, and those uses don't include large-scale mature software engineering. I actually argued otherwise for my first couple years at Google (where both are used extensively, though the JS is largely statically typed), but eventually saw the wisdom of more experienced engineers in this, and relegated my Python to exploratory coding.


Java: 11

I guess companies should stop using Java for big enterprise applications with tons of dependencies. Or this isn't a problem because programmers usually know the basics of the language they are using. And if they don't, then that is the problem, not the language.

btw, Python: '1' * 3 -> '111'


   Main.java:17: error: incompatible types: String cannot be converted to int
    int z = x + y;
>btw, Python: '1' * 3 -> '111'

In theory I agree with this but in practise I see this so rarely used it barely matters.


Sorry, I meant "11" (String), same result as with JS.

see here: https://repl.it/Cqeq/0


The python example is not an issue; you're going from string to a longer string, not to an integer.


That's not true, you're going from string _and_ an integer, because '*' is a binary operator. (And it isn't communicative as shown here, which is another 'problem')

But that's not really the point, crdoconnor seems to think that languages should throw an error in cases like this, not just keep the type of the first argument.


dart , typescript, typed/racket ,julialang ?


>There exist strongly typed dynamic languages that are good at both.

What concrete examples were you thinking of? (You didn't mention any strongly-typed-dynamic languages in your replies to the others.)


I really don't think that people have been coming up with new frameworks because you can add [1] to 5 and get nonsense.

Javascript cycles through technologies quickly because web developers cycle through technologies quickly, and they do that because they get to work on greenfield projects with minimal expectation for them to be around in 5 years a lot. Check out all the different server side frameworks and infrastructure components that have been in vogue with web developers over the last decade.

In comparison, people who aren't writing consumer-facing websites and webapps tend to have much more clearly-defined goals, longer lifespans of their apps, and don't often get the choice to use anything but industry standard technology. Because of the slower cycle, there's less opportunity to redesign frameworks and core technologies even when it's allowed.


>I really don't think that people have been coming up with new frameworks because you can add [1] to 5 and get nonsense.

There's plenty more nonsense where that came from. That's just an easy to understand, concrete and obviously stupid example.

>Check out all the different server side frameworks and infrastructure components that have been in vogue with web developers over the last decade.

In python it's mainly been django and flask for a decade. In Ruby it's mainly been Rails.

Why do they have sticking power? It's partly cultural but it's largely because they were built on far more stable foundations.


In web frameworks, over the past decade, we've had various PHP frameworks, Zope, Ruby on Rails, Django, a variety of microframeworks in various scripting languages, Play, node.js+express in a handful of configurations (though generally MVC-ish), and Phoenix. There's very likely more that I'm forgetting.

In deployment, we've gone from SFTP scripts to Fabric-like software to PaaS to configuration management software to Docker, and then it seems every 6 months there's a different preferred way to make Docker do something useful. And of course there's the eternal argument over whether to deploy to VPSes, cloud platforms, or bare-metal hardware.

The "hip" web companies at any given moment - the ones who need the latest and greatest components to impress investors and attract "rockstar" "10x" developers - aren't tied to any specific language. They'll pick whatever was the most popular at the time they needed to pick something. Hence, right now, you have a whole lot of companies building on Golang and node.js, where they'd've been building on RoR five years ago.


Great comment illustrating the big picture of a few years. Now we just have to figure out which of those is the best for arbitrary, use cases with easy maintenance, unlimited scaling, and high availability. Whoever figures that out will finally be "Right." ;)


Is it a tradeoff or idiocy (bad idea)? Clearly you are in the "bad idea" camp. No worries, you can use TypeScript. Enjoy! (edited for clarity)


    > with Babel you can use TypeScript
Be careful with throwing "idiocy" at otehrs when it seems you yourself don't even know what you are talking about. To write TypeScript you use... TypeScript (their compiler).


Thanks the Babel thing was incorrect, Typescript is separate.

To clarify, I'm certainly not implying this person is an idiot. I'm saying, they lean toward thinking that the typing system is more of a bad idea (idiocy) than a valid tradeoff.


Yes, that's accurate.

I don't think typescript is necessarily the answer though. You don't fix the problems caused by weak implicit type casts with static typing, you do it by turning off weak implicit type casting and raising a lot more type errors.


Try to add some counter-arguments instead of just emotions.


Creativity is awesome. But when someone asks you to deliver something, spending all day wading through "beautiful chaos" might not be the best approach. In that case boring is better than interesting, IMHO. The more attention can be devoted to the problem at hand, the higher the chance to get the solution right.


> Look at all this horrible code! So sad that all these people are not as smart as me. Look at this horrible language! So sad the people that created it are not as intelligent as me!

It's not about being smarter; smart people are a dime a dozen. It's about the fact that what happens in the industry happens to all of us. When a large chunk of the industry adopts callbacks as their threading model, that means I have to either work with their horrible threading models, or not take those jobs.

Don't psychoanalyze people who you disagree with; that's just an ad hominem attack.

> Really? There is no more "problem" with Node.js than there is a "problem" with any other platform. There is no more problem with JavaScript/ES-(name your flavor) than there is with any programming language. Different languages are different. Different platforms are different. Of course every system has its own problems. Sometimes people who appreciate them call these "tradeoffs" or the superior types call them idiotic.

This is the favored defense of people whose favored languages/tools are under attack. But this is absolutely not a tradeoff. A tradeoff is when you make a choice that has some downsides, but you get something for it.

With JavaScript in the browser, the tradeoff is clear--you use this shitty awful language and you get to run your code on the browser, because that's pretty much the only reasonable way to run your code in the browser right now. There are alternatives (TypeScript, CoffeeScript) but then you're limited to a smaller community with fewer resources.

But with JavaScript on the server, there's no tradeoff. You use this shitty awful language and you get... a shitty awful language. You don't get a reasonable threading model, you don't get a reasonable type system. You don't get anything you couldn't get from another language.

It's not a tradeoff, it's just a bad choice.

> As much of a pile of hot steaming code as it is, Babel as an idea (AKA transpiling one language to another) is pretty cool. Of course you can do this in other places but its featuring prominently in the JS community leading to an interesting result. The language and its features become configurable, easy to adapt and change and evolve over time and suit to your liking. This is interesting!

Interesting, yes, and useful. But there's really no reason this had to be written in JavaScript, and the code would likely be a lot less of a "pile of hot steaming code" if it were written in a more reasonable ecosystem.

> Of course there are lots of negatives, lots of horrible code, lots of mistakes happening.

The problem isn't that there is bad code, it's that there isn't any good code. If you needed to write a server-side program and you chose JavaScript, your code is bad and you should feel bad. It's literally impossible to write good server code in JavaScript because it doesn't provide adequate types or threading primitives. It would be different if there weren't alternatives (like in the browser), but there are alternatives which are better.


Your argument proves too much, i. e. that all languages / runtimes / frameworks are of equal quality and usefulness and all differences come down to individual taste – and that's obviously absurd.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: