Even errors.Is won’t really save you. Anecdotally, admittedly, but I still come across people running regexes against errors to extract filenames and other data. errors.Join helps as long as you can rely on the libraries returning the error to actually return an error struct with actual context on the issue rather than using errors.New and fmt.Errorf everywhere. At this point, Go errors have essentially mutated into a half-assed version of Java checked exceptions where you can’t even tell from the signature what you’re meant to handle.
Well… Now you can actually depend on the fact that the randomization occurs, or even that it gives the distribution you want.
But actually this is a bad idea (even if compatibility is not a concern). Once I was lazy to write proper randomization and just tried to rely on the fact that Go randomizes maps already. Then I ended up with a map consisting of two values, and the distribution was extremely skewed:
package main
import "fmt"
func main() {
m := make(map[int]int)
m[0] = 0
m[1] = 1
for range 10000 {
for k := range m {
fmt.Println(k)
break
}
}
}
This code prints 0 in something like 90% of iterations, so the distribution is quite skewed. I ended up writing a proper randomization in my code.
There are a lot of instances of this in net/http that don’t reference Hyrum’s law too. It gave me a newfound appreciation for the Go maintainers efforts to not break people’s code.
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
The contract defines the guarantees. Not part of the contract, not guaranteed.
It is, separately, and commonly, true, that “all observable behaviors of [the] system will be depended-on by somebody”. That’s Hyrum’s Law, sure. But Hyrum’s Law describes a pathological relationship between producer and consumer(s), it doesn’t define a contractual expectation.
Software authors get to say what their software does or doesn’t support. Observable behavior isn’t a contract.
Many (most?) people here will already know what Hyrum’s law is, but I found the link in the following striking:
I’m guessing a lot of these usages predate
errors.Is. If the errors were wrapped you would not have been able to compare them directly.https://go.dev/blog/go1.13-errors
Even
errors.Iswon’t really save you. Anecdotally, admittedly, but I still come across people running regexes against errors to extract filenames and other data.errors.Joinhelps as long as you can rely on the libraries returning the error to actually return an error struct with actual context on the issue rather than usingerrors.Newandfmt.Errorfeverywhere. At this point, Go errors have essentially mutated into a half-assed version of Java checked exceptions where you can’t even tell from the signature what you’re meant to handle.Most famously, ranging over a go map returns keys in a random order specifically to prevent Hyruming: https://stackoverflow.com/questions/55925822/why-are-iterations-over-maps-random/55925880#55925880
Well… Now you can actually depend on the fact that the randomization occurs, or even that it gives the distribution you want.
But actually this is a bad idea (even if compatibility is not a concern). Once I was lazy to write proper randomization and just tried to rely on the fact that Go randomizes maps already. Then I ended up with a map consisting of two values, and the distribution was extremely skewed:
This code prints
0in something like 90% of iterations, so the distribution is quite skewed. I ended up writing a proper randomization in my code.I wrote “
// Due to Hyrum's law, this text cannot be changed.” AMA.See https://blog.carlana.net/post/2022/golang-119-new-features/#new-httpmaxbyteerror for an explanation.
There are a lot of instances of this in net/http that don’t reference Hyrum’s law too. It gave me a newfound appreciation for the Go maintainers efforts to not break people’s code.
[Comment removed by author]
[Comment removed by author]
The contract defines the guarantees. Not part of the contract, not guaranteed.
It is, separately, and commonly, true, that “all observable behaviors of [the] system will be depended-on by somebody”. That’s Hyrum’s Law, sure. But Hyrum’s Law describes a pathological relationship between producer and consumer(s), it doesn’t define a contractual expectation.
Software authors get to say what their software does or doesn’t support. Observable behavior isn’t a contract.