News for hackers. Stuff that matters.
Re:One Year After Switching from Java to Go: Our Experiences by roncesvalles on Wednesday February 19, 2025 @02:34AM (#43099616)
IoC DI in Go is a massive antipattern and absolutely should not be done. Do NOT write Java/.NET style controllers in Go i.e. initializing an instance of a "controller" type with some instances of a "dependency" such as a store.

Just use the dependent package directly. Initialize the package once using init() or Init(). Rely on the built-in package dependency resolver system in Go, which will catch cyclic dependencies, call init() in topo order, and other such things.

Test using monkey-patching. Stop using interfaces just to be able to swap a real thing with a mock implementation. These are all symptoms of writing Java in Go.

Re:One Year After Switching from Java to Go: Our Experiences by someothherguyy on Wednesday February 19, 2025 @02:47AM (#43099699)
So, write python in go instead, gotcha.
Re:One Year After Switching from Java to Go: Our Experiences by roncesvalles on Wednesday February 19, 2025 @02:54AM (#43099736)
The idiomatic way to write Go is as naively as possible after you fully understand how it works. Otherwise it'll just feel like Java with shitty ergonomics.

If you're ever writing Go and wish you had real classes instead of this deconstructed "mess" with struct types, methods, and interfaces, you're writing Go totally wrong.

Re:One Year After Switching from Java to Go: Our Experiences by gf000 on Wednesday February 19, 2025 @05:47AM (#43100727)
Sounds like a no true Scotsman fallacy.
Re:One Year After Switching from Java to Go: Our Experiences by unscaled on Wednesday February 19, 2025 @07:37AM (#43101395)
That is certainly one way to write Go, but I wouldn't call it "idiomatic" when evil the Google Best Practices guide recommends against it[1][2]. I'll wager you'll probably find it in most other Go style guides. This is how the Go standard library itself works. While you can use http.Get() if you want to use the default HTTP client for simple apps, the library provides you the http.Client struct, where you can also override the Transport (RoundTripper interface) and Jar (CookieJar interfaces). The transport interface lets you further override the Dialer and Proxy function.

[1] https://google.github.io/styleguide/go/best-practices#global... [2] https://google.github.io/styleguide/go/best-practices#provid...

Re:One Year After Switching from Java to Go: Our Experiences by roncesvalles on Wednesday February 19, 2025 @08:07AM (#43101709)
>This document is neither normative nor canonical
Re:One Year After Switching from Java to Go: Our Experiences by stpedgwdgfhgdd on Wednesday February 19, 2025 @02:59AM (#43099767)
I don't get the part on package. Often you want to use structs. (Instance vs static)

How would you construct an instance in a test that needs mock implementations?

Re:One Year After Switching from Java to Go: Our Experiences by roncesvalles on Wednesday February 19, 2025 @03:04AM (#43099791)
Such an instance would just be a variable somewhere that would be initialized in some init() call when the program starts. Every user of that instance will use it directly (as opposed to storing a reference to it locally DI style).
Re:One Year After Switching from Java to Go: Our Experiences by gf000 on Wednesday February 19, 2025 @05:48AM (#43100732)
So global mutable state? How wonderfully modern!
Re:One Year After Switching from Java to Go: Our Experiences by 3uler on Wednesday February 19, 2025 @02:43AM (#43099670)
And yet Uber wrote fx[1] to support DI in their golang services. It’s clearly a useful pattern when working on large services.

[1]: https://github.com/uber-go/fx

Re:One Year After Switching from Java to Go: Our Experiences by 65a on Wednesday February 19, 2025 @02:48AM (#43099702)
I really cannot say Uber's use of Go is particularly idiomatic to me, having started writing Go more than a decade ago now. It just strikes me as overwrought, and I've worked on big services.
Re:One Year After Switching from Java to Go: Our Experiences by roncesvalles on Wednesday February 19, 2025 @02:46AM (#43099689)
I disagree with the premise of that whole project. It shouldn't exist.
Re:One Year After Switching from Java to Go: Our Experiences by Cthulhu_ on Wednesday February 19, 2025 @08:15AM (#43101782)
Just because a known company uses it doesn't mean it's authoritative; there's likewise functional programming libraries built by big companies, but FP should also be avoided in Go because it's not a functional language and not optimized for it.
Re:One Year After Switching from Java to Go: Our Experiences by akoboldfrying on Wednesday February 19, 2025 @03:18AM (#43099845)
> Test using monkey-patching.

TIL Go has monkey-patching.

But since it has monkey-patching, how is it statically typed? Or does Go monkey-patching amount to creating an instance of a defined-on-the-fly subclass?

The latter would be interesting, because Java lets you do this too -- conveniently "new up" an instance of a subclass that you define inline of a given class or interface (this used to be the easiest way to define callbacks, before lambdas came along), so this testing strategy is available to Java too, but seems not to be preferred.

Separate question: IIUC, monkey-patching is convenient if your test code directly needs to create a TestX instead of a real X, but what if you need the test double "deeper down" -- that is, you need an X that creates a Y that creates a TestZ instead of a real Z?

Re:One Year After Switching from Java to Go: Our Experiences by tpm on Wednesday February 19, 2025 @04:53AM (#43100420)
Java doesn't really enable monkey-patching in the style of Javascript, Perl etc. AFAIK, or am I missing something? That you can create anonymous subclasses during runtime is different to e.g. editing methods of existing objects/classes during runtime.
Re:One Year After Switching from Java to Go: Our Experiences by fweimer on Wednesday February 19, 2025 @05:47AM (#43100729)
JVMTI allows method patching: https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.h... The capabilities are somewhat limited, and an enhancement JEP was withdrawn: https://openjdk.org/jeps/159

On the other other, there is a movement to remove such late binding/rebinding features from the Java platform. However, I think JVMTI is expected to remain supported if the agents are loaded ahead of time. Only on-demand loading of agents will be removed from OpenJDK.

Re:One Year After Switching from Java to Go: Our Experiences by gf000 on Wednesday February 19, 2025 @05:51AM (#43100759)
I wouldn't say that there is a movement to remove such late binding features -- the "movement's" primary goal is simply to properly encapsulate and mark any such part of the code (e.g. make it explicit in the module that that should be supported).

That way AOT compilation becomes possible/efficient and dependencies can't hack into other packages in an unmaintainable way without explicit permission from the user, so that updating the JVM and dependencies will be even more streamlined.

Re:One Year After Switching from Java to Go: Our Experiences by fweimer on Wednesday February 19, 2025 @07:55AM (#43101585)
As far as I know, there is no tooling support to propagate these marks to the launcher program even in cases where they can be statically discovered. (This could be similar how dynamic linker agents (audit modules) are handled by the Solaris linker, via DT_AUDIT and DT_DEPAUDIT markers.) Mainly because OpenJDK does not provide a tool (beyond jar) that creates launchers.

This doesn't concern features that have been traditionally abused (such as reflection on core OpenJDK classes), but also harmless (from an encapsulation perspective) uses of JNI, and access to future features such as FFI/Panama. Justification for restricting those as well is not so much OpenJDK updates, I think, but that it could cause crashes that might be blamed on OpenJDK.

Re:One Year After Switching from Java to Go: Our Experiences by akoboldfrying on Wednesday February 19, 2025 @09:43AM (#43102630)
I agree -- I was just trying to guess what OP might have meant by "monkey-patching" when talking about Go (which is TTBOMK statically typed, which precludes what I'd personally call "monkey-patching" at the language level).

Java does have "agents", which enable arbitrary control of bytecode at class loading time -- bytecode in existing .class files can be transformed, or completely new bytecode generated on-the-fly. But generating bytecode just to replace a class with a test double would be insane.

From another comment I learned there's also a separate "Tool Interface" that can do this bytecode-replacement job, but again, it's a huge amount of tricksiness and bother for something more easily and clearly accomplished in source code with a boring old anonymous subclass. (Though it won't work if the class is sealed, or final, or your code uses reflection to check the class name, or...)

Re:One Year After Switching from Java to Go: Our Experiences by the_gipsy on Wednesday February 19, 2025 @08:25AM (#43101885)
> Test using monkey-patching.

Can you elaborate? What library do you use?

Re:One Year After Switching from Java to Go: Our Experiences by captain_coffee on Thursday February 27, 2025 @09:45AM (#43194806)
Hard disagree to literally every thing that you have said in your reply above.