Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The issue is that the API can change unintentionally, breaking clients because of an implementation change.


It seems that you're talking about a code that is exposed to some third-party clients where you need to maintain compatibility. This is, of course, a valid concern, and you're absolutely right that this layer, exposed to third party clients absolutely does need increased level of friction.

However, most applications don't have any such exposure, all of their code is consumed internally. And even when they do, their external API surface which is actually exposed as some REST or ABI is minuscule in comparison to all the internal APIs — method calls and types that are never exposed anywhere.

I think that this problem, which is certainly a valid one, should be solved with methods which would not negatively affect developer experience of working with 99% of all the completely private APIs that don't need to be backwards compatible.


Implementation changes can already break clients, except without checked errors/exceptions, they do so silently.


Yes, certain language designs make it easier to break APIs for clients, just like the one mentioned above. I was pointing out that this is bad and we should try to prevent that from happening


No, the one mentioned above makes it easier to not break clients. A language that exports an API without checked exceptions can change the implementation and break clients silently in production. A language with checked exceptions will not break clients silently, ever. That's strictly superior from a robustness perspective.

If, as a library author, you want to define a strict contract with clients that you never break, then you explicitly specify the exception signature and you don't let the exceptions be inferred. Then if the implementation changes in a way that introduces a new exception that doesn't match the client contract, then the API author gets the error at compile-time.


That depends a bit on the definition I guess - let me explain why:

If you call a method in e.g. Java which is annotated to return a string, then by definition you have to expect the following possible outcomes:

- The method returns a string

- The method throws an exception (or rather: a Throwable)

- The method does not return at all

That's just how it is in Java and also in most other languages. Therefore, throwing an exception must always be expected. Only if there were only checked exceptions and no unchecked exceptions this would be different - but then how do you handle things like Stackoverflow or OOM exceptions?

In fact, if a methods says it returns a string, what that really means is that that it will not return something else than a string. That is the real meaning. It cannot e.g. return an integer. But that's about all the guarantees that it gives.

So you see, it's tricky.

There are however languages where you can really rely on that they do return what they claim. But those languages then force you to prove that a method actually returns within a finite amount of time and such things. Not very practical to use in many cases.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: