Live data from Hacker News

Hyrum’s Law in Golang

abenezer.org

131–140 of 190 posts

Re: Hyrum’s Law in Golang

#131
post #8

This is a good example of "stringly typed" software. Golang designers did not want exceptions (still have them with panic/recover), but untyped errors are evil. On the other hand, how would one process typed errors without pattern matching? Because "catch" in most languages is a [rudimentary] pattern matching. https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

Go has typed errors, it just didn't use it in this case.

They didn't have them when they implemented this code.

Back then, error was a glorified string. Then it started having more smart errors, mostly due to a popular third party packages, and then the logic of those popular packages was more or less* put back to go.

* except for stacktraces in native errors. I understand that they are not there for speed reasons but dang it would be nice to have them sometimes

Re: Hyrum’s Law in Golang

#132
It's interesting that this law is the exact opposite of the Robustness Principle / Postel's Law.

> be conservative in what you send, be liberal in what you accept

If you are liberal in what you accept, you'd better understand the ways in which you've been liberal, and document them (at least) internally, because you're going to have to support all those ways forever, even after huge codebase changes, due to Hyrum's Law.

I try to avoid creating APIs which are "liberal in what they accept" for exactly that reason.

Re: Hyrum’s Law in Golang

#133
post #74

Hyrum's Law is one of those observations that's certainly useful, but be careful not to fixate on it and draw the wrong conclusions. Consider that even the total runtime of a function is an observable property, which means that optimizing a function to make it faster is a breaking change (what if suddenly one of your queues clears too fast and triggers a deadlock??), despite the fact that 99.99999999% of your users w…

I once sped up a very suboptimal routine that from ~100s to ~.1s (it was doing database lookups in a for loop), and that broke the reporting system because the original author had made several asynchronous function calls and assumed they would have all finished running by the time the (formerly) slow routine was done. Figuring out exactly what happened took forever.

Re: Hyrum’s Law in Golang

#134
post #74

Hyrum's Law is one of those observations that's certainly useful, but be careful not to fixate on it and draw the wrong conclusions. Consider that even the total runtime of a function is an observable property, which means that optimizing a function to make it faster is a breaking change (what if suddenly one of your queues clears too fast and triggers a deadlock??), despite the fact that 99.99999999% of your users w…

I think everything you said is totally correct for open source library owners. But let me offer a different perspective: Hyrum’s law is neither a technical contract nor a social contract. It’s an emergent technical property in a sufficiently used system. How you respond to that emergent property depends on the social context. If you are a FOSS maintainer, and an optimization speeds up 99.99% of users and requires 0.0…

Seems like you're saying the same thing, just using "social contract" differently. I think they use social contract not to mean binding, but to highlight the fact that Hyrums Law must be taken in the social context of the project. In the case of large SW company, the social contract would be to not break services, even when folks are misusing an API. And for a popular open source project, it would mean not breaking a widely used behavior, even if it isn't specified or officially supported. Determining the social contract seems to be precisely what you describe as "not a social contract".

Re: Hyrum’s Law in Golang

#135
what I learned from shipping APIs:

1. Clients will do whatever they need to do get their job done, even if it's not the publisher's intended way

2. Clients don't read documentation

3. Bugs will become part of API once enough clients rely on their behavior

4. The number of API calls does not necessarily equate to importance.

---

As such, I aim for the following when developing an API

1. Ship the beta API early and see how they use it to minimize the surprise. (This may not always be possible)

2. In most cases, bump up the major version while supporting the previous version. This means you'll need to define SLA for your API

3. Most clients are OK with breakages as long as they are given enough time to migrate, or the API provider gives them a tool to auto-migrate the code (if that's possible in your product)

Re: Hyrum’s Law in Golang

#136
post #122

Earlier quoted context omitted.

I feel like this is approaching absurdity, if only because something like the total runtime of a function is not under the control of the author of the function. The operating environment will have an impact on that, for example, as will the load the system is currently experiencing. A GC pass can affect it. In short, I wouldn't consider emergent behaviours of a machine as part of an intentional interface or any kind…

Yes, it’s an absurd example to make a point. We don’t normally consider performance in scope for what’s considered a breaking API change and there are good reasons for that, including being non-portable. Performance guarantees are what hard real-time systems do and they’re hardware-specific. (There is also the “gas fee” system that Ethereum has, to make a performance limit consistent across architectures.) But there…

> If the performance impact is bad enough

Even worse, it's possible to select a new algorithm that improves the best-case and average-case runtimes while degrading the worst-case runtime, so no matter what you do it will punish some users and reward others.

Re: Hyrum’s Law in Golang

#137
post #74

Hyrum's Law is one of those observations that's certainly useful, but be careful not to fixate on it and draw the wrong conclusions. Consider that even the total runtime of a function is an observable property, which means that optimizing a function to make it faster is a breaking change (what if suddenly one of your queues clears too fast and triggers a deadlock??), despite the fact that 99.99999999% of your users w…

That used to be a problem in the 1980s. Thus PCs came with a turbo button to slow them down, and 8 bit computers went the entire decade without upgrading their speed even though faster CPUs were available. These days nearly everything runs on more than one CPU and so nobody relies on function runtime (other than is if fast enough). Even in embedded they have been burned by their one CPU going out of production and so…

I found a used copy of Warcraft III and found it was unplayable because the scrolling algorithm ran as fast as possible with no minimum time. Any map bigger than 2x2 screens you could not scroll to the middle.

Re: Hyrum’s Law in Golang

#138
post #83

Earlier quoted context omitted.

One day I will give a lighting talk about the load bearing teapot, or how and why I made HTTP Status 418 a load bearing part of an internal API, and why it was the least bad option considering the constraints.

It’s a classic. Binance will give you 429 errors to back off then 418s to tell you you will be IP banned and then they’ll ban you.

Google’s spiders will punish you for giving them too many 429 responses. It’s hell for hosting sites with vanity urls. They can’t tell they’re sending you 50+ req/s.

It’s practically a protection racket. Only AWS gets the money.

Re: Hyrum’s Law in Golang

#139

Hah, I wrote the crypto/rsa comments. We take Hyrum's Law (and backwards compatibility [1]) extremely seriously in Go. Here are a couple more examples: - We randomly read an extra byte from random streams in various GenerateKey functions (which are not marked like the ones in OP) with MaybeReadByte [2] to avoid having our algorithm locked in - Just yesterday someone reported that a private ECDSA key with a nil public…

The map iteration order change helps to avoid breaking changes in future, by preventing reliance on any specific ordering, but when the change was made it was breaking for anything that was relying on the previous ordering behaviour. IMO this is a worthwhile tradeoff. I use Go a lot and love the strong backwards compatibility, but I would happily accept a (slightly) higher rate of breaking changes if it meant greater…

Java 5 was a fun upgrade for a lot of people because it caused JUnit tests to run in a different order. Due to hashtable changes altering the iteration of the reflected function names.

Don’t couple your tests, kids!

Post reply on HN