-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
spec: add untyped builtin zero #61372
Comments
Change https://go.dev/cl/509995 mentions this issue: |
Assuming that you prefer I personally find |
I would really like for the spec and builtin change to include guidance on this. That is, I assume we want "idiomatic Go" to not replace most uses of We really want to discourage rewriting |
An alternative is to adding |
FWIW, I would still prefer #21182 here ( |
I am not a super smart guy but, I do think explaining Secondly, I think standard cmp package shouldn't be reasoning behind any change because we as developers now going to bump into same package names with 1.21 (because we use google/go-cmp primarly for our testing and IDEs will show up 2 results now, did you mean this or that etc), I am personally not happy with 1.21's cmp package direction Thirdly, I think explaining zero as a concept over struct{} will be harder for everyone and in most cases, we never return allocated struct and error at the same time, it should be the dev who is assigning to a default when error occurs, not the other way around. I always never liked returning apologies for the noise from me |
I prefer |
FWIW I don't have strong opinions about how to spell a universal zero value - I'm fine with any color for that bikeshed.
The justification isn't the The I think it's fair to criticize arguments like the explainability or readability of |
this proposal would also satisfy #26842. @rsc would accepting this proposal also involve changing cmp.Or to accept any type and use @josharian #21182 could be additionally accepted. It would be less needed than it is now but there's still an argument to its utility and if it were accepted instead of this proposal there'd still be a need for the additional functionality contained in this proposal. |
I like this a lot. I also like What I almost want is for What I really want is "zero is a universal zero that you can use except when you know you are thinking about a thing in pointer terms, in which case you want nil". Although thinking about it more, at least two cases where I currently use nil (slices, maps), I think "zero" would be comparably/similarly expressive. I am now very conflicted on whether I think it's more consistent to call the zero value for a slice |
Okay but thinking about it more, I have concluded: I would also be fine with just extending Observation: That you can use |
Could it be just 0 instead of an identifier? ( |
@seebs I think it would be interesting to allow |
A linter to complain about |
|
It might be funny business if |
Why won't What guidance do you propose to give for when 0 vs. zero and nil vs. zero should be used? In other words, what would be idiomatic? For example, for I'm concerned by the direction the language is evolving. I see non-orthogonal features like this being added instead of existing features being generalized. There is already a zero value in Go: nil. If you lump all the built-in number types together, most built-in types have a nil value. Numbers, strings, arrays, and structs are the exception. Instead of adding something new to solve this one problem, let's generalize what we already have: make nil work for all built-in types. This has been proposed many times by many people. I'm disappointed that this proposal didn't address why this obvious solution won't work. My vote is no until it's changed to do so.
As an aside, I don't agree that coming up with a good name is bikeshedding. Naming is often characterized as one of the two hard things in computer science. Whether or not you agree with that quotation, naming is indeed important, and entirely relevant to the quality of a software design, as opposed to a nuclear power plant design committee getting derailed by the paint color for a bike shed. |
I would write |
Currently, it works because |
I feel like |
Some have favored removing the restrictions on So often have I refactored |
FWIW there is more to the bikeshed analogy than just the importance of the question. But, in any case, I was merely trying to express that it doesn't matter to me. I want something to happen and I find |
So, I think the messiest aspect of this is roughly the behavior in ambiguous contexts. If you're returning an interface value, then I could see a hypothetical benefit to a Right now, if you are actually returning an interface type, and you have a lot of So I think |
Returning |
The only thing that is not possible today is the zero value comparison, at least not without To create a generic zero value That's why I'm in favor of an |
I think if |
You're right. At the same time, even in the spec, the zero value is nil for this type. Not even typed nil although it probably is. No one really uses a type conversion. Still, in usage, we already have many zero values for structs and zero is actually not an identifier for them. But in that case, I'd really rather have a predicate or something else. It's a bit confusing. |
This discussion has made clear that we're not ready for this change. Retracting the proposal. |
@rsc wait, can you elaborate a bit? You said in the last message that "No new information has been presented since the proposal was accepted.". And now it suddenly closed and retracted. What changed since then? |
The new information was the sheer lingering of this thread. I'm sad about the decision because I liked zero, but I can't fault the reasoning. |
If we apply the same reasoning to the generic proposal, we would never got generics. As well as This proposal had overwhelming support, few edge cases, it pas properly discussed and accepted. It is Russ right to retract it, because it's his proposal. But I'm going to admit that closing and retracting things like that, without any explanation, is demotivating for all who participated in discussion. |
I don't think that the comparison with generics is quite right. There were several public proposals about generics that had a great deal of discussion and were then withdrawn and reconsidered. It's true that they weren't formally accepted, but the general idea was the same: we didn't move forward with generics until there was broad (though not universal) agreement. And I wouldn't say that this proposal was withdrawn without explanation. The explanation was that many people still disagree with the proposal, as can be seen in the discussion on this issue. The acceptance may have been premature, or the acceptance may have led people to think further about it and led them to disagree. |
With all due respect, that would not be the first accepted proposal where many people disagreed.
And that contradicts @rsc notes about "Reconsideration". That also means that with sufficient repeating of the same points from the same people any, even accepted, proposal can be declined in the end. What I'm trying to say, it's IMHO wrong to say "we are not going to reconsider our decision until new data arrives" and then reconsider it without any sort of explanation about what sort of new data arrived. That also kills any initiative to participate in any proposal discussion since rules of accepting/declining/reverting are arbitrary and can change at any point. P.S. With this and #62487 both retracted, probably some Google internal discussion happened which lead to this? And if so, why not share the summarized details? |
The goal of the proposal process, as described at https://go.dev/s/proposal, is to reach consensus. If the proposal process is accepting ideas where many people disagree, then I hope that many more people agree, or at least that it is clear that the proposal is important for some other reason. Are there specific proposal that you have in mind?
Respectfully, more than one person has explained what the new data was. It's true that the proposal committee (which is not only Googlers) and others discussed this issue off line. That discussion amounted to: we have not reached a consensus here. And the evidence for that was the continued discussion on this issue. I'm sorry that you feel that this kills any initiative to participate in any proposal discussion. I hope that most people don't feel that way. |
I think the main source of confusion was really just that @rsc announced its withdrawal kind of suddenly. If he had just had an extra few words in there, even something like
it wouldn't have been as confusing. |
Then why close the discussion instead of just retracting the acceptance and saying where we're at and where we go from here? It seems like you're saying the approach in this thread is now off the table entirely. |
Personally I don't think this approach is off the table. I do think that we need to step back and reconsider the problem. We know from experience that proposal issues are not good places to discuss a problem. This issue already has over 300 comments. Keeping this issue open is not a useful path forward. |
And that what exactly is missing. Just like @DeedleFake said - a few phrases explaining, that, despite proposal being accepted, consensus was not reached neither here nor in committee internally and because there is no clear part forward, proposal is un-accepted and closed for a time being. Small explanation is all that needed. The reason for this need is also quite simple - Russ made a statement that merely disagreeing or continued discussion of the same points on accepted proposal is not enough to reverse it. But then suddenly it is.
#59488 (comment) comes to mind, where there was no agreement about |
Someone made me notice that this proposal was retracted, but I left the impression that this was accepted. Apparently, there are tons of discussions that happened after the proposal was accepted, but it is not entirely clear, neither from this proposal (top message, or have to click through "load more") nor from #33502. Considering this special case, @rsc, could you perhaps add the decision to #33502 as well so that people get to know that the status is retracted rather than accepted? |
Perhaps these kind of comments are not really wanted, but I wish to express my hope that this returns in some form or another, having to change the empty values in my return statements is one of my current annoyances with the language. #21182 does indeed look interesting. |
I'm really appreciative of you @rsc, for suggesting something, getting it accepted, and having the humility to retract it. Good move. |
I don't want the language to get any more complicated. |
@jhw0604 This issue is closed. We're not adding a built-in zero. |
I propose to add a new predeclared identifier
zero
that is an untyped zero value. Whilenil
is an untyped zero value restricted to chan/func/interface/map/slice/pointer types,zero
would be an untyped zero value with no such restrictions.The specific rules for
zero
mimicnil
with fewer restrictions:zero
is assignable to any variable of any type T that does not already have a short zero (0, "", nil), including when T is a type parameter with constraint any.zero
when it cannot already be compared to a short zero (0, "", nil), again including when T is a type parameter with constraint any.That's it. That's all the rules.
Note that assignability includes function arguments and return values:
f(zero)
andreturn zero, err
are valid.See CL 509995 for exact spec changes.
This proposal addresses at least three important needs:
Referring to a zero value in generic code. Today people suggest
*new(T)
, which I find embarrasingly clunky to explain to new users. This comes up fairly often, and we need something cleaner.Comparing to a zero value in generic code, even for non-
comparable
type parameters. This comes up less often, but it did just come up incmp.Or
(cmp: add Or #60204).Shortening error returns:
return zero, err
is nicer thanreturn time.Time{}, err
.More generally, the zero value is an important concept in Go that some types currently have no name for. Now they would:
zero
.Because zero is not valid anywhere 0, "", or nil are valid, there will be no confusion about which to use.
I'm not claiming any originality in this proposal. Others have certainly suggested variants in the past, in quite long discussions. I'm not aware of any precise statement of the exact rules above, but I won't be surprised if one exists.
A brief comparison with earlier proposals:
iszero(x)
. This proposal usesx == zero
instead.zero(T)
is a zero of type T. This proposal uses plainzero
which enables use in comparison and avoids a usually unnecessary(T)
. In non-assignment, non-conversion contexts where a type must be written, this proposal usesT(zero)
, which seems more idiomatic to me at least.{}
. Later discussion in also consideredzero
._
.The text was updated successfully, but these errors were encountered: