←back to thread

Constraints in Go

(bitfieldconsulting.com)
210 points gus_leonel | 1 comments | | HN request time: 0.207s | source
Show context
pansa2 ◴[] No.42163816[source]
I'm surprised by the complexity of Go's generic constraints, given the language's focus on simplicity. Things like the difference between "implementing" and "satisfying" a constraint [0], and exceptions around what a constraint can contain [1]:

> A union (with more than one term) cannot contain the predeclared identifier comparable or interfaces that specify methods, or embed comparable or interfaces that specify methods.

Is this level of complexity unavoidable when implementing generics (in any language)? If not, could it have been avoided if Go's design had included generics from the start?

[0] https://stackoverflow.com/questions/77445861/whats-the-diffe...

[1] https://blog.merovius.de/posts/2024-01-05_constraining_compl...

replies(5): >>42164004 #>>42164048 #>>42164801 #>>42164982 #>>42176376 #
rendaw ◴[] No.42164004[source]
There are tons of random limitations not present in other languages too, like no generic methods.
replies(2): >>42164827 #>>42170829 #
bigdubs ◴[] No.42164827[source]
That's not a random limitation, there are very specific reasons[1] you cannot easily add generic methods as struct receiver functions.

[1] https://go.googlesource.com/proposal/+/refs/heads/master/des...

replies(2): >>42165247 #>>42168728 #
the_gipsy ◴[] No.42168728[source]
> Or, we could decide that parameterized methods do not, in fact, implement interfaces, but then it's much less clear why we need methods at all. If we disregard interfaces, any parameterized method can be implemented as a parameterized function.

What? Methods are not needed if not for implementing an interface?

Anyway, functions could also be implementing interfaces, some languages allow that.

I swear the go docs read like a cult.

replies(1): >>42189837 #
int_19h ◴[] No.42189837[source]
Functions in Go can be generic, just not methods.

And unless you're also using interfaces, methods are no different from functions aside from call syntax.

replies(1): >>42193172 #
the_gipsy ◴[] No.42193172[source]
But "methods are only needed because of interfaces" is simply not true. Not true in all other OOP languages that I know of, not true in go, and not true in go's stdlib (that is, in practice).

Methods bind state with a function.

That an object can satisfy an interface is secondary here. In different languages, an interface could be satisfied with a combination of methods, fields, or nominality.

If the statement "we could decide that parameterized methods do not, in fact, implement interfaces, but then it's much less clear why we need methods at all" was true, then there should not be a single struct in go (stdlib nor elsewhere) that does not implement some interface (and it must be used via that interface to make sense). This is obviously not the case.

replies(1): >>42210745 #
1. int_19h ◴[] No.42210745[source]
If the method is not dynamically dispatched, it is exactly equivalent to a function with receiver passed as the first argument. The receiver-dot notation is just a convenient form of implicit namespacing, then, nothing more. And, in Go, methods are only dynamically dispatched on the receiver in the context of interfaces. So, everything else is just syntactic sugar. And what the doc is saying is that supporting this syntactic sugar makes the spec much more complicated, so they deemed it not worthwhile, given that a global function works just as well in this context.