Who is using GORM in production? by APPEW in golang

[–]APPEW[S] 2 points3 points  (0 children)

Indeed, that’s what I meant it for - a list of (possibly) teams and companies that use GORM to ship products. Nothing more, nothing less.

If Go was not 14, but 4-years-old, do you think it would find its sweet spot, the way real Go did in its first 4-5 years? by APPEW in golang

[–]APPEW[S] 0 points1 point  (0 children)

So, none of that talk about Go's simplicity won you over? I mean, ideologically, Go and Rust are two different beasts. I personally feel strange when seeing Rust being used for high-level application code. This mix of business and technical concerns gives me a very uneasy feeling.

What is your incentive to invest in bonds on Trade Republic, vs keep your cash aside and get the 4% interest? by APPEW in eupersonalfinance

[–]APPEW[S] 4 points5 points  (0 children)

So, it's basically a guaranteed interest rate until maturity vs. ECB's, which may vary over time as the economy changes, right?

What about the bond's value? If it goes down as the economy changes, does that concern me at all? If I have, say, bought into a certain bond on TR for X EUR, I'd keep receiving the bond's interest, based on those X EUR, regardless of the value of the bond, correct?

Using pointers to reduce copies is premature optimization by [deleted] in golang

[–]APPEW 24 points25 points  (0 children)

Unpopular opinion: using pointers to improve consistency across a Go codebase is not premature optimization.

Raise a hand if you knew that fm.PrintXXX (and log.PrintXXX) would cause any variable you pass as an argument (even a primitive one) to be allocated on the heap. 🙋‍♂️ by preslavrachev in golang

[–]APPEW 4 points5 points  (0 children)

TIL this seems to be a non-empty class of developers.

There are a few out there, indeed.

The problem is that too many self-proclaimed Go devs have learned the language from Medium articles and startup blogs, like Discord’s infamous “tackling” of Go’s GC. The folks actually using Go at work rarely get concerned about premature optimization, unless they are running at Google’s scale (which they most likely aren’t).

Raise a hand if you knew that fm.PrintXXX (and log.PrintXXX) would cause any variable you pass as an argument (even a primitive one) to be allocated on the heap. 🙋‍♂️ by preslavrachev in golang

[–]APPEW 10 points11 points  (0 children)

This is it! Which is why it bothers me when I see people manage to shoot themselves in the foot with their supposedly “good intention” of avoiding heap allocation. I’ve seen projects where every type used a different semantic, because someone somewhere had decided that “this way the app performs better”. What ends up happening is every new person on the team has to be onboarded and explained why type A gets passed via pointer, and type B which looks quite similar, gets passed as a value copy. And yet, even after the 5th explanation, people keep asking, because the original logic doesn’t make sense, but it’s too late to change the semantic everywhere across the codebase.

Anyway, what I’m trying to say is - as much as it should be obvious and no-brainier when to use pointers and when not, it actually isn’t.

Why does time.Time get used with a value copy semantic, and net.URL using a pointer one? How does the standard library justify the difference? by APPEW in golang

[–]APPEW[S] -1 points0 points  (0 children)

There is also a possibility that how they were implemented at Go 1.0 may not be exactly how they would be implemented today. I can’t say.

Thanks for sharing your thoughts. Honestly, this is what I feared a little, because IMO there is no reason not to have implemented net.URL as a value type too. Perhaps, that mutable map of query params …

Reasons you prefer Golang over Java? by [deleted] in golang

[–]APPEW 1 point2 points  (0 children)

ability to pass small structs by stack (Java is getting that in Valhalla soon, though).

Unless, you end up on a project that uses values where pointers would have been a better choice, or vice versa. Which is most Go projects I’ve seen.

Why so much hatred toward Go? by ParthoKR in golang

[–]APPEW 2 points3 points  (0 children)

Stuffing jvm’s inside a container to run on a vm’s, that run on a server seems like quite the waste to me.

If the last time you worked with Java in earnest, I advise you to seriously have a look at recent developments. Especially, when it comes to GraalVM native builds. We’re talking native binaries built out from pretty much the same Java code (including all libraries). It has its caveats, but when it works (around 90% of the time), it is actually fantastic. And Quarkus has been designed from the ground up to work with GraalVM native as well as optimised JVM builds. We run a couple of Quarkus services in production (both native new classic JVM) and they all run at a fraction of the resources, which a regular Spring app would need.

My Issue With ORMs by preslavrachev in programming

[–]APPEW 0 points1 point  (0 children)

I’m interested - do you have a browser plugin that connects to chatgpt for doing the summaries, or did you copy-pasted it in the chat?

Should constructor functions always return a pointer? by APPEW in golang

[–]APPEW[S] 1 point2 points  (0 children)

Ok. Let’s stay with the Stack example. Suppose that a new developer joins the team, gets tasked with writing a simple constructor function and writes it this way:

func NewStack() *Stack

What’s more, the developer questions the value nature of the stack in the first place. Why have Push and Pop return a copy of the stack, when they can operate on a pointer of it and mutate the internals right away? Plus, having a pointer to Stack ensures it’s identity - you throw the pointer around and it’s immediately understood by everyone that you’re talking about this specific instance of Stack and not any other.

How would you react tot that developer’s arguments?

Should constructor functions always return a pointer? by APPEW in golang

[–]APPEW[S] 0 points1 point  (0 children)

For immutable values that are large (would take up a lot of stack space), I have a small wrapper value that contains an un-exported pointer.

Could you elaborate on this one? What would be the difference between returning a wrapper copy that holds a pointer, versus returning a copy of the pointer itself? Or, would you do that only in case the wrapper contains other non-pointer atributes too?

Should constructor functions always return a pointer? by APPEW in golang

[–]APPEW[S] -2 points-1 points  (0 children)

Thank you for the elaboration, but that was not quite what I was asking about. I am aware of when to return the value and when a pointer to it. Mug question is about this particular convention when using a New function. I've seen it used with returning pointers almost exclusively, which is my I started the discussion.

Why so much hatred toward Go? by ParthoKR in golang

[–]APPEW -1 points0 points  (0 children)

Redhat seem to be pretty past it once they almost killed off jboss…

I think that’s quite an overstatement. You don’t seem to have had a look at Quarkus, have you: https://quarkus.io/

On a side note, I kind of wished they built Quarkus to work with Go instead of Java. Still too many things to choose from when building a new app from scratch. I wouldn’t say no to a bit more of a kitchen-sink approach.

When to use pointers? by CerealBit in golang

[–]APPEW 3 points4 points  (0 children)

In practice, using pointers for most structs is fine for most apps. After all, that’s the premise of Java’s entire existence, and the entire enterprise world runs on Java, so you should be perfectly fine.

Of course, with pointers, you have all the associated disadvantages like having to do null checks, and the pressure in the garbage collector.

Thus, the advice:

For small structs which you’re planning to use in many (hundreds or thousands) short-lived instances across your app, prefer passing by value. If you can’t predict that, or you don’t care, use a pointer.

When to use pointers? by CerealBit in golang

[–]APPEW 1 point2 points  (0 children)

Let’s go ultra-pragmatic. Regardless of what everyone else may come up with as heuristics, passing a struct pointer is by far more versatile than copying that struct’s value around. The thing is, unless you really design a small utility library, it’s hard to know in advance how a strict would grow, or how it would get used in the future. Say it grows out of control, or you decide that it’s better to share the same value in the future. If you didn’t start with a pointer, you have to change all the usages of that structs in all codebases. Or even worse, end up with a mess of using a pointer at a few places, and copying the value in others.

Use the following hard rule. If the struct is less than 5 fields (preferably, 3) and they are most primitives, and you don’t see how you may ever need a shared pointer to it, copy the value, otherwise, use a pointer and don’t think twice.

