Is it safe to say two unname interface types are identical if their type sets are identicial?

86 views
Skip to first unread message

tapi...@gmail.com

unread,
Mar 24, 2022, 6:58:33 AM3/24/22
to golang-nuts

.

Axel Wagner

unread,
Mar 24, 2022, 7:37:08 AM3/24/22
to tapi...@gmail.com, golang-nuts
A named type is always different from any other type. Otherwise, two types are identical if their underlying type literals are structurally equivalent

Neither type is named, so they are identical, if their underlying type literals are structurally identical, namely:

 Two interface types are identical if they define the same type set.

So, yes.

On Thu, Mar 24, 2022 at 11:58 AM tapi...@gmail.com <tapi...@gmail.com> wrote:

.

--
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/ad3a0670-a7a7-49ad-9e85-cbdae98cacb7n%40googlegroups.com.

Jan Mercl

unread,
Mar 24, 2022, 7:38:10 AM3/24/22
to tapi...@gmail.com, golang-nuts
On Thu, Mar 24, 2022 at 11:58 AM tapi...@gmail.com <tapi...@gmail.com> wrote:

https://go.dev/ref/spec#Type_identity

tapi...@gmail.com

unread,
Mar 24, 2022, 8:28:57 AM3/24/22
to golang-nuts
Then I think interface{int; m()} and interface{bool;; m()} should be identical.
Because their type sets are both empty..

Axel Wagner

unread,
Mar 24, 2022, 8:56:35 AM3/24/22
to tapi...@gmail.com, golang-nuts
I believe you are correct in that the spec needs work here. The two should probably not be considered identical, but they are according to the spec right now.
I'm not sure this poses an immediate problem, as I don't think such interfaces can ever appear in a position where type identity matters.

--
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.

Jan Mercl

unread,
Mar 24, 2022, 9:04:46 AM3/24/22
to Axel Wagner, tapi...@gmail.com, golang-nuts
On Thu, Mar 24, 2022 at 1:56 PM 'Axel Wagner' via golang-nuts
<golan...@googlegroups.com> wrote:

> I believe you are correct in that the spec needs work here. The two should probably not be considered identical, but they are according to the spec right now.
> I'm not sure this poses an immediate problem, as I don't think such interfaces can ever appear in a position where type identity matters.

I think the specs are correct, type set != method set.

Axel Wagner

unread,
Mar 24, 2022, 9:13:41 AM3/24/22
to Jan Mercl, tapi...@gmail.com, golang-nuts
The type set is defined as "all types which implement the interface".
Any type implementing interface{int; m()} has to both

1. have the method m()
2. be the type int

That's not possible. Therefore, the type set of that interface is empty.

The problem is, that the type set is potentially hard to calculate. I wrote a proof of that at some point: https://github.com/golang/go/issues/45346#issuecomment-813639125
However, since then, the design has changed and become more restricted, so the proof might no longer be accurate (I also wrote a follow-up, but the design has changed after that as well). So, I don't know if this is still NP-hard.

If it is, though, that would present a problem, because if the spec defines interface types to be identical, if their type sets are identical, the compiler would have to solve an NP-hard problem to check if two interface types are indeed identical. Obviously, we want to avoid needing a compiler to do that, so our definition should then not depend on the actual type sets.

Currently, this isn't a problem, because the compiler only has to check if two interface types are identical, when this is trivial to do, by comparing method sets. So, in a sense, it doesn't matter if "the spec is right or not", because there is no one disagreeing with the spec. But we might want to consider this, if we ever allow *other* interfaces to be full types (i.e. to take values), because then the compiler would have to actually be able to check that.

At that point, we should either a) be certain that we can efficiently compute type sets, or b) change the definition to no longer rely on type sets (as we did for e.g. whether or not it's valid to call methods or use operators).

Axel Wagner

unread,
Mar 24, 2022, 9:37:02 AM3/24/22
to golang-nuts
Out of curiosity, I went ahead and checked what go/types thinks:

It prints
interface{m(); int}
interface{m(); string}
false

So, there is a Go implementation which disagrees with the spec after all.

Axel Wagner

unread,
Mar 24, 2022, 9:43:41 AM3/24/22
to golang-nuts
Reply all
Reply to author
Forward
0 new messages