On Wednesday, June 17, 2020 at 12:08:59 AM UTC-4 Ian Lance Taylor wrote:

> On Tue, Jun 16, 2020 at 9:04 PM Xie Zhenye <xiez...@gmail.com> wrote: 
> > 
> > I agree. constraint is different from normal interface. It's better to 
> use type SomeConstraint constraint {} than type SomeConstraint interface {} 
>
> That is an option, but then we would have two different concepts, 
> constraints and interfaces, that are very very similar. It's not 
> clear that that is better. 
>

I think we already have two very different concepts — we're just conflating 
them together by giving them the same name.
As far as I can tell, the semantics of non-type-list interface types and 
the semantics of type-list interface types are not compatible.

Today, if we have two interface types T1 and T2, with T1's method set is a 
superset of T2's, then any value assignable to T1 is also assignable to T2: 
that is, T1 is a subtype of (not just assignable to!) T2. That observation 
is also reflected in the Featherweight Go paper, in which a type argument 
satisfies a type constraint if (and only if) the argument is a subtype of 
the constraint.

Based on the semantics of type-lists in type constraints, I would expect 
that a run-time interface type containing a type list would mean “an 
interface value whose dynamic type is one of the listed types”, or perhaps 
“an interface value whose dynamic type has one of the listed types as its 
underlying type”. For consistency, such interfaces should also have the 
same sort of subtyping relationship: if type T1's type-list is a strict 
subset of T2's type-list, then any value assignable to T1 (including a 
variable of type T1 itself!) should be assignable to T2.

So, for example:
type SmallInt interface { type int8, int16 }
should be a subtype of
type MediumInt interface { type int8, int16, int32 }

However, in the current design draft, a constraint that is a type-list 
interface allows use of the operators common to the types in the list.
In the presence of type-list subtypes of interface types, the semantics for 
those operators would be confusing at best. Consider the program:

func Add(type T MediumInt)(x, y T) T {
return x + y
}

func main() {
var a int8 = 127
var b int16 = 1
fmt.Println(Add(SmallInt)(a, b))  // Should this print 128, or -128?
}

So type-lists as they are defined in the current draft either cannot have 
the subtyping properties of ordinary interfaces, or must have a meaning as 
type constraints that is fundamentally different from their meaning as 
interfaces. Either way, they don't seem at all consistent with ordinary 
interfaces to me, so I would prefer that we not call them interfaces.

----

On the other hand, if we accept that there is a fundamental difference 
between concrete-type constraints and type-list interfaces, then perhaps 
the type-list interfaces and the “concrete underlying type” constraints 
could be made orthogonal.
Consider, instead of an interface, a constraint indicating that the type 
parameter must be a *concrete* type implementing the given interface:

func Add(type T concrete(MediumInt))(x, y T) T

Now the problem is once again resolved: even if SmallInt is a valid 
run-time interface, it is not a concrete type and cannot satisfy a 
concrete-type constraint.


> On Wednesday, June 17, 2020 at 11:12:24 AM UTC+8 Brandon Dyck wrote: 
> >> 
> >> I find it a little strange that an interface with a type list can only 
> be used as a constraint, and not as the type of a variable or parameter, 
> despite it using basically the same syntax as a normal interface. Is this 
> difference between constraints and other interfaces a property of the type 
> system, or just a limitation of the translation? I don't think it was 
> explicit in the design document. It would certainly be useful to declare 
> variables with type-list interfaces, as it would provide a much less hacky 
> way to define sum types than using an unexported interface method as in 
> https://medium.com/@haya14busa/sum-union-variant-type-in-go-and-static-check-tool-of-switch-case-handling-3bfc61618b1e.
>  
>
> >> 
> >> My failing example is at https://go2goplay.golang.org/p/-lQ0jKs8_hU. 
> > 
> > -- 
> > 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...@googlegroups.com. 
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/88aa126b-d8f1-49c0-84cd-c0ea8cd87d39n%40googlegroups.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/f0e7753a-af88-4481-9df1-8d884558803cn%40googlegroups.com.

Reply via email to