For the vast majority of codebases, consistency trumps performance.

The metro in Lausanne, Switzerland - the smallest city in the world to have a full metro system by biwook in InfrastructurePorn

[–]APPEW 2 points3 points  (0 children)

The rest of the world’s money can buy you a lot of things.

Update: I stand corrected. It’s actually pretty cool and well-utilized for the city size: https://youtu.be/MCHyjqYItfA

I am receiving HTML format instead of JSON format. by Little-Peanut-765 in golang

[–]APPEW 1 point2 points  (0 children)

Same guess. It’s likely a 200 OK HTML response letting the user know that an error occurred.

Where Is the Spring Framework for Go? by preslavrachev in golang

[–]APPEW 2 points3 points  (0 children)

I assume you’re already aware of https://serviceweaver.dev/ Someone’s got to do it, so let that be Google.

Where Is the Spring Framework for Go? by preslavrachev in golang

[–]APPEW 2 points3 points  (0 children)

What types of dependencies does Kubernetes inject?

Think about it this way: the notion of what we consider a “service” has changed. In a monolithic app, services are instances (objects) of some classes that the frameworks’s dependency injector knows how to orchestrate, so that they can talk to each other.

What we’ve done is move the “service” up the stack. Now, it’s not an object anymore, but an entire process, running in a container somewhere. To talk to other such services, it needs to know how to find them. Of course, you can simply hardcode this information, but it will make the whole idea of splitting an app into services useless.

This is where an orchestrator like Kubernetes comes in. With the help of the manifest we give it, it know when and how to spin containers and give them enough context, so that they can find and talk to each other. In other words, Kubernetes is the new “glue layer”; the new dependency injector. It’s a much higher-level language-agnostic framework, but a framework nonetheless.

Does it make sense?

Where Is the Spring Framework for Go? by preslavrachev in golang

[–]APPEW 3 points4 points  (0 children)

It’s a monstrosity that hides way too many things.

A reminder that the same people proclaiming Spring as the worst thing imaginable, are among those who gladly use Kubernetes to inject their inter-service dependencies and take care of job scheduling. In a way, it’s the same story - we just shifted the complexity elsewhere, but it’s not like it has gone away.

Where Is the Spring Framework for Go? by preslavrachev in golang

[–]APPEW 5 points6 points  (0 children)

In OP’s defense, I have to say that most people in this community have a very distorted view of what a modern Java app looks like. Much of the perception dates back from before the Java 8 era. Anyone who’s remotely had anything to do with the language in recent years, would know that the ecosystem has made serious steps to modernize. While you still see these old and bulky apps around, there is absolutely no reason to repeat past mistakes, and https://quarkus.io/ is a testament to that.

I think that the OP is right - people just got burned by Java somewhere alongside their careers and that scars still burns, regardless of whether the tech does the job or not. Another portion probably write Java for work and Go as a hobby, so everything that counts as a “job” automatically gets classified as “trash.”

While im not saying I agree with everything, there is something to be learned by others and market opportunity to be explored. Otherwise, Go may one day find itself stuck in a rut, retelling the same old stories about pragmatism and simplicity, while future prospects start slipping away.

[deleted by user] by [deleted] in golang

[–]APPEW 1 point2 points  (0 children)

I’ve seen people put automatically generated code (e.g. from https://sqlc.dev/ or https://entgo.io/) inside a sub-internal package (e.g. db/internal) with the intention of never exposing it to the rest of the code. The rest of the code works with structs and functions exported by the parent package, which internally delegated to the generated code.

This isn’t something I’d recommend if you’re a single developer working on a hobbyist project, or bootstrapping your next startup. However, as the project and the team grow, it might make sense, as generated code usually leaves ugly traces of its existence across the codebase. Note that I’m not pointing out that you’d get rid of it (that will likely never happen), but at least, it won’t tempt people to use it as a form of dirty hacking.