On Fri, Jun 19, 2020 at 2:38 PM Ian Lance Taylor <i...@golang.org> wrote:

> On Fri, Jun 19, 2020 at 9:31 AM Bryan C. Mills <bcmi...@google.com> wrote:
> >
> > On Fri, Jun 19, 2020 at 1:30 AM Ian Lance Taylor <i...@golang.org>
> wrote:
> >>
> >> This code is acting as though, if ordinary interface types could have
> >> type lists, it would be OK to write
> >>
> >> func Add2(x, y SmallInt) SmallInt { return x + y }ᵢ
> >>
> >> That is not OK, even though SmallInt has a type list.  Even though
> >> every type in theSmallInt type list supports +, they don't support +
> >> with every other type in the type list.
> >
> >
> > Yes, that is exactly my point: the fact that that program is invalid
> implies that type-list interfaces are not consistent with the semantics of
> other interface types.
>
> I'm sure that I don't really understand what you are saying.
>
> But from my perspective using a type list in an interface type used as
> a type constraint permits certain operations in that generic function.
> That is a specific feature of generic functions.  You seem to be
> trying to extend that capability to non-generic functions.  But that
> doesn't work.
>

I am not trying to extend that capability to non-generic functions. I am
pointing out that the fact that generic functions *do* have that capability
implies that type-list interfaces — unlike non-type-list interfaces! —
would have a meaning as type constraints that is incompatible with their
meaning as non-generic interface types.

(Specifically, they would have the usual interface property that “T
implements T” *except* when used as type constraints, and as you note, that
exception is fundamental to the design of constraints.)

> Because the rules for type-list interfaces always have an extra condition
> beyond “simply implementing the interface type”, we would be locked into at
> least one of the following limitations on the evolution of the language:
> >
> > A type-list interface can never be used as a type argument.
> > Or, a type parameter of an interface type can never be allowed as the
> constraint of another type parameter, nor embedded in the constraint of
> another type parameter.
>
> I don't understand what the second limitation means.  The current
> design draft has no way to require that a type parameter have an
> interface type.  Can you give an example of what you mean?
>

https://go2goplay.golang.org/p/6cu23w3iYHQ

> Otherwise, we would break the substitution property: the meaning of a
> type-list interface would depend upon whether it was written literally in
> the source code or passed as a type argument. (That is: the meaning of a
> generic declaration instantiated with a given list of argument types would
> be different from the meaning of the same declaration with some of its
> actual arguments substituted for the corresponding parameters.)
>
> Again I'm sure that I don't understand what you are saying.  My
> initial reaction is that of course the meaning of a type-list
> interface depends on whether it is used as a type constraint or is
> passed as a type argument.  Those are two entirely different
> operations.  You can't use a type parameter as a type constraint.  I
> suppose you could regard that as a limitation of the system, but it's
> an intentional one.


It is already possible to use a type parameter as *part of* a type
constraint, as illustrated by the SliceConstraint example.
That pattern works in a variety of situations, just not as the
*entire* constraint
or as an interface embedded in the constraint type (
https://go2goplay.golang.org/p/cYOhEKo-mm0).

The design doc states clearly that “[t]ype constraints are interface
types”, so it seems oddly inconsistent to allow the parameter to be a
*component
of* the constraint but not the *entire* constraint.


> If a type parameter can be a type constraint,
> then there is no contract for the generic function: it has ceded
> control over what type arguments are permitted.  It is no longer
> possible to compile the generic function separately.  It's a very
> different semantic model.


A type parameter as a type constraint does not “cede” control over types —
it relates one type parameter to another.

The generic function still has control over the constraints of the
parameter itself, so it would still restrict which type arguments are
permitted, and could still be type-checked and compiled independent of
those arguments (with the restriction that the function still cannot use
any *additional* operations granted by, but not required of, the
parameter-constraint).

For what it's worth, I believe that the FGG model also allows parameters as
constraints (via the last rule in Fig. 14, applied iteratively).

> To me, this all suggests that the “underlying type” sort of constraint
> should be conceptually and syntactically different from the “simply
> implementing the interface type” sort of constraint.
>
> I don't necessarily object, if we can find the right name and syntax,
> but I don't understand how that would be effectively different from
> what the design draft says today.  We would say that a type constraint
> can be an interface type, or it can be this other thing that is an
> interface type plus a list of types.
>

It would be different in that the words “type” and “interface”, including
as keywords in Go source code, would retain their consistent and
conventional meanings, which we could then continue to use when discussing
and thinking about those concepts (including in future proposals).

A valid “type” would continue to represent “a set of values
<https://golang.org/ref/spec#Types> together with operations and methods
specific to those values”.
(In contrast, a type-list interface in the current draft, when interpreted
as a constraint, instead represents a set of *sets of* values.)

An “interface type” would continue to always be a valid “type”, and would
continue to represent the set of values “of any type with a [set of
supported operations] that is any superset of the interface” — that is, of
any type whose set of values is a subset of the set represented by the
interface type.

-- 
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/CAKWVi_Rv9m2Tsx3MSA2sMwkk7qY9VqC3c%2Bsfaz8vnBd1Zg4FZA%40mail.gmail.com.

Reply via email to