6 ms·
From an API designer's standpoint (especially if that API has paying customers), Hyrum's Law is something that has to be taken into account. But from a user's s
by AdamH12113 1y ago
From an API designer's standpoint (especially if that API has paying customers), Hyrum's Law is something that has to be taken into account. But from a user's standpoint, it is engineering malpractice, plain and simple. At the very least, relying on quirks of someone else's implementation is a risk that should be understood and accounted for, and no one has any reasonable grounds for complaint if those quirks suddenly change in a new version.
- kccqzy 1y agoMalpractice? It's usually just plain old bugs unintentionally written that way.
- breppp 1y agoDepends on the product. Sometimes you are completely dependent on an API ecosystem (iOS, Android, Windows) where the only way to achieve something is a quirk
- Ygg2 1y ago> But from a user's standpoint Not true generally. One man's engineering malpractice is another man's clever hack. Users of Windows 95 complained that Windows 95 broke SimCity. What did Windows 95 break? It fixed an obscure allocator bug SimCity was relying on. Users loved Windows 95, for ""fixing"" this. How was it fixed? By introducing an obscure switch to old allocator if it detected SimCity in the app name. https://arstechnica.com/gadgets/2022/10/windows-95-went-the-extra-mile-to-ensure-compatibility-of-simcity-other-games/ https://arstechnica.com/gadgets/2022/10/windows-95-went-the-...
- bigstrat2003 1y agoDifferent users. The users that GP was accusing of malpractice would be the Maxis devs in this case, not the end users who were trying to install SimCity on their Windows 95 machine. Microsoft has a commitment to backwards compatibility that I think is going too far, but I understand why. Raymond Chen has explained that if a user buys the new version of Windows and their programs stop working, they will blame MS regardless because they don't have any way to know it's the program's fault. So MS is incentivized to go out of their way to enable these other programs' bad behavior, because it keeps their (Microsoft's) customers happy.
- Ygg2 1y ago> Different users. But same principle. Everyone loves for someone else to maintain backwards (and forwards compatibility). > The users that GP was accusing of malpractice would be the Maxis devs in this case, not the end users who were trying to install SimCity on their Windows 95 machine And Windows devs aren't to blame for backporting buggy allocators? If SimCity depended on buggy behavior was malpractice, what the hell is backporting bugs? Exporting malpractice?
- patrickmay 1y agoExactly. Hyrum's Law should always be paired with Postel's Law: Be conservative in what you do, be liberal in what you accept from others.
- chuckadams 1y agoBeing liberal in what you accept also leads to users depending on you accepting marginal input that exploits implementation quirks, either because the quirks get the job done or for more nefarious reasons.
- bigstrat2003 1y agoYeah, I definitely don't agree with the "be liberal in what you accept" paradigm. It's worth it to force users to send correctly-formed data, IMO.
- hinkley 1y agoIt's also worth writing yourself some smoke tests that tell you when your very important customer starts sending total garbage to your servers and expects you to just handle it because they're paying you instead of the other way around. Even a couple hours of additional warning that you're about to get pulled into an uncomfortable conference call can greatly improve outcomes.
- hinkley 1y agoThere's a veritable sewer in the area where Hyrum and Postel intersect.
- don-code 1y agoI don't think such usage is malicious, so much as ignorant - it's sometimes hard to know that a behavior _isn't_ part of the API, especially if the API is poorly documented to begin with. I maintain a number of such poorly-documented systems (you could, loosely, call them "APIs") for internal customers. We've had a number of scenarios where we've found a bug, flagged it as a breaking change (which it is), said "there's _no way_ anybody's depending on that behavior", only to have one or two teams reach out and say yes, they are in fact depending on that behavior. For that reason, we end up shipping many of those types of changes ship with a "bug flag". The default is to use the correct behavior; the flag changes the behavior to remain buggy, to keep the internal teams happy. It's then up to us to drive the users to change their ways, which.. doesn't always happen efficiently, let's say.
- twodave 1y agoHard disagree. If my users are exploiting some unintended, unannounced part of my API then me patching that out is something they’re just going to have to deal with. In well-described systems these sorts of behaviors lead to nasty bugs down the line, sometimes months in the future (e.g. “Huh, why aren’t my tax reports tying out?”).
- partdavid 1y agoI think you're agreeing with GP, not disagreeing.
- twodave 1y agoI was disagreeing with the notion that this law has to be taken into account. I suppose that’s true for certain software, but if e.g. Apple can get away with breaking these use cases then I don’t see why, as an API designer, I should care either.
- bryanrasmussen 1y agoI think this really depends on who your customers are and how they pay for your services.
- RyanCavanaugh 1y agoThe problem is that people commonly don't even realize they're depending on implementation quirks. For example, they write code that unintentionally depends on some distantly-invoked async tasks resolving in a certain order, and then the library implementation changes performance characteristics and the other order happens instead, and it creates a new bug in the application.
- throw0101c 1y ago> From an API designer's standpoint (especially if that API has paying customers), Hyrum's Law is something that has to be taken into account. How good-of-an-idea / best practice is API versioning? /api/v1/foo /api/v2/foo What are the pluses and minuses?
- detaro 1y agoyou end up with a lot of versions if you version everything that could change some non-guaranteed behavior in some corner case.
- ad_hockey 1y agoA couple of considerations are: - You have to decide whether to bump the entire API version or only the /foo endpoint. The former can be a big deal (and you don't want to do it often), the latter is messy. Especially if you end up with some endpoints on /v1 (you got it right first time) while others are on /v4 or /v5. Some clients like to hard-code the URL prefix of your API, including the version, as a constant. - You still have to decide what your deprecation and removal policy will be. Does there come a time when you remove /api/v1/foo completely, breaking even the clients who are using it correctly, or will you support it forever? It's not easy at all, especially if you have to comply with a backwards compatibility policy. I've had many debates about whether it's OK to introduce breaking changes if we consider them to be bug fixes. It depends on factors like whether either behaviour is documented and subjective calls on how "obviously unintended" the behaviour might be.
- 8n4vidtmkvmk 1y agoI'm one of those users of 10-year deprecated APIs. Thank you for not breaking me. If it works, it works.
- cogman10 1y agoPlus, easy to see that you might have to do something different to move over to v2 as client. Minus, You will support v1 forever. It's almost impossible to make it go away.
- gwd 1y ago> At the very least, relying on quirks of someone else's implementation is a risk that should be understood and accounted for, and no one has any reasonable grounds for complaint if those quirks suddenly change in a new version. It's almost always unintentional. Someone wrote some code, it works, they ship it, not realizing it only works if the list comes back in a specific order, or with a specific timing. Then a year or two later they do some updates, the list comes back in a different order, or something is faster or slower, and suddenly what worked before doesn't work. This is why in Golang, for instance, when you iterate over map keys, it purposely does it in a random order -- to make sure that your program doesn't accidentally begin to rely on the internal implementation of the hash function. ETA: But of course, that's not truly random, just pseudorandom. It's not impossible that someone's code only works because of the particular pseudorandom order they're generating, and that if Golang even changes the pseudorandom number generator they're using to evade Hyrum's Law that someone's code will break.
- RyanCavanaugh 1y agoThere's probably at least one game out there somewhere that uses Go's map iteration order to shuffle a deck of cards, and would thus be broken by Go removing the thing that's supposed to prevent you from depending on implementation details.
- deathanatos 1y agoIntent enters into it when someone complains about something that is obviously out of the specification breaking. Prior that, yeah, that's just a bug. > This is why in Golang, for instance, when you iterate over map keys, it purposely does it in a random order It could be that Go's intentions are different here, but IIRC languages will mix randomization into hashtables as it is otherwise a security issue. (You typically know the hash function, usually, so without randomization you can force hash collisions & turn O(1) lookups into O(n).)
- CobrastanJorji 1y agoA counterexample would be Python, where dictionaries maintain their insertion order.
- hinkley 1y agoI was a Java user when Java 5 came out. Java 5 had a new hashtable implementation, and that implementation was also used for the reflection API. That was an era where lots of testing code barely worked, and what we found over and over again is that we had tests that were dependent on each other and the tests only passed because they ran in a particular order. And now Java 5 changed the order in which the test functions were being enumerated in the test files. Oops.