5 ms·
How can Go does it even worse that Java where generics implementation is the worse of all modern language with type erasure. Java is way worse than Go on that
by Thaxll 4y ago
How can Go does it even worse that Java where generics implementation is the worse of all modern language with type erasure.
Java is way worse than Go on that aspect.
- drdaeman 4y agoFor 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
- Quekid5 4y agoType erasure is interesting. It turns out that not doing type erasure (combined with instanceOf-like things, like pattern matches on type parameters) breaks parametricity. Parametricity is a very powerful reasoning tool. Of course, type erasure isn't the actual culprit in that case, but once you don't do it, it gets very tempting to allow pattern matching on type parameters...
- juliangamble 4y agoThis.
- Gibbon1 4y agoI read an essay by a CS post doc taking about type erasure. He said getting to the point where you can do type erasure is golden. And then everyone makes the mistake of actually implementing type erasure. He said you consign yourself to no tooling and terrible debugging.
- tadfisher 4y agoType erasure has little to do with the power of generics at the language level. Haskell, with one of the most powerful type systems around, erases types to a greater extent than Java does (concrete types are still encoded in JVM bytecode, Haskell erases everything).
- deleted 4y ago[deleted]
- kaba0 4y agoYou do realize that type erasure is the common way of dealing with (generic) types? Haskell also does type erasure, as well as basically every language outside C#.
- seabrookmx 4y agoYou can have it both ways in C++ depending on your compiler flags! And people wonder why we complain about C++..