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.

Reply via email to