6 ms·
Experience with Go in the last few years has shown that you don't really need them. If you think you do, then you're doing it wrong. Also: http://research.swtc
by _ak 14y ago
Experience with Go in the last few years has shown that you don't really need them. If you think you do, then you're doing it wrong.
Also: http://research.swtch.com/generic http://research.swtch.com/generic
- AndrewDucker 14y agoAnd as the various comments there show, .Net does it right, and better than any of the methods they list. If I want to create a new wrapper class, the last thing I want to do is either make it hold an Object, or have to write a new version of it for every type it can hold.
- grey-area 14y agoIf I want to create a new wrapper class, the last thing I want to do is either make it hold an Object, or have to write a new version of it for every type it can hold. Can't you solve this problem with an interface defining the behaviours your wrapper expects? The interface can then be passed in or held as a ptr without requiring a specific type, allowing a generic implementation. You can create a generic iterate or sort function for example which operates on slices of a given interface. Sorry if I've misunderstood, if so a code example might help clarify what you mean.
- AndrewDucker 14y agoLet's say we have a Reply<T> which packages up the actual reply from a service, along with the status of the service call, and any additional warnings, etc. In C# I can define this once, and then any service can just return a Reply<string>, Reply<int>, Reply<Address>, etc. The calling method can check the associated reply status, and then unwrap the data if the call was successful, displaying any associated messages as needed. Or, for a different example: If I want to store a long list of Customers in a dictionary, keyed on String, then in C# I'd create a Dictionary<string,Customer>, and know that it would always contain the types I'd expect. How would I do either of those in Go?
- grey-area 14y agoI'm no expert in Go, but I think it can cover most common uses of generics like those you mention, though you cannot of course replicate all C++ code in Go without changing paradigms a little. It won't work in exactly the same way, but it can usually solve the same problems elegantly. 1. Generic reply (for a good example of this in use see the way errors are used in go; errors are extensible and can contain info like that in your example). http://blog.golang.org/2011/07/error-handling-and-go.html http://blog.golang.org/2011/07/error-handling-and-go.html For your example, you could have a reply interface, defining the requirements, then concrete types which conform: http://play.golang.org/p/e18n36Ub5u http://play.golang.org/p/e18n36Ub5u There are probably shorter ways to do this, this is just an off the cuff example, but it's quite possible to have generic reply types which respond to any methods you want, and can be created easily and extended if necessary. You can also cast back to the original type. 2. Just use map[string]Customer - Customer could be an interface (duck typing) or a type. Something like this: http://play.golang.org/p/ZoftbY8mQX http://play.golang.org/p/ZoftbY8mQX IMHO using an interface here is more interesting, as it lets you define your requirements, and forget all about the type system, while letting the compiler check that any uses will always work as they conform to the interface.
- AndrewDucker 14y agoIn your examples there, am I not having to create a new type per case? So a Reply<String> and a Reply<Customer> will require me to create two classes?
- ansible 14y agoYou'd just want to have your types implement the interface for Reply, and provide a method with the same signature that clients can use. Here's what I think you want, written in (as far as I am able to) idiomatic Go: http://play.golang.org/p/KI79ynfRg2 http://play.golang.org/p/KI79ynfRg2
- quatrevingts 14y agoThis means that your objects are aware of every "container" that might hold them. This does not scale, and it certainly doesn't work for reusing data structures.
- gngeal 14y ago"And as the various comments there show, .Net does it right, and better than any of the methods they list." .NET has generics? I mean, actual generics, not simple first-order parametric polymorphism with type constructors of the kind (* -> *)? Can you write, say, a generic reader or a generic printer that will work with all types? How would you go about doing that?
- AndrewDucker 14y agoYou'll have to simplify that for someone who doesn't know type theory :-> Looking at the Parametric Polymorphism article on Wikipedia, that indicates that implementing it produces generic functions and generic datatypes, which is what I'm talking about here. Sadly, beyond about the third sentence of that article I'm lost :->
- deleted 14y ago[deleted]
- coldtea 14y ago>Experience with Go in the last few years has shown that you don't really need them. If you think you do, then you're doing it wrong. No. Some people's experience with Go. People that might not have much experience with generics to start with. And if they think the rest are "doing it wrong", they are mistaken.
- _ak 14y ago> People that might not have much experience with generics to start with. Well, I as someone who has professionally worked with C++ for over 5 years and used C++ templates quite a bit, I never ever needed generics in Go even once. Why do you think is that so? Maybe because I do not force my C++ style of thinking onto what language features Go offers and instead write idiomatic Go code? (n.b. I did more than just playing around with Go a bit, I wrote serious applications in Go some of which are in production use)
- jbooth 14y agoI've definitely copy/pasted a stripe-locked concurrent map a couple times to use it for different types. Basically any re-usable container class is the canonical case for generics. I agree that in most other cases, it turns out you can write a simpler API than Thing<OtherThing<Key, ? extends Value>>, and nobody wants to open the door to that mess. But for containers, they either need to dramatically multiply the number of built-in container classes (slice[] map[] are generic in a way), or create a way to write your own.
- wyqueshocec 14y agoI found that doing data processing in Go was a bit cumbersome due to missing generics. Using a functional programming approach, data processing is easy because you can create new data by taking old data and specifying a transformation process. With Go, I had to manually handle the iteration through the old data's container object. Not a huge deal, but it felt like I was reinventing the wheel in every goroutine.
- abraininavat 14y agoAre you really saying that there's no place for generics? You can't think outside your own anecdotal experience and see that there's a reason generics exist and are used and considered important by many serious engineers? Are you saying that every one of the many serious engineers who miss generics when writing Go are just not thinking outside the generics box? Or are you willing to admit that, while Go without generics may be a great language for many applications, there clearly are applications where generics are the right language construct for the job?
- quatrevingts 14y agoSo they pick the option that slows down the programmer? How forward-looking. And yet, Java, .NET, Haskell, O'Caml, etc. are all faster than Go anyway. Not to mention the fact that this makes it harder to reuse data structures and algorithms, which can have a much bigger impact on performance.