40 ms·
For example, by not allowing one to create a parametrized method. `func (self SomeNonGenericType) Foo[T any](param T) T` is not allowed, best one can do is `fun
by drdaeman 4y ago
For example, by not allowing one to create a parametrized method. `func (self SomeNonGenericType) Foo[T any](param T) T` is not allowed, best one can do is `func Foo[T any](self SomeNonGenericType, param T) T`.
The reasons are explained here: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#No-parameterized-methods https://go.googlesource.com/proposal/+/refs/heads/master/des... but the point is, you can have this in Java, but not in Go.
- thegeekpirate 4y agoYou can certainly use generic parameters in methods—the [T any] just has to be on SomeNonGenericType, even if it's not used inside the type itself https://rakyll.org/generics-facilititators https://rakyll.org/generics-facilititators
- drdaeman 4y agoYes, but that's completely different thing. If you move T you would change the semantics. - func (self SomeType[T]) Foo(...) is a method for a class parametrized on T. So if you want foo.Foo(1) then it only works for foo that's SomeType[int]. You cannot then easily call foo.Foo("one") on the same instance. - func (self SomeType) Foo[T any](...) - if that'd be a thing - would be a generic method on SomeType that works for any T. So you can foo.Foo(1) and foo.Foo("one") on the very next line and that would work.
- deleted 4y ago[deleted]
- thegeekpirate 4y agoYou can instantiate it with [any] then use whatever you'd like https://go.dev/play/p/JeSuB_xYNEf https://go.dev/play/p/JeSuB_xYNEf, but I don't think it would work with a type constraint such as `int|string`, which would be a fair point.
- drdaeman 4y agoOooh. My bad. Thank you! I honestly thought that wasn't possible at all. Today I learned. However, it won't work for return values, right? Because e.g. `func (some something[T]) hi(b T) T` would return `any` and not whatever it was provided (`int` or `string` respectively). https://go.dev/play/p/IYoPUQg04sg https://go.dev/play/p/IYoPUQg04sg Also, I don't think this can work well with types narrower/fancier than `any`, e.g. I had trouble figuring out how to deal with type IntOrString interface { int | string } type something[T IntOrString] int https://go.dev/play/p/acwjxdpHTJO https://go.dev/play/p/acwjxdpHTJO
- tsimionescu 4y agoSure, but it's no longer generic, you're just using runtime types again. This is extremely important, because it means `func (someType[T any]) foo(T x) T`, `x.foo(1)` would return `any`, not `int` like a generic function would. In fact, if you're going to instantiate a generic type parameter with `any`, I would very much doubt you wanted a generic type in the first place.
- socialdemocrat 4y agoWhy not use a free function? That is more flexible. Go isn’t Java, it is not a deadly sin to write free functions. You look at something like the Reader and Writer interfaces and there are very few methods. The Go approach is to put more functionality in free functions such as fmt.Fprintf which allows more code reuse across multiple types. In fact I view the heavy Java use of methods as an anti-pattern.
- drdaeman 4y agoOne surely can, and probably that's about the only option they have. But for some `foo.Add(bar)` can be considered nicer than `AddFoo(foo, bar)` or `foopkg.Add(foo, bar)`. The semantic differences are mostly in in an aesthetic/stylistic/personal preferences realm, so it's hard to argue for or against it.
- doctor_eval 4y agoExcept that in Java, the former is more common and in Go, the latter is more common. Really, the latter looks more like idiomatic Go, which makes the original complaint somewhat redundant. You might stylistically prefer the former, but then you're probably not going to enjoy using Go anyway.
- drdaeman 4y agoWell, yes, name "Add" was a bad idea - collection management in particular tends to use free functions somewhat more - starting from the built-in `append`, hah. Although even that is not universal - consider e.g. github.com/deckarep/golang-set, which I believe is one of most popular set packages, based on number of imports. It doesn't strike me as non-idiomatic), it's all methods there and not free functions. And either way, I'd disagree on the general principle. I'm not claiming to be well-versed in Go styles and patterns, but most well-designed libraries I've seen had exposed `foopkg.NewFoo()`, useful structs and constants (e.g. `foopkg.FooParams` or `foopkg.NoSuchFoo`) and the rest is typically interface methods.
- 4y ago