Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think it's common, coming from the object oriented world, to expect polymorphism to be intrinsically tied to method overloading. But it doesn't have to be.

Please provide some examples. For example, I don't think polymorphism in direct variable references is all that good.

It leaves the Go language with more freedom from the future. Everyone agrees Go needs polymorphism. So add polymorphism.

This statement confuses me. Go has polymorphism.



If you go and look at the Map/Reduce/Filter, Channels, Containers, and Append sections of the examples, there isn't any use of contracts. All that is required for those sections to work is to declare a type parameter, and then allow that parameter to be filled by any type, but still typecheck that all of the variables with the same parameter are the same type at the calling site. There's no need to have a contract for which methods can be called on the type, because we don't need to call any methods or access any fields. In my experience, this fills most use cases. It allows generic data structures, and generic functions over those structures.

If you need a little bit of behavior for those types, such as for a TreeMap data structure or a Sort function, Go's higher order functions make this possible without contracts, by passing in functions. The draft's Containers section uses this approach to construct a TreeMap. The SliceFn function, described in the Sort section, also uses this approach:

    func SliceFn(type Elem)(s []Elem, f func(Elem, Elem) bool) {
     Sort(sliceFn(Elem){s, f})
    }
Although this does use method overloading via contracts in implementation (via Sort), it doesn't need it. I expect that Go's existing interfaces (which yes, are a form of polymorphism, mea culpa) + unbounded parametric polymorphism are enough to solve 90% of Go's current issues.

The more complex cases are still possible to handle with parametrically polymorphic structs containing functions. Yes, that's bad code, but we'd be able to look for this use case, judge how often it occurs, and use it's use cases as data to inform further discussions on contracts.

The only case I struggle to easily deal with is the numeric case. My solution doesn't allow generic numeric functions, although I think there's room to explore that in more detail.


If you go and look at the Map/Reduce/Filter, Channels, Containers, and Append sections of the examples, there isn't any use of contracts.

I see. I'm of the opinion that the Go team might be more cautious and introduce a more limited form of generics first, which seems in line with what you're saying.

In my experience, this fills most use cases. It allows generic data structures, and generic functions over those structures.

How would one make something like ConcurrentMap? Perhaps some operations on a map could be exposed and "overridden?"


It would be simple to write a ConcurrentMap.

What is more difficult is writing a function which accepts both ConcurrentMaps and TreeMaps. In Java, they would both inherit from Map. In this proposal(/Rust/Haskell) they would implement the same contract(/trait/interface). In my proposal... there isn't an elegant solution.

In some cases, you can write the function to be generic over an insertion function `insert func(T)`, if all you need is assertion, and then you can pass `treeMap.insert` as the parameter. If you really truly need to be generic over the entire `Map` interface, that is one of the cases that I claim only takes up 10% of the cases. In that case, you could define a type which contains all of the functions a Map needs, and then you could construct that and manually pass that in.

This can be viewed as a desugaring of contracts. One implementation that contracts could have would be to, at runtime, construct and pass a value containing the functions that the contract specified are possible.


It's "typeclass", not "interface". Though it works similar and is, in fact, just a way to define a constraint.

As of your described way of desugaring the contract, looks way too cluttered. It's exactly the reason why Reader and ReaderT exist in Haskell. Even though the proposal's contract syntax doesn't look very beautiful, it's still drastically better than keeping track of drilled structs of functions, the latter will become a mess really really fast, so having a way to conveniently constraint the accepted types while having a full-blown parametric polymorphism is essential for a modern language. Not sure exactly why anyone would be against that.


Sigh, I really need to read my posts before submitting. You're right, of course it's typeclass.

The whole point is to implement the bare bones of a parametric polymorphic system without constraining further development of the language. Additionally, it discourages complexity and requires explicitness, two goals of Go.

As far as my description of desugaring the contract, that is literally how Haskell implements typeclasses.


Well, yeah, Reader is that kind of thing.

I guess that the complexity people are concerned about is that once you implement a parametric polymorphism, HKTs are inevitable and that probably requires some brain flexing in order to get the meaning of a structure, which defeats the main purpose that is being explicit and simple. Pretty much a deadlock. I now understand why the community is so in odds with the parametric polymorphism as the concept but I'm also sure that simplicity of use and convenience of writing a robust solution is the two things that require it. You can't keep your head near the sand and avoid HKTs when you want flexibility and you can't allow that type of polymorphism whilst striving for what's Go trying to do.

While understanding the both standpoints, though, I still hope that Go will get parametric polymorphism as it's just so much more pleasant and convenient than carrying around a mess of structures to be explicit no matter the costs.


> Go has polymorphism

polymorphism is often distinguished into ad-hoc polymorphism (interfaces) and parametric polymorphism (generics) – i'm guessing GP was referring to the latter?


You're right, in my head I was writing parametric polymorphism, and it just didn't make it's way to my fingers somehow.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: