Skip to content
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

proposal: change the definition of zero value, and the semantics of reflect.Value.IsZero are used to compare any type of zero value #63552

Closed
qiulaidongfeng opened this issue Oct 15, 2023 · 12 comments

Comments

@qiulaidongfeng
Copy link
Member

qiulaidongfeng commented Oct 15, 2023

Proposal: change the definition of zero value, and the semantics of reflect.Value.IsZero are used to compare any type of zero value

Author: @qiulaidongfeng

Last updated: 2023-10-15

Background

This proposal aims to provide a way to compare whether any type of value is a zero value of this type.

This is an alternative solution proposed for #61129.

Proposal

Change the definition of zero to:
For type t, all the values with 0 bits of this type are called zero values of this type.
Specifically, the zero value of int type is 0,and the zero value of pointer type is nil.

Change of reflect
reflect.Value.IsZero returns true when all bits of the value are 0, otherwise it returns false.

The compiler optimizes reflect.Value.IsZero to achieve performance equivalent to that of using = =.

Implementation

@qiulaidongfeng realize this proposal.

@gopherbot gopherbot added this to the Proposal milestone Oct 15, 2023
@seankhliao
Copy link
Member

I think our recent acceptance of #61827 means this cannot be feasible.

@qiulaidongfeng
Copy link
Member Author

I think our recent acceptance of #61827 means this cannot be feasible.

Perhaps the LanguageChange tag should be added.
Should I use the go2 template? Or is it like #60078 not using the go2 template?

@ianlancetaylor
Copy link
Member

I'm not sure I understand the language change here, but I'm also not sure that it matters. We aren't going to change what the meaning of "zero value" in the language.

If I understand correctly, this is basically #61129, except that instead of introducing a new builtin iszero we effectively make reflect.IsZero into a builtin. That is just an optimization, and doesn't need to be a proposal.

@qiulaidongfeng
Copy link
Member Author

qiulaidongfeng commented Oct 15, 2023 via email

@ianlancetaylor
Copy link
Member

The intention of this proposal is that the zero value of a type is the value where all bits of this type are zero

That is a statement about the language.

So reflect. Value. IsZero is equivalent to the following code

That is a statement about the implementation.

We aren't going to change the language. That would not be backward compatible. So we need to be clear about whether you are suggesting a change to the language or not.

As far as the implementation goes, as @seankhliao noted earlier, if we change reflect.Value.IsZero as you suggest, that would mean that it would return false for a negative floating point zero. Today it returns true, though that is a recent change. reflect.Value.IsZero also returns true if a struct has a field named _ that holds a non-zero value. It also returns true for a string of length zero, even if the string pointer field is set to a non-nil value. So you are proposing a change that seems both subtle and hard to explain.

@qiulaidongfeng
Copy link
Member Author

The intention of this proposal is that the zero value of a type is the value where all bits of this type are zero

That is a statement about the language.

So reflect. Value. IsZero is equivalent to the following code

That is a statement about the implementation.

We aren't going to change the language. That would not be backward compatible. So we need to be clear about whether you are suggesting a change to the language or not.

As far as the implementation goes, as @seankhliao noted earlier, if we change reflect.Value.IsZero as you suggest, that would mean that it would return false for a negative floating point zero. Today it returns true, though that is a recent change. reflect.Value.IsZero also returns true if a struct has a field named _ that holds a non-zero value. It also returns true for a string of length zero, even if the string pointer field is set to a non-nil value. So you are proposing a change that seems both subtle and hard to explain.

Yes, the proposal includes language changes.

@earthboundkid
Copy link
Contributor

In my tests, reflect.Value.IsZero was about 50x slower than x == 0. If that gap could be narrowed, I would be happy, but it seems difficult to do.

@ianlancetaylor
Copy link
Member

Yes, the proposal includes language changes.

Can you give an example of a program that would change behavior if we adopt this proposal? Thanks.

@zigo101
Copy link

zigo101 commented Oct 17, 2023

The intention of this proposal is that the zero value of a type is the value where all bits of this type are zero

One more counter example: https://go101.org/article/unofficial-faq.html#zero-values-zero-bytes

@qiulaidongfeng
Copy link
Member Author

Yes, the proposal includes language changes.

Can you give an example of a program that would change behavior if we adopt this proposal? Thanks.

https://go.dev/play/p/PD-jF82PRrY?v=gotip

-0.0 will not be a zero value.

If a string pointer is not nil, it is not a zero value.

@ianlancetaylor
Copy link
Member

Thanks. If I understand your example correctly, you are suggesting that the behavior of reflect.Value.IsZero would change. That is not a language change. It is a library change.

It is also not a change that we are going to do. We just adopted #61827. We're not going to reverse that decision without some clear reason to do so.

Thanks.

@qiulaidongfeng
Copy link
Member Author

Withdraw this proposal.

@golang golang locked and limited conversation to collaborators Oct 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants