News for hackers. Stuff that matters.
Re:One Year After Switching from Java to Go: Our Experiences by MrDarcy on Tuesday February 18, 2025 @06:42PM (#43096604)
I hit this point in tfa and had the same comment. Please don’t pass things around in a Comtext. Maybe stash a slog logger in there, but that’s about it.

I made the switch to Go a few years ago. For those who are on a similar journey as the author, or the author himself, I suggest spending time with the Go standard library and tools written by Rob Pike and Russ Cox to get a handle on idiomatic Go.

It’s clear the author still thinks in Java, not go. Saying Context ctx for example instead of ctx context.Context. Also DI, which is arguably not necessary at all in Go given how elegantly interfaces work.

I spent quite a lot of time using wire for DI in go only to really study the code it was generating and realizing it truly is code I would normally just write myself.

Edit:

Regarding stack traces, it turns out you don’t need them. I strongly suggest a top level error handler in Go combined with a custom error struct that records the file and line the error was first seen in your code. Then wrap the error as many times as you want to annotate additional lines as the error is handled up to the top level, but only that first point in our own code is what actually matters nearly all of the time.

Re:One Year After Switching from Java to Go: Our Experiences by arnath on Tuesday February 18, 2025 @07:08PM (#43096842)
This comment is about a very minor part of what you said, but isn’t the whole point of a DI framework to write code you’d have written anyway to save you time?
Re:One Year After Switching from Java to Go: Our Experiences by MrDarcy on Tuesday February 18, 2025 @10:39PM (#43098306)
I was writing code similar to how the popular int13 kubelogin kubectl plugin works, which also uses wire for DI and is organized as a clean architecture repo. In that particular case I found both the clean architecture and the wire DI to add more layers of abstraction, which took more time to comprehend, write, and maintain than jettisoning both and doing it with idiomatic Go.
Re:One Year After Switching from Java to Go: Our Experiences by bcrosby95 on Wednesday February 19, 2025 @12:29AM (#43098889)
DI frameworks save you from writing trivial code, and it masks dependency insanity. This is why I don't use it even in Java. If the codebase gets to the point where a DI framework is really useful then you've fucked yourself over.
Re:One Year After Switching from Java to Go: Our Experiences by unscaled on Wednesday February 19, 2025 @07:18AM (#43101250)
To be fair, traditional Java EE apps often required a DI framework, because you couldn't control the main entry point of the program, and the entry point to your code was a class with a default no-argument constructor.

This is still insanity, but the insanity comes from Java EE rather than the apps themselves.

Re:One Year After Switching from Java to Go: Our Experiences by mukunda_johnson on Tuesday February 18, 2025 @10:15PM (#43098162)
I prefer stack traces in errors. It's gives so much more automatically so you don't have to worry about manual annotation. Stack traces and debug logs are the way to go. I like to use panics for exceptional conditions just for the convenient escape with the stack trace.
Re:One Year After Switching from Java to Go: Our Experiences by ignoramous on Wednesday February 19, 2025 @01:54AM (#43099348)
> I like to use panics for exceptional conditions just for the convenient escape with the stack trace.

One can debug.PrintStack(), instead.

https://pkg.go.dev/runtime/debug#PrintStack

Re:One Year After Switching from Java to Go: Our Experiences by nine_k on Tuesday February 18, 2025 @11:19PM (#43098528)
The exact stack trace may not be very necessary, but tracing the chain of calls, especially async, can be hugely helpful in troubleshooting, performance tracking, etc.

In Node, I remember wrapping Promisesromises into objects that had a stack for pushing messages onto them, so that the creator of a Promise could mark the calling site, and creating another Promise within that promise would pick up the chain of call site names and append to it, etc. Logging that chain when a Promise fails proved to be very useful.

Re:One Year After Switching from Java to Go: Our Experiences by lelanthran on Wednesday February 19, 2025 @01:23AM (#43099165)
> In Node, I remember wrapping Promisesromises into objects that had a stack for pushing messages onto them, so that the creator of a Promise could mark the calling site, and creating another Promise within that promise would pick up the chain of call site names and append to it, etc. Logging that chain when a Promise fails proved to be very useful.

Sounds complicated. I don't use Node much (nor recently, for that matter), but when I write f/end JS I capture the chain of function calls by creating a new exception (or using whatever exception was thrown), and sending the `.stack` field to a globally-scope function which can then do whatever it wants with it.

Will that not work in Node?

Re:One Year After Switching from Java to Go: Our Experiences by galaxyLogic on Wednesday February 19, 2025 @03:17AM (#43099834)
I believe it does. Creating a new Error-instance to learn what the current stack is a bit hacky, but it can be useful, even when there is no error. The code can reflect on who is calling it.

Sometimes a function or method is called very many times so trying to log them all is useless. But at the same time it can be the case that there are multiple callers of the said function. Then looking at a stack we can log just the case of some specific call-chain calling that function.

Re:One Year After Switching from Java to Go: Our Experiences by nesarkvechnep on Wednesday February 19, 2025 @01:35AM (#43099235)
I’m yet to see a former Java developer who uses the idioms of the language they currently use. They all just write Java in a different language.
Re:One Year After Switching from Java to Go: Our Experiences by vram22 on Wednesday February 19, 2025 @02:47AM (#43099695)
That is a function of the developer, not of the language, i.e. f(dev), not f(lang) ;)

Replace Java with star and that statement still holds true (for some people).

Hence the statement that you can write FORTRAN in any language.

https://blog.codinghorror.com/you-can-write-fortran-in-any-l...

Re:One Year After Switching from Java to Go: Our Experiences by vram22 on Wednesday February 19, 2025 @03:38AM (#43099969)
wassup, eff of downvoter, can't handle de troot? :) :) :)

wonder if you read the article linked in my above comment before downvoting, and noted who it is by.

this is who it is by:

https://en.m.wikipedia.org/wiki/Jeff_Atwood

, aka the co-founder of StackOverflow, a q&a site which you have probably used zillions of times, if you are a dev of any kind at all. He is also the cofounder of StackExchange.

>In June 2021, Prosus acquired Stack Overflow for $1.8 billion, its first complete acquisition in the area of educational technology.[11]

so he should know something about what he said, right? unlike you.

You ever achieved anything like that?

Re:One Year After Switching from Java to Go: Our Experiences by mavelikara on Wednesday February 19, 2025 @04:27AM (#43100282)
This isn’t anything special about Java. A determined programmer can write Fortran in any language.
Re:One Year After Switching from Java to Go: Our Experiences by akoboldfrying on Wednesday February 19, 2025 @02:59AM (#43099768)
> Regarding stack traces, it turns out you don’t need them.

goes on to suggest rolling your own buggy, slow, informally specified implementation of half of a stack trace printer

Re:One Year After Switching from Java to Go: Our Experiences by andreasmetsala on Wednesday February 19, 2025 @03:13AM (#43099821)
> Also DI, which is arguably not necessary at all in Go given how elegantly interfaces work. > I spent quite a lot of time using wire for DI in go only to really study the code it was generating and realizing it truly is code I would normally just write myself.

DI is the idea that you should create your dependencies outside of the module / class / function that uses it and pass it in. This makes it easy to swap implementations.

DI does not require any framework and I would argue you can’t write modular code without it. Most likely you are doing DI even in your manually written code.

Re:One Year After Switching from Java to Go: Our Experiences by RussianCow on Wednesday February 19, 2025 @03:34AM (#43099943)
If you're doing "dependency injection" by just passing arguments to functions/modules, you're not really doing dependency injection—you're doing "dependencies" without the "injection" part. I'm not saying that DI necessitates a ton of magic, but you need at least a small framework for specifying dependencies and injecting them into your modules dynamically.
Re:One Year After Switching from Java to Go: Our Experiences by com2kid on Wednesday February 19, 2025 @04:16AM (#43100207)
[delayed]
Re:One Year After Switching from Java to Go: Our Experiences by cryptos on Wednesday February 19, 2025 @04:26AM (#43100273)
But that "framework" could be a simple factory function.
Re:One Year After Switching from Java to Go: Our Experiences by lucumo on Wednesday February 19, 2025 @05:23AM (#43100588)
No, that's wrong.

DI requires that the deps come from outside, not that it's dynamically created. The opposite is that dependencies are created inside the unit. DI is about which part of the code owns the dependency. With DI it's some parent component, without DI it's the component itself.

DI with magic can simplify the management of component lifecycles, but it's entirely possible to do it without.

Re:One Year After Switching from Java to Go: Our Experiences by gf000 on Wednesday February 19, 2025 @05:44AM (#43100709)
No, you can pass (inject) the necessary dependencies to the constructor of an object at creation time, and then simply use that object instance everywhere. The only thing frameworks do is "solve" the dependency graph and instantiate stuff in the correct order.

This is also the most common/preferred way Spring et alia implements their "framework-aided" DI, so that you can write unit tests easily without bootstrapping a Spring context (and it is just well-designed vanilla Java code).

Re:One Year After Switching from Java to Go: Our Experiences by simiones on Wednesday February 19, 2025 @07:05AM (#43101162)
"Injection" in "dependency injection" simply refers to getting your dependencies from outside instead of building them yourself.

Let's take the case of an object which represents a simple CRUD web service that needs to talk to a database to get some data. Here is what it looks like without dependency injection:

  func NewService(databaseHostname, databaseLoginSecret string) (WebService, error) {
    databaseConn, err := databse.NewConn(databaseHostname, databaseLoginSecret)
    if err != nil {
        return WebService{}, fmt.Errorf("Failed to create database conn for WebService: %w", err)
    }
    return WebService{
        databaseConn: databaseConn
    }, nil
  }
And here is what it looks like with dependncy injection:

  func NewService(databaseConn DatabaseConn) WebService {
    return WebService{
        databaseConn: databaseConn
    }
  }
This is the only concept: don't build your own dependencies, get them from outside.

Ideally then there is a place in your application, possibly in `main()`, where all of the base services are initialized, in the required order, and references are passed between them as needed. This can include "factory" style objects if some of these need to be initialized on-demand.

Re:One Year After Switching from Java to Go: Our Experiences by eximius on Wednesday February 19, 2025 @03:51AM (#43100046)
> spent quite a lot of time using wire for DI in go only to really study the code it was generating and realizing it truly is code I would normally just write myself.

Yes, but the point is 1) you don't have to write it yourself and 2) it does 'the right thing' even if your junior dev straight out of BS CS wouldn't know how to write it.

There are, of course, caveats and not all frameworks are created equal and any tool can be misused. But I find DI very useful. Personally I'd recommend Uber's Fx framework and underlying dig library.

Re:One Year After Switching from Java to Go: Our Experiences by fweimer on Wednesday February 19, 2025 @05:51AM (#43100754)
How does Go avoid getting bogged down by middleware-oriented programing in practice? I think most large-scale programming in organizations tend to converge on that because it sort of works.

Is it that people who like this kind of stuff write microservices for deployment on Kubernetes clusters?

Re:One Year After Switching from Java to Go: Our Experiences by Cthulhu_ on Wednesday February 19, 2025 @08:11AM (#43101748)
Go itself doesn't do anything about that, nor does Java or JS dictate anything about using middleware.

I can't speak for the ecosystem / developers though; there are plenty of examples where e.g. HTTP request handlers are wrapped in several onion layers of middleware itself. But, there's also an emphasis on keeping things simple and lightweight.

What kind of middleware are you thinking of when you mention things getting bogged down?

Re:One Year After Switching from Java to Go: Our Experiences by nprateem on Wednesday February 19, 2025 @06:02AM (#43100817)
> Regarding stack traces, it turns out you don’t need them

Then you go on to explain how to recreate them by hand.

Re:One Year After Switching from Java to Go: Our Experiences by saturn_vk on Wednesday February 19, 2025 @06:40AM (#43101015)
> Maybe stash a slog logger in there, but that’s about it.

Please don't do this either. Read the stuff you want to log as additional attributes in your slog handler from the context, which you ultimately pass to `slog.*Context`

Re:One Year After Switching from Java to Go: Our Experiences by saturn_vk on Wednesday February 19, 2025 @06:42AM (#43101030)
> Also DI, which is arguably not necessary at all in Go given how elegantly interfaces work.

DI is necessary in every language that doesn't rely solely on global singletons. Passing dependencies as arguments to a function is DI.

What may not be necessary, are IOC containers automatically create objects and satisfy their dependencies.

Re:One Year After Switching from Java to Go: Our Experiences by unscaled on Wednesday February 19, 2025 @07:12AM (#43101199)
Too many people confuse the concept of DI with a DI framework. You don't even need a DI framework to write straightforward programs in Java. After all, Java also has interfaces!

One of the reason people needed a DI framework in Java is crazy "enterprise" configurability requirements and Java EE-based standards that required you to implement a class with a default no-argument constructor. If you're using a web framework like Jooby, Http4k, Ktor or Vert.x, you do not need a DI framework (source: we've written many modern Kotlin applications without a DI framework and we've had zero issues with that).

Of course, all of our non-toy Go applications are using dependency injection as well. Unless the code reviewer messes up, we won't let anyone configure behavior through globals and singletons.

Re:One Year After Switching from Java to Go: Our Experiences by mexicocitinluez on Wednesday February 19, 2025 @10:43AM (#43103293)
> One of the reason people needed a DI framework in Java is crazy "enterprise" configurability requirements a

No, it's so that you can have something else manage the lifetime and disposal of your services instead of doing this yourself. You don't have to be writing crazy enterprisey code to have the need for this.

I agree DI is simple, but 100% disagree that you can achieve this through a hand-rolled library without sinking a ton of wasted time.

Re:One Year After Switching from Java to Go: Our Experiences by Cthulhu_ on Wednesday February 19, 2025 @08:09AM (#43101721)
> Then wrap the error as many times as you want to annotate additional lines as the error is handled up to the top level

I'd add that this is a last resort; errors should be handled and resolved as close to where they occur as possible. Having them bubble up to a central error handler implies you don't really want to do anything with it.

Re:One Year After Switching from Java to Go: Our Experiences by gf000 on Wednesday February 19, 2025 @09:13AM (#43102360)
I would argue that in the majority of the cases that's the only reasonable behavior. I do agree that errors should be handled as close as possible to where they occured, but not any closer -- e.g. there is not much you can do within a library's functions if an unexpected error occured inside. It should be handled at whatever business code happens to call it. And in the worst case, they should bubble up to a central handler, that either outputs an 500 error, or an error dialog.

Exceptions pretty much make this the sane/default behavior, with rust-like ADTs with syntax sugar being close.

Re:One Year After Switching from Java to Go: Our Experiences by jbreckmckye on Wednesday February 19, 2025 @08:25AM (#43101893)
> Regarding stack traces, it turns out you don’t need them. I strongly suggest a top level error handler in Go combined with a custom error struct that records the file and line the error was first seen in your code. Then wrap the error as many times as you want

So instead of a stacktrace, you are - tracing the stack? Am I understanding correctly?

Because it just sounds like a manual version of stacktraces

Re:One Year After Switching from Java to Go: Our Experiences by Capricorn2481 on Wednesday February 19, 2025 @03:31PM (#43107247)
> Because it just sounds like a manual version of stacktraces

Because it is. I don't understand it either.

Re:One Year After Switching from Java to Go: Our Experiences by mexicocitinluez on Wednesday February 19, 2025 @10:50AM (#43103377)
> I spent quite a lot of time using wire for DI in go only to really study the code it was generating and realizing it truly is code I would normally just write myself.

This is like saying "I won't use source generators because it generates code I would normally write myself"

Like, yea no shit. THAT'S the point.