Live data from Hacker News

No safe efficient ways to do three-way string comparisons in Go

go101.org

91–100 of 154 posts

Re: No safe efficient ways to do three-way string comparisons in Go

#92
post #60

Earlier quoted context omitted.

- Is 1.2.3 > 1.2.3omega? No - Is 1.2.3 > 1.2.3beta? No - Is 1.2.3gamma > 1.2.3? Yes I don't see ambiguity in your examples.

> - Is 1.2.3gamma > 1.2.3? Yes I wrote this example, because I knew the answer. And your interpretation (the same as my initial one) is wrong :) > Pre-release versions have a lower precedence than the associated normal version. [1] https://semver.org/#spec-item-9

Well, if You want to compare strings according to some rules then... write a custom comparator.

Re: No safe efficient ways to do three-way string comparisons in Go

#93

What I don’t understand is that they doing first check for lengths Strings are so common, it’s insane they don’t optimize

Wouldn't the normal implementation for == check lengths? Edit: Never mind, it doesn't: https://github.com/golang/go/blob/d28bf6c9a2ea9b992796738d03... But checking lengths doesn't really help you: it only tells you when strings are not equal, and you would still have to walk the string to see which one is larger/smaller.

> But checking lengths doesn't really help you: it only tells you when strings are not equal, and you would still have to walk the string to see which one is larger/smaller.

Only for a three-way comparison. If all you care about is equality different lengths gives a fast path for inequality.

Re: No safe efficient ways to do three-way string comparisons in Go

#94
post #53
post #41

The optimal version does seem to exist here (per the comment too): https://github.com/golang/go/blob/d28bf6c9a2ea9b992796738d03... So the goal was to intentionally nerf Compare() to discourage code the golang authors considered less clear. I'm not sure bad performance is really discouraging usage though, it just penalizes folks that use stdlib. I wonder if they'd accept a PR to switch to runtime.cmpstring today?

> "intentionally nerf Compare() to discourage code the golang authors considered less clear" If that's true, it further proves that I disagree with the philosophy of the Go designers on pretty much everything. If your language provides multiple ways to do something, they should all be optimized in good faith. To do what you suggested is insane and user-hostile.

> If your language provides multiple ways to do something

Yeah, no. The founding principle of Go is to avoid multiple ways. If multiple ways emerge anyway, move things&people around until one of them becomes strongly preferred.

There's nothing inherently bad about the approach, it's a choice which has costs and benefits.

Re: No safe efficient ways to do three-way string comparisons in Go

#95
post #41

The optimal version does seem to exist here (per the comment too): https://github.com/golang/go/blob/d28bf6c9a2ea9b992796738d03... So the goal was to intentionally nerf Compare() to discourage code the golang authors considered less clear. I'm not sure bad performance is really discouraging usage though, it just penalizes folks that use stdlib. I wonder if they'd accept a PR to switch to runtime.cmpstring today?

Completely OT but, after 5 years of writing Go, TIL you can assign multiple LHS from multiple RHS:

c1, c2 := a[i], b[i]

Re: No safe efficient ways to do three-way string comparisons in Go

#96

What I don’t understand is that they doing first check for lengths Strings are so common, it’s insane they don’t optimize

Because string comparison is usually alphabetic. If a string is longer/shorter it says nothing about its ordering. Even if the lengths are equal, you still need to memcmp them to verify hey are indeed equal. The length doesn't actually get you new information in this context.

I'm assuming encoding and utf-8 normalization and other similar things are not in scope when answering this.

Re: No safe efficient ways to do three-way string comparisons in Go

#97

This is really interesting. I never use three way string comparison, and so I wondered when other programmers use it. (The obvious use case is sorting, but in Go, sort.Interface expects a Less function and sort.Slice accepts a "Less" function, so you won't use it there.) I searched through my random checked out applications to see who calls strings.Compare, and why. Most of them are mistaken sorting. In gVisor, there…

> so the documentation is trying to talk them out of... What documentation though? There's an internal comment but it's not documentation and it's not really arguing against the use of this type of comparison (just against use of the implemented function). If the documentation for this function went on along the lines of "we discourage the use of 3 way compares as we consider it an antipattern, do X instead, there's…

> If the documentation for this function went on along the lines of "we discourage the use of 3 way compares as we consider it an antipattern, do X instead, there's literally no reason to ever use 3 way compares, we know it, here's why..." maybe, but it doesn't.

But it does. It literally says "It is usually clearer and always faster to use the built-in string comparison" and it always said that.

https://pkg.go.dev/strings@go1.5#Compare

https://pkg.go.dev/strings@go1.19.2#Compare

The entire documentation for this function is four short sentences. If my code editor didn't make it easy and natural to see them, I'd rethink my shit right now.

Re: No safe efficient ways to do three-way string comparisons in Go

#98
post #64

Earlier quoted context omitted.

I would understand that if the method was left out. But in this case, a strings.Compare method is provided but the implementation says not to use it. That's the worst of both worlds. The stdlib still has this extra method and users will feel obligated to use it because it exists but the method is inefficient.

The standard library can't ever remove anything because of the Go compatibility promise, and a certain percentage of it is mistakes. Once some functionality is later realized to be poor or incorrect, and the design prevents fixing it, there is not much that can be done other than telling people not to use it anymore. What you refer to as the worst of both worlds is unfortunately inevitable, but at least it's in servi…

That is what happens when they refuse to adopt a deprecation process, even Java, .NET, C and C++ with their high regard for backwards compatibility do have such processes, and have removed features from standard library and languages.

Re: No safe efficient ways to do three-way string comparisons in Go

#100
post #98

Earlier quoted context omitted.

The standard library can't ever remove anything because of the Go compatibility promise, and a certain percentage of it is mistakes. Once some functionality is later realized to be poor or incorrect, and the design prevents fixing it, there is not much that can be done other than telling people not to use it anymore. What you refer to as the worst of both worlds is unfortunately inevitable, but at least it's in servi…

That is what happens when they refuse to adopt a deprecation process, even Java, .NET, C and C++ with their high regard for backwards compatibility do have such processes, and have removed features from standard library and languages.

Go marks features as deprecated, though, both in source code and in the docs. For example, strings.Title() has been deprecated and instead the case package should be used. The backwards guarantee merely means that the feature won't be removed from the library in Go 1.x, but when you write new code you won't use it and the preferred way of doing the same is mentioned in the docs and version notes. I think it's good not to remove deprecated functions within the same major version.
Post reply on HN