-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: cmp: add CompareBool #61643
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
Comments
Alternatively, I guess that has been propsed but I can't find it. |
How often does sorting boolean values arise? Surprised to hear this is a pain point. |
As for your suggestion of a conversion from bool to int, something I have used myself, it's so easy to do that I can't see it needs to be in the standard library. No one's going to get it wrong and it's less text than this reply of mine. Far less. |
I've sorted on bool many times, always on some property like "new" or "featured" that means it should jump to the top of a list presented to a person, but it's never been on just that property: always sort on flag then title/date/etc. I'm not sure how much help this would be in those scenarios unless there was also some kind of I would love bool↔int conversions, though. Not hard to write but neither was min/max and those get to be builtins. I may have even written those more than I have various min/max's |
Part of the problem with a bool->int function is that there are several. In the compiler we have two, one that converts to int64 and one that converts to int32. |
In our migration, ~20% of conversions required expanding the logic for boolean comparisons. |
As another observation. I recently implemented a comparison for protobuf messages, and also wrote this by hand |
This I think is one area where the compiler could do better*, the return early style in simple functions like this causes more branching than necessary, as it fails to realize it could be using conditional sets or moves. The compiler can write this without branches. func CompareBool[T ~bool](x, y T) int {
r := 0
if x != y {
r = 1
if y {
r = -1
}
}
return r
}
|
@dsnet Would you be able to give a couple of concrete examples of this? |
@benhoyt, our examples are very similar to what @jimmyfrasche mentioned. It's wanting to sort on boolean properties. Our situation is networking specific(e.g., whether DNS is set, whether an IP address is v4 or v6, whether a node is rejected, whether a key is revoked, etc.). |
Maybe comparison operators should work on bools. They did in C. false < true. |
Alternatively (or perhaps additionally), we could permit |
I think this would worry me a bit ... for I think |
@AndrewHarrisSPU just wondering out of curiosity what would be dangerous about int(false) being 0 and int(true) being 1? |
For example, if int(bool(int(-1))) is 1, it’s greater than int(bool(int(0))) - I’ve never missed this kind of thing in Go. |
@AndrewHarrisSPU isn't the issue the conversion of a number into a boolean? |
|
@AndrewHarrisSPU I don't understand the argument. |
@robpike |
I'd be happy with something like: package math
func Bool[T number](v bool) T {
if v {
return 1
}
return 0
} Although that would still leave the original request as something like cmp.Compare(math.Bool(x.Flag), math.Bool(y.Flag)) |
The package docs for cmp say "Package cmp provides types and functions related to comparing ordered values." The simple fact is that bools are not ordered values in Go. I don't believe it makes sense to add "plus a special case for bools" to the package summary. If we changed the language to make bools ordered, then cmp.Compare would start supporting them. Until that point, it seems very wrong to take a package whose entire API is:
and add a special-case As many people have already noted, it would be trivial to put CompareBool in any code that needs it, or in a third-party package. That seems much better than adding a special-case to this otherwise very well-defined package. As Ian noted, we've also already considered allowing an explicit conversion int(b) for boolean b and any integer type. If we were going to make any change in this area, I think that would be the direction to go, and then people who want comparison of bools can convert them to ints first. But again it is trivial to write that function. #9367 and #45320 both ended up declined for lack of strong evidence. It seems unlikely the situation has changed much since then, but if you do have evidence, opening a new proposal for that seems like the right path. |
This is related to a comment I made: #60204 (comment). |
This proposal has been added to the active column of the proposals project |
Even if we add cmp.Or and expand the scope to "comparing values", the fact remains that bools are not ordered in Go, so ordering them in a library function seems inconsistent. |
For the record, I'm not tied to |
package math
// IversonBracket returns 1 if b is true; 0 otherwise.
func IversonBracket(b bool) int {
if b {
return 1
}
return 0
} https://aplwiki.com/wiki/Ken_Iverson#Iverson_bracket This would have a prominent advocate: "Donald Knuth has argued strongly for its wider use." It should feel right at home next to |
Based on the discussion above, this proposal seems like a likely decline. |
Given that #45320 was closed before the introduction of |
Perhaps it is time to re-litigate the declined proposal #9367 to support explicit If accepted then CompareBool would be |
I mentioned elsewhere that a helper function cannot be used in the construction of a Go constant. |
I filed #62049 as a possible compiler optimization that does constant propagation for bool-to-int conversions. |
It still seems like this one is a decline. I said above:
I think that's still true. |
No change in consensus, so declined. |
Yeah, we had exact the same experience as @dsnet. It's unfortunate that the old reflect-y |
Change https://go.dev/cl/550235 mentions this issue: |
We just did a migration switching over usages of
slices.SortFunc
fromfunc(T, T) bool
tofunc(T, T) int
and noticed that many comparisons between booleans suddenly became more complex.Given that
cmp.Compare
can't be used on bools because bools are notordered
, I propose the addition of:Alternatively, we could add a helper function that converts
false
to0
andtrue
to1
.\cc @bradfitz @danderson
The text was updated successfully, but these errors were encountered: