Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I also prefer writing REST APIs in Go.

- Compared to Java: Ecosystem is way over-engineered. You might get along just fine without writing a bunch of boilerplate and factories and XML configs, but sooner or later you're probably going to pull in some dependency that does and have to deal with a bunch of clunky APIs and other annoyances.

- Python: Possibly the only language that's even worse at dependency management than Go. Installs packages globally. The solution is to create a "virtual environment" which is code for hacking up your PATH.

- Node: I dislike the quirks of Javascript like remembering the difference between == and ===, undefined vs null, etc. I haven't used Typescript which may solve some of those language issues. I also dislike dealing with promises/callbacks for so many operations.

I like Go because:

- I can compile to a single statically-linked binary and cross-compile for other platforms

- I can choose to either vendor dependencies or use go-dep to create a dependency lockfile. I can have multiple GOPATHs with minimal magic.

- The "go" CLI handles pretty much everything I need without an explicit config file like pom.xml or package.json.

- The language lacks features. There is no magic. Way more so than even Python, there is one obvious way to do things and there's even an official style guide, so it's easy to jump into someone else's code and understand exactly what's going on immediately. After working with Scala professionally for a few years, I firmly believe this to be a feature, not a flaw.

- The standard library is incredibly comprehensive. It's completely possible to write a web service without importing a single external dependency. There has been a lot of thought put into library APIs for things like byte Readers/Writers and HTTP handlers, to the point that external libraries still usually stick to these standard interfaces. Contrast that with a language like Python where urllib sucks so everyone uses requests.



Obviously completely get that this is subjective, whatever language you're happiest and most productive in is the correct choice for you, etc, but if I might address your points on JS/node perhaps you'll find something useful there:

> == vs ===

Just never use ==, and you're done. This is pretty much a defacto standard. It essentially has no legitimate usecase that couldn't be expressed more explicitly with at most 1 extra line, and should just be ignored.

> undefined vs null

I've only very occasionally run into this being an issue. Standard seems to be using the falsey nature of both undefined and null to check for them, !x rather than x === null for example, so that it doesn't really come up much in practice, but anyway...

> TypeScript may solve some of these issues

Yes, it solves both the above :-)

> Dislike dealing with promises / callbacks

Firstly callbacks are hardly seen anywhere any more. And if they are, certainly no more than one level deep, and that's even assuming you don't just promisify the callback function anyway, which is trivial to do.

For Promises - async/await makes dealing with them syntactically much nicer in node. It's pretty much just like synchronous code to read, and in behaviour.


I see this complaint against Java a lot. If you're going to slum it in a language with no ecosystem so you don't feel overwhelmed, why not just use less of the Java ecosystem?


I think that when GP said, "ecosystem is over-engineered", they didn't mean that it's too rich, they meant to say that it's over-engineered.

Which, I'm not sure there's a more durable reputation in all of informatics than Java's reputation for over-engineering things.

There are cleaner Java libraries for most things nowadays, but the culture around the language is also such that, in many companies, it is politically much easier to use another language entirely than it is to use Java but choose a REST framework that doesn't implement JAX-RS.


>politically much easier to use another language entirely than it is to use Java but choose a REST framework that doesn't implement JAX-RS

This might be true but I find it so backwards.


It's not always clear how to do that. Sure, in theory it's possible to manually download JARs, configure your classpath, and run javac. In practice, the wisdom seems to be to replace the old ecosystem with a new ecosystem like Maven -> Gradle or Spring -> Spring Boot.

In comparison, the entire standard build process for a Go program is:

    $ export GOPATH="/path/to/repo" && go get && go build && ./main
No config files with some DSL to learn or handwritten XML, no weird class loader behavior to track down, no tuning memory limits or any of that stuff that is just par for the course in Java.


The tooling is a very valid critique.

Like C/C++, javac is just a compiler.

It's not a a dependency resolver, a runtime, a formatter, etc.

go is all of those things.


The entire build process for java is mvn package. The only xml you encounter in modern java will be your pom.xml. How is that any different from a package.json, go.mod, cargo.toml, or Pipfile?


And then I get a jar. Or maybe a war. Or maybe a zip? And maybe it's a fat jar with all dependencies bundled. Or maybe not and I need to fetch a bunch of deps and configure a classpath. And then I need the right JRE wherever I'm going to run it. And then I can run it like 'java -jar'. Or maybe I need a server like Tomcat. Or maybe something else.

And every time you jump into an existing codebase, you need to scrutinize the docs that are hopefully there to figure out particulars of the build/deploy process.


This is any language in any code base. Even in Go I will need to figure out if go modules, dep, or something else is being used. In rust, does this project produce a bin or rlib? Having options isn't a bad thing.


These complaints are usually by people who have not been using modern Java, or who have just been reading or hearing unsubstantiated claims about it. Or who haven't worked in large golang projects to see all the mess it brings with it because of how underpowered it is.

Look up libraries like Spark[1] or Javalin[2] and you get something quite light weight. Or DropWizard[3] if you need something more holistic.

That being said, the moment you need something more involved, say validation, DB access, pre- or post- endpoint call processing (e.g. for authorization), then golang completely falls on its face. There is nothing in golang that compares to Jooq[4] for instance, and because golang doesn't have annotations, you can't do automatic validation or authorization, and you end up having to do everything manually in a verbose and error prone manner.

For static compilation in Java, GraalVM is supposed to be quite good[5]

[1] http://sparkjava.com/ [2] https://javalin.io/ [3] https://www.dropwizard.io/1.3.12/docs/ [4] https://www.jooq.org/ [5] https://quarkus.io/


You are right that big (especially enterprise) projects in Go are also a mess. But one of the main reasons is that people have a Java (or C++) background and try to replicate all sorts of complexity.. not because Go is "underpowered".

Also if you compare those codebases to Java (again enterprise) projects of a similar size they seem quite readable instantly..


> You are right that big (especially enterprise) projects in Go are also a mess. But one of the main reasons is that people have a Java (or C++) background and try to replicate all sorts of complexity.. not because Go is "underpowered".

That hasn't been my experience at an employer. Their devs mainly had Python and NodeJs experience and similar languages (which is what the first version of the code base was written in), and disliked "enterprisey" code. Somehow, the decision to move to golang was made.

Yet, they somehow managed to come up with their own mess, and yes it is mainly because how underpowered golang is. I keep thinking about how much simpler the code base would be if it were written in Java, let alone something like Kotlin.


I've used Spark in prod. Worked great and was the highest QPS service in the company I worked at. It was pushing >5GB/hour of JS over ~50 running containers at more than ~1000QPS/container each doing a bunch of crypto (AES) & and data wrangling (JDBC). Only thing that was difficult was serving SSL but that was the Java SSL-key ecosystem's fault. Ideally SSL would come from an edge load balancer but this company had a strange requirement that there was no 80 traffic.


GraalVM is nowhere near production-ready nor is supported by a lot of frameworks. Porting existing code is still a big challenge.


There hasn't been a single job advert in the last decade when I was being contacted for Java gigs that didn't involve dealing with legacy code and dependency injection spaghetti.

Everybody has legacy code. Modern Java doesn't mean much if your team is 2 years away from being able to use the modern stuff.


Not OP, but in my experience, it's harder to know how to get from System.out.println("hello world") to GET / in a browser showing "<b>hello world</b>", without adopting some intensely documented framework and infrastructure, along with obscure XML configuration files. I liked that aspect of Clojure, but I wouldn't have a clue how to achieve the same thing in pure Java.


This is patently false. Getting to hello world is as simple as knowing how to add a dependency, just like any other language and requires 0 xml. See javalin [0], or spark [1].

[0] https://javalin.io/ [1] http://sparkjava.com/


Thanks for sharing these links! My point was that I didn't know how to do this, not knowing these frameworks existed and unable to find them on my own search. You solved that issue for me. If these frameworks get more attention, maybe it'll be solved for more people!


On Python packages, we’ve found miniconda + pip is great for isolated environments that JustWork.




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

Search: