On Tue, Aug 4, 2020 at 1:01 AM Ben Hoyt <benh...@gmail.com> wrote: > In terms of a "solution" for this, one that I'm sure has been thought > about: what about keeping type constraints and interfaces completely > separate? They are half the time anyway (when there are type lists), > so why not make them separate all the time. >
They used to be. That's essentially what contracts used to be in the previous iteration of the design. Of course they also used a completely different syntax and way to define the constraints, but this separation was one of the major changes between the original contracts design and this new draft. At the time I (and others) have argued against this separation: https://blog.merovius.de/2018/09/05/scrapping_contracts.html#scrapping-contracts I'm still strongly in favor of not having it. In particular, there is a large section of conceptual overlap between interfaces and constrained type-parameters. And at least as far as function parameters go, an interface parameter can *always* be re-written into a constrained type-parameter. At least as long as we live in this overlap, it seems very confusing to have two separate names for what is very much the same thing - specifying a subset of valid types to use. It also has technological downsides, because if you already have an `io.Reader` interface, you also need to have an equivalent contract (or whatever we call this constraint kind) and vice-versa, if a concept is more naturally translated one way or another. So, just as it can be argued that certain kinds of constraints are very different from interfaces, so it's confusing to conflate them, it can also be argued that many (if not most) constraints are exactly the same thing as interfaces, so it's confusing to separate them. AIUI, the evolution of the design then basically progressed from "so maybe we should allow interfaces as constraints as well as contracts, to simplify things" to "it turns out we don't really need contracts as a separate concept after all, so it is cleaner to leave them out". IMO the discussion about this is purely based on the idea of type-lists which exists purely so as to support operators on type-parameters. And personally I feel a better way to solve this solution would be to just drop that from the design. IMO, the utility of this isn't really worth the cost. Especially given that there's no way to write a function to work with *either* methods *or* operators, so the actual practical utility is pretty small. Arguably you need two copies of any function working with - one for "primitel types" using operators and one for "composite types" using methods. That seems… inelegant to say the least and I'm not convinced that it's better than to require people to add a method to "primitive types" to use them in generic code. And IMO a more orthogonal solution to allowing use with "primitive types" would be some form of operator overloading or endowing predeclared types with suitable methods - either would allow us to actually write generic code that could work with both primitive and composite types, without needing us to introduce a separate way to specify constraints. That being said, I know that the people driving the design consider being able to write generic code using operators non-optional, so I know that this likely won't happen. But I do think it's important to allow using interfaces as constraints and I do think that any benefit of separating the concepts would probably vanish, as long as you allow that - being able to have both seems to me the prototypical compromise, in that it combines the downside of both ideas. So, personally, I still strongly believe that re-using interfaces is the right design. I realize in the design draft the "Stringer" interface is used as a > type constraint heavily, but that seems like a bit of an example/toy. In real-world code, how likely is it that we'll be using lots of > existing interfaces as constraints? I think that's very likely. So far, in the 6 weeks I've been thinking about how I'd use generics in Go, I have not considered a single use-case that uses operators - and they all either used no constraints at all or pre-existing interfaces or `comparable` (but even there, only for use as map-keys, not for the actual comparison operator). I also don't think "pre-existing" is the right lense. More interesting is: How many constraints would *also* be useful as types? And I'd argue that probably *every* constraint that is implemented mostly by composite types (for example any abstract data structure, which is a *huge* chunk of use-cases for generics) would also be useful as a type in its own right (and obviously can't be used with operators then). If you want a constraint to also be useable as a type, you either end up a) having to write down two declarations which are identical, except one says "interface" and one "constraint" - which seems confusing, because if the declarations are identical, why do you both of them? Or b) making it possible to constrain type-parameters with interfaces as well. In which case you have this entirely separate concept for something that ends up being sort of an edge-case, as in the general case (i.e. no type-lists), interfaces would be strictly more useful. PS: Just for posterity, I do think this has been discussed at least a little bit: https://groups.google.com/forum/#!searchin/golang-nuts/type-list|sort:date/golang-nuts/jpw7ndLrjtQ/w20lhwVIAQAJ https://groups.google.com/forum/#!searchin/golang-nuts/type-list|sort:date/golang-nuts/CYMIK-Ojvi8/P6eos__vAAAJ https://groups.google.com/forum/#!searchin/golang-nuts/type-list|sort:date/golang-nuts/IABU_sD6SsA/xjMNy73kBgAJ (maybe others, this is just a very cursory search) To me it seems like that won't be > common, but I don't have much to go on. > > -Ben > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/CAL9jXCHa5%2B4LreE7acP_r3QEBMGKN6qzgzkLFv4VXsW5aoXfcw%40mail.gmail.com > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfG9HinxnC_d2mQyWRWsgRJDn7ZmV5X9iE1QL%2BysCcyHaA%40mail.gmail.com.