5 ms·
> My biggest problem with the whole static typing trend is that it makes developers feel empowered to break backwards compatibility when it would be trivial to
by zahlman 11mo ago
> My biggest problem with the whole static typing trend is that it makes developers feel empowered to break backwards compatibility when it would be trivial to keep things working.
I don't see the connection you're drawing here.
- ljm 11mo agoRather, static typing empowers backwards compatibility, right? Because it lays out the contract you have to meet on the interface. No contract? No enforced compatibility.
- dec0dedab0de 11mo agoIt is a way to signal to other developers that your code changed, which is better than not saying anything. But it seems to make library developers more comfortable with making breaking changes. It's like they're thinking 'well it's documented, they can just change their code when they update and get errors in their type checker/linter.' When I think they should be thinking, 'I wonder what I could do to make this update as silent and easy as possible.' Of course, we all have different goals, and I'm grateful to have access to so many quality libraries for free. It's just annoying to have to spend time making changes to accommodate the aesthetic value of someone else's code.
- ljm 11mo agoI think the only time I’ve ever seen this is in a JS library, where each major version bump is practically a different library altogether because it’s a complete rewrite, and these days is a wrapper around some Rust thing. Not even JS alone. I blame the enforcement of semantic versioning, as if a version of code simply had to be a sequence of meaningful numbers.
- thayne 11mo agoBut it also makes it easier for library developers to identify that a change is breaking. Without static types you can easily make a change you think is fine, but it ends up breaking user code because they depended on something you didn't expect. Granted, static typing doesn't completely solve that problem, there can still be changes in behavior that break things, but it is a useful tool in identifying certain classes of breaking changes.
- dec0dedab0de 11mo agoyes, that is my point.
- 9rx 11mo agoIf you are using a language with a complete type system, sure. But who uses those? When using the languages people actually use in the real world, not really. Consider a simple example where the contract is that you return an integer value from 1 to 10. In most languages people actually use, you're going to be limited to using an integer type that is only constrained by how many bits it is defined to hold, which can be exploited later to return 11, unbeknownst to the caller's expectations. There are a small number of actually-used languages that do support constraining numeric types to a limited set of values, but even they fall apart as soon as you need something slightly more complex. This is what tests are for. They lay out the contract with validation of it being met, while also handily providing examples for the user of your API to best understand how it is intended to be used.
- IceDane 11mo agoMore than anything, this reveals your lack of understanding of modern languages and type systems. TypeScript, for example, is one of the most widely used languages in the world. It has an incredibly powerful type system which you can use to model a lot of your invariants. By leaning on patterns such as correct-by-construction and branding, you can carry around type-level evidence that e.g. a number is within a certain range, or that the string you are carrying around is in fact a `UserId` and not just any other random string. Can you intentionally break these guarantees if you go out of your way? Of course. But that's irrelevant, in the same way it is irrelevant that `any` can be used to break the type system guarantees. In practice, types are validated at the boundaries and everything inside can lean on those guarantees. The fact that someone can reach in and destroy those guarantees intentionally doesn't matter in practice.
- 9rx 11mo agoTypescript is one of the actually-used languages that supports constraining the integer, albeit in a pretty awkward way. type Decade = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 But now try defining a type that enforces a RFC-compliant email address... There are languages with proper type systems that can define full contracts, but Typescript is not among them. Without that, you haven't really defined a usable contract as it pertains to the discussion here. You have to rely on testing to define the contract (e.g. assert the result of the 'generate email' function is RFC-complaint). And Typescript most definitely does. Testing is central to a Typescript application. It may have one of the most advanced type systems found in languages actually used, but that type system is still much too incomplete to serve as the contract. Hence why the ecosystem is full of testing frameworks to help with defining the contract in tests.
- eyelidlessness 11mo agoDisclaimer: I’m a strong advocate for static typing. I absolutely see the connection. One of the advantages of static typing is that it makes a lot of refactoring trivial (or much more than it would be otherwise). One of the side effects of making anything more trivial is that people will be more inclined to do it, without thinking as much about the consequences. It shouldn’t be a surprise that, absent other safeguards to discourage it, people will translate trivial refactoring into unexpected breaking changes. Moreover, they may do this consciously, on the basis that “it was trivial for me to refactor, it should be trivial to adapt downstream.” I’ll even admit to making exactly that judgment call, in exactly those terms. Granted I’m much less cavalier about it when the breaking changes affect people I don’t interface with on a regular basis. But I’m much less cavalier about that sort of impact across the board than I’ve observed in many of my peers.
- layer8 11mo agoI could see some maintainers being encouraged by static typing to introduce breaking changes, as long as the changes ensure compile-time breakage. However, that’s only an option in languages without dynamic linking. So it’s the combination of static typing and static linking that would encourage that.
- anonymars 11mo agoIndeed. C# is statically typed. Python is not. Which is the one with a notorious backwards-incompatibility story?
- shakna 11mo agoBoth. https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010 https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/br...
- mrsmrtss 11mo agoCome on, those are very rare and minor things that are very easy to fix.
- shakna 11mo agoPort me something from DotNet 9.0 and say that again. https://learn.microsoft.com/en-us/dotnet/core/compatibility/10.0 https://learn.microsoft.com/en-us/dotnet/core/compatibility/...
- mrsmrtss 11mo agoWe have already ported many projects from .NET8 and .NET9 to .NET10 with close to zero issues.