Skip to content

Proof that golang's interface type (nil) current judgement is wrong #67879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ruyi789 opened this issue Jun 7, 2024 · 4 comments
Closed

Proof that golang's interface type (nil) current judgement is wrong #67879

ruyi789 opened this issue Jun 7, 2024 · 4 comments

Comments

@ruyi789
Copy link

ruyi789 commented Jun 7, 2024

Proposal Details

Example:

var a *st //struct
if a==nil //true,yes

var b = any(a) //

a0,yes := b.(*st)
if yes==true //true,yes
if a0==nil//true,yes

if b==nil//(false, yes or no?) The problem arises here when someone argues that this judgement should not hold, based on the type assertion (a0,yes := b.(*st)).

But I think this is wrong, the if b==nil judgement should be based on a value judgement (true,yes), not on a type judgement (false,no). If you make a type judgement

(a0,yes := b.(*st)) is sufficient, the only thing missing is the value judgement of the interface type (essentially the compiler is judging two interfaces of the same type by the value judgement, which is a bit confusing).

Interface type occupies two pointers {typeinfo_ptr, value_ptr}, we should take the judgement (value_ptr) judgement (nil), such as integers (0==0, 1!=0), pointers can also be understood as a kind of value. The following connection example causes problems exactly what I said!

https://go.dev/play/p/pnVn1mT6Keg

@gopherbot gopherbot added this to the Proposal milestone Jun 7, 2024
@gophun
Copy link

gophun commented Jun 7, 2024

There is nothing proposed here.
Also, this behavior is well known and understood: https://go.dev/doc/faq#nil_error
Even if one thinks it's unfortunate, it cannot be changed.
It's also a duplicate of #60786.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Jun 7, 2024
@ALTree ALTree changed the title proposal: Proof that golang's interface type (nil) current judgement is wrong Proof that golang's interface type (nil) current judgement is wrong Jun 7, 2024
@ALTree ALTree removed the Proposal label Jun 7, 2024
@ALTree ALTree removed this from the Proposal milestone Jun 7, 2024
@ruyi789
Copy link
Author

ruyi789 commented Jun 8, 2024

@gophun @seankhliao @ALTree
Our suggestion is not that v-any variable can't access a value of type nil, but to make sure that the logic branch runs strictly to eliminate uncertainty during the (if v==nil) judgement. The compiler fixes its not-so-big change, leaving it to go2 (or go3go4go5... Waiting for someone to fix it later?)
It also creates version variability, and version change variability should be minimised rather than maximised.
For example, versions before 1.8 are not compatible with 1.22, let alone a small change!

https://go.dev/play/p/KTHiMoUDAJY

// Isn't this function funny???
func IsNilSetNil[T any](a *T) {
	var v T
	if IsNil(v) && IsNil(*a) {
		//Ensure that the nil type is consistent
		//*a=v
		*(*unsafe.Pointer)(unsafe.Pointer(a)) = nil
	}
}
func IsNil(a any) bool {
	return (*[2]uintptr)(unsafe.Pointer(&a))[1] == 0
}

@gophun
Copy link

gophun commented Jun 9, 2024

The compiler fixes its not-so-big change, leaving it to go2 (or go3go4go5... Waiting for someone to fix it later?)

There won't be a Go 2: https://go.dev/blog/compat#go2

It also creates version variability, and version change variability should be minimised rather than maximised. For example, versions before 1.8 are not compatible with 1.22, let alone a small change!

return (*[2]uintptr)(unsafe.Pointer(&a))[1] == 0

Unsafe code is not covered by the compatibility promise: https://go.dev/doc/go1compat#expectations

"Use of package unsafe. Packages that import unsafe may depend on internal properties of the Go implementation. We reserve the right to make changes to the implementation that may break such programs."

@atdiar
Copy link

atdiar commented Jun 9, 2024

@gophun I think OP is referring to a conversation that was had on another (now closed) issue.
Seems to have tried to prototype a simulated change to the semantics of nil comparison for interface typed and concrete typed values.

It's appreciated.

As discussed in that issue, it can be implemented in a forward compatible way but not sure it is worth it.

The issue being that it would somehow impose a version on the code examples found at large since semantics would be substituted.

To be fair, one advantage would also be that we could remove the need for errors.Is and errors.As in favor of already established operations.

But hey, this probably has to be examined in the context of a larger potential revamp of error handling if required and that can't happen if it is not frictionless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants