Live data from Hacker News

One year after switching from Java to Go

glasskube.dev

111–120 of 503 posts

Re: One year after switching from Java to Go

#111
post #71

Earlier quoted context omitted.

What challenge did you run into with exception handling? I'm curious because I've never felt it being onerous nor felt like there was much friction. Perhaps because I've primarily built web applications and web APIs, it's very common to simply let the exception bubble up to global middleware and handle it at a single point (log, wrap/transform). Then most of the code doesn't really care about exceptions. The only cas…

In Go, b) is really common. Most of my code will annotate a lower error with the context of the operation that was happening. You’ll ideally see errors at the top level like: “failed to process item ‘foo’: unable to open user database at ‘/some/path’: file does not exist” as an example. Here, the lowest level IO error (which could be quite unhelpful, because at best it can tell you the name of the file, but not WHY i…

    > Most of my code will annotate a lower error with the context of the operation that was happening.
This is easy to solve with chained exceptions to add context.

    > it generates much better debugging info than a stack trace in a lot of situations, especially for non-transient errors because you can annotate things with method arguments.
You cannot add method args to an exception message? I am confused.

Re: One year after switching from Java to Go

#112
post #74

Earlier quoted context omitted.

Agreed, every time I jump back into Go I'm at first relieved at how nimble it feels; but it never takes long to remember what a pita error handling is or the kludges you need to write to do basic collection transformation pipelines (compared to Java/Streams, C#/LINQ, C++/std etc).

> or the kludges you need to write to do basic collection transformation pipelines (compared to Java/Streams, C#/LINQ, C++/std etc). Why hasn't anyone written a good open source for this problem, now that Go has generics?

Don't know, every time I try to do anything beyond trivial using Go generics I run into some kind of issue. They haven't been around that long, it takes time for ideas to mature.

Re: One year after switching from Java to Go

#113
post #81
post #77

Earlier quoted context omitted.

I could tell you why, based on writing a ton of code in both, but I doubt that would lead anywhere.

https://github.com/codr7/tyred-java/tree/main/src/codr7/tyre... 24 of those files are under 100 lines - some of them are as small as three lines of code. and that's not a personal preference - that's mandated by Java that each type needs to be in its own file, ridiculous.

    > that's mandated by Java that each type needs to be in its own file, ridiculous.
Nested classes?

Re: One year after switching from Java to Go

#114

I've been using Go for a while now. The biggest headache is error handling. I don't care what the "experts" say, having exception handling is so, so, so much cleaner in terms of error handling. Checking for err is simply bad, and trickling errors back up the call stack is one of the dumbest experiences in programming I've endured in multi-decades. If they are willing to add generics, they should add exception handlin…

Maybe go just isn’t for you? It really doesn’t need every feature of other languages. The error handling is ideal for me, better than any other language. You are always explicit, with every function call, about “what could happen if this fails?” Maybe passing it up the stack is the best way to handle it, but also maybe it’s better to handle it somewhere in the middle. The thing that always happens with exceptions in…

Exceptions are a terrible idea.

However, I strongly prefer rust error handling to Go.

go:

   (res, err) := foo()
   if err != nil
       return err
   (res, err) := bar(res)
   if err != …
Equivalent rust:

   let res = bar(foo)?)?;
I think go should add the ? sigil or something equivalently terse.

Ignoring all the extra keystrokes, I write “if err == nil” about 1% of the time, and then spend 30 minutes debugging it. That typo is not possible in idiomatic rust.

Re: One year after switching from Java to Go

#116
post #5

I long for a deep article about the same topic. The real, core difference between Java and Go for backend is declarative vs imperative coding styles. This one, as typical for such articles, repeats typical secondary talking points and even makes similar mistakes. For example it conflates the concept of DI with specifics of implementation in some frameworks. Yes there are older Java frameworks that do runtime magic. B…

Which of these languages is declarative? Aren't they both imperative?

Java 8+ is basically a declarative language. They even officially started departing from Object Oriented Programming towards Data Oriented Programming ( article by their chief architect https://www.infoq.com/articles/data-oriented-programming-jav... ). Unfortunately, most of the comparison articles come from people who still code POJOs with setters, use for loops and overall rely on mutable and unsafe code.

And using Pike’s own words “go is unapologetically imperative”.

Re: One year after switching from Java to Go

#117

Earlier quoted context omitted.

To each their own. I'm not going to claim to be an expert, but as somebody who's been coding since the 80s it was a breath of fresh air to see Go do what I wanted languages to do all long instead of ramming exceptions down my throat. I have problems with Go (examples: slice behavior and nil type interfaces) but error handling is not one of them.

What challenge did you run into with exception handling? I'm curious because I've never felt it being onerous nor felt like there was much friction. Perhaps because I've primarily built web applications and web APIs, it's very common to simply let the exception bubble up to global middleware and handle it at a single point (log, wrap/transform). Then most of the code doesn't really care about exceptions. The only cas…

Exceptions are fine if you never catch them. So is calling abort(). (Which is the Unix way to do what you described.)

If you need to handle errors, you quickly get into extremely complicated control flow that you now have to test:

   // all functions can throw, return nil or not.
   // All require cleanup.
   try {
      a = f();
      b = a.g();
   } catch(e) {
      c = h();
   } finally {
      if a cleanup_a() // can throw 
      if b cleanup_b() // null check doesn’t suffice…
      if c cleanup_c()
   }
Try mapping all the paths through that mess. It’s 6 lines of code. 4 paths can get into the catch block. 8 can get to finally. Finally multiplies that out by some annoying factor.

Re: One year after switching from Java to Go

#118

Earlier quoted context omitted.

> How about database transactions? Ran into an interesting issue this week. In a .NET world, every ORM can participate in an ambient transaction because everyone uses System.Transactions. Not the case in Node because there's no such thing. I mean you could say the same thing about TypeScript - if your entire stack is TypeScript then there's no need for the type validation either.

Even if your entire stack is TS, you still need validation because the submitted data from an external interface (API call) might not be valid. You can't just accept any JSON payload and expect it to be valid. In Java or .NET, it will fail at serialization when the runtime tries to map it to a static type (automatic). This is not the case at runtime with JS (because at runtime, it's no longer TS). Thus you need a Zod…

I think CharlieDigital's point is that a bad payload will fail right at the serialisation boundary in case of .NET. We know the problem right there. Now we only need to fix the bad payload.

For TypeScript with only types and without validation, a bad payload gets through, and there is no telling where in the workflow it will explode. This could waste more time and developer resources in debugging.

Re: One year after switching from Java to Go

#119
post #74

Earlier quoted context omitted.

Agreed, every time I jump back into Go I'm at first relieved at how nimble it feels; but it never takes long to remember what a pita error handling is or the kludges you need to write to do basic collection transformation pipelines (compared to Java/Streams, C#/LINQ, C++/std etc).

> or the kludges you need to write to do basic collection transformation pipelines (compared to Java/Streams, C#/LINQ, C++/std etc). Why hasn't anyone written a good open source for this problem, now that Go has generics?

It seems like the std library has slowly been adding generic iterators methods. Maybe one day?

Re: One year after switching from Java to Go

#120
post #89

We run mostly Java apps with a few Go apps. What I miss with Go, maybe just because I'm not as familiar and don't know where to look, is all the runtime analysis that's built in. Thread dumps, heap dumps, and even flight recorder profiling is all built in to the JVM so it works with all apps everywhere. When a Go app suddenly slows down it's very difficult to determine why unless the app was coded to provide the righ…

I actually much prefer go ‘s runtime tooling. Pprof has everything I need built in; heap, cpu, blocking, mutex contention. And don’t need additional tools to visualize the collected data. https://pkg.go.dev/net/http/pprof@go1.24.0

Does pprof work when CGO is enabled?
Post reply on HN