Live data from Hacker News

One year after switching from Java to Go

glasskube.dev

421–430 of 503 posts

Re: One year after switching from Java to Go

#421
post #240

Earlier quoted context omitted.

To me the implication is that the culture at this company won't allow this team to master Go either, and in a few years there will be a post describing how they moved from Go to another language. Many people like to write about how Golang is so simple, but the drawback of that simplicity is that many features of other languages are either covered by additional dependencies or by inflating code size. It's just as poss…

Golang's standard library looks pretty complete to me and they will probably master it in a month.

But people here are comparing a language standard library with a framework like Spring, which doesn't make sense.

The Java standard library has a web server in it, it has JDBC. You could use those directly. That's comparable to the Go standard library. For real apps people don't do this because they want a lot more, like simplified database access or session management.

Look at this: https://pkg.go.dev/database/sql

It strongly resembles JDBC. Doing a database query with that is verbose and error prone. Compare the work needed to do a lookup query and map the results to a data structure with that to (Micronaut syntax, Spring is similar):

    @JdbcRepository(dialect = Dialect.POSTGRES) 
    interface GophersRepository extends CrudRepository {}
... and later ...

    var someGopher = gophersRepository.findById("goo");
Add the username/password/host/port to the config file and that's all you need for db access. Compare to the Go stdlib which wants you to manage drivers, connections, prepared statements, rollbacks, etc. It's a different level of abstraction.

Re: One year after switching from Java to Go

#422
post #278

Earlier quoted context omitted.

> 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.

It is definitely possible with exceptions, but it is not the norm (you can do it yourself, but will a library also do it?) because the norm in Java is to silently pass up exceptions as that is the most ergonomic thing. And once you start doing it with exceptions, there’s not much difference in the code you end up writing between errors and exceptions. In practice, I’ve found that when I write Go, I end up annotating…

> And once you start doing it with exceptions, there’s not much difference in the code you end up writing between errors and exceptions

The difference is where you want to catch the error, and not doing a bunch of "plumbing code" for intermediate callers that don't need to know about that error.

> because the norm in Java is to silently pass up exceptions as that is the most ergonomic thing

Adding args to an exception is completely localized. Adding additional args to an error in Go could mean changing dozens of files.

Not to mention I can actually make my own exceptions for the problem. They are like enums with data.

Re: One year after switching from Java to Go

#423

Earlier quoted context omitted.

Again this isn’t an inherent property of .net, you have to add validation. There are plenty of ways to do this in node so the point is moot.

The issue is that this sort of validation boilerplate shouldn't have to be written. The framework should be able to figure it out from the HTTP handler declaration. I suspect this is why FastAPI got so popular in the Python world. IMO, a lot of the JS world seems mentally fixated on express.js-levels of abstraction still. Anything more is viewed as "magic" and viewed as suspect because it requires learning.

The irony is that the "learning" just gets applied elsewhere; there are certain foundational building blocks that I think every language and platform needs once you start building "serious" applications.

Re: One year after switching from Java to Go

#424
post #283

Earlier quoted context omitted.

But that's our point - you're saying java is fast (and it is ripping fast once it gets going) and the startup is fast, unless it's not.

Well no, startup is fast, period. You're probably just giving the class loader a ton of work on startup? I would start with checking that I think. It could also be when he's hitting "run test" it's actually "compile and run"...

Well I could switch to a programming language that isn't so slowed down by ahead-of-time compilation. Maybe a JIT language?

Re: One year after switching from Java to Go

#425
post #278

Earlier quoted context omitted.

It is definitely possible with exceptions, but it is not the norm (you can do it yourself, but will a library also do it?) because the norm in Java is to silently pass up exceptions as that is the most ergonomic thing. And once you start doing it with exceptions, there’s not much difference in the code you end up writing between errors and exceptions. In practice, I’ve found that when I write Go, I end up annotating…

> And once you start doing it with exceptions, there’s not much difference in the code you end up writing between errors and exceptions The difference is where you want to catch the error, and not doing a bunch of "plumbing code" for intermediate callers that don't need to know about that error. > because the norm in Java is to silently pass up exceptions as that is the most ergonomic thing Adding args to an exceptio…

> difference is where you want to catch the error

Catching is pretty similar no? In Java you match by type and in Go, you match by `errors.Is`? I guess the static checking in Java js better, but in terms of code written it is no different.

> additional args to error in Go could mean changing dozens of files

Just to be clear, here we are talking about a function that already returns an exception/error and adding args to it? That is also a local change in Go as well. The call site already handle the interface for error, not sure why changing a field or modifying the error message would make a difference.

Arguably, this type of thing is harder in Java. Adding a new type of exception requires modifying all dependent callers to declare/handle the exception (unless they handle the generic Exception), whereas in Go it is a local only change (except if you need to actually handle the error).

Re: One year after switching from Java to Go

#426
post #380

Earlier quoted context omitted.

> ...includes support for a soft memory limit. This memory limit includes the Go heap and all other memory managed by the runtime, and excludes external memory sources such as mappings of the binary itself, memory managed in other languages, and memory held by the operating system on behalf of the Go program" Of course it’s a runtime setting, it won’t affect other factors but you can’t say it didn’t solved anything “…

Sorry, but no - putting the burden on the developer to detect whether they are running in a container or not and then determine and adjust to cgroup settings is far too high an encumbrance on the service developer. This is a demonstrative example of a fundamental responsibility that should always be delegated to the runtime as the default behavior. Neither Go 1.19 nor any subsequent version has "solved" this issue.

> Sorry, but no - putting the burden on the developer to detect whether they are running in a container or not and then determine and adjust to cgroup settings is far too high an encumbrance on the service developer.

Because there’s no one way solution to this problem, the problem isn’t unique to only Go, but every GC language because you’re starving the program if there isn’t sufficient CPU Quota it will all eventually lead to CPU throttling, this isn’t really the problem of Go or any other GC language but at the OS layer, the inherent nature of containers

Secondly am pretty sure the Linux CFS does not strictly follow the CPU Quota, tho there could be something like a panic or warning, or switching to entirely different memory management just for what ? people who want 10ms ?

Re: One year after switching from Java to Go

#427

Earlier quoted context omitted.

I like to think of these problems as having skill ceilings and skill floors like in video games. For large companies often the skill floor is more important than the skill ceiling. If it is easier to start in B than A, even though after years of experience A can be much better, it might still be a better choice to use B. When you have lots of junior devs, you are more concerned with this upstart time, and I think in…

I do have experience of managing junior teams and I think Java is actually great for them. You only need one senior person to kick off the project and put down the rails - a relatively small effort if you use frameworks instead of bespoke solutions. The team just needs to follow the lead. It is extremely cost efficient and good enough for business in terms of quality/security/performance.

Another re-phrasing of my comment is that perhaps using Go they do not require the strong senior to kick it off.

Otherwise yes there is always the argument of "they're just using it wrong" etc...

ultimately: ¯\_(ツ)_/¯

Re: One year after switching from Java to Go

#428
post #126

Earlier quoted context omitted.

went to springone conference in vegas in 2016. eight years later, there are still no good alternatives :)

> eight years later, there are still no good alternatives Micronaut? Quarkus? Depends on what you need.

Will take a look:)

Re: One year after switching from Java to Go

#429
post #216

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…

Having exceptions means that every line in your function is a potential exit point, often without you being aware of it. This can lead to bugs when a non-atomic operation is abruptly terminated, and you might not realize it just by glancing at the code. When we were rewriting some code from PHP to Go, I remember that simply thinking about "what to do with err" led me to realize we had a ticking time bomb - one that c…

It's rather the opposite, it helps avoid bugs when something is terminated, e.g. by ensuring that if an exception is thrown it rolls back a database transaction.

Generally you want to do several classes of things with exceptions in web apps:

1. Return a 500, possibly rendering a nice error page.

2. Log why it occurred.

3. Roll back changes you were making at the time in the database.

And you might also want to do other things, like propagate the error via tracing, increment monitored metrics and many other things. All these are easily done with exceptions, and will often be done by frameworks for you. In desktop apps you may also want to trigger a crash reporter, display a sorry message to the user, and if the exception was inside something like a button click handler you may even be able to proceed safely too.

Given the level of bugginess in untested error handling codepaths that crop up in languages without them, exceptions are definitely the way to go.

Re: One year after switching from Java to Go

#430

Earlier quoted context omitted.

Sad, spring is killing java

if it is, it is doing a very, very, very bad job of it

Okay, maybe I spoke to strongly, it is very widely used and does have some nice ideas (Spring Boot is awesome). But it's just my opinion that Spring does give a lot of new devs the idea that Java is overly complex. And for me at least, I've only needed to use dependency injection once throughout my years as a dev (worked in many companies, large to small). Had to rename a class in a large microservice and didn't have to do a search and replace to rename all the places it was used.

But, in my opinion, the cons outweigh the benefits. It adds a lot of complexity for a feature that is rarely used. Am sure if used in a major refactor it'd be nice, but some search and replace is much better than adding an entire layer to your system that in many ways is not strongly typed (auto-wiring), and also adds an entire set of steps to the debugging process. Am actually pretty good at debugging Spring wiring problems, but still don't think you should have to have learned the art of Spring wiring just to debug something relatively simple - how your components are linked together - and all done at runtime.

To me, if tool builders want to support dependency injection, it should be done at the compiler level, along with the rest of the linking of objects. Yeah, don't think dynamically wiring objects is all that useful for a very large majority of builds... ... thought it over, I think I'd like this actually. A new, dedicated component type where the Java compiler checks your DI. That might be very nice. Yeah, also because having a component type will support using DI where it should be, at the component level, not on every class like it tends to be used.

Post reply on HN