Strong static typing, a hill I'm willing to die on

tasn1 pts0 comments

Strong static typing, a hill I'm willing to die on... | Svix Blog

AuthorsNameTom HacohenTwitter@TomHacohen<br>Svix is the enterprise ready webhooks sending service. With Svix, you can build a secure, reliable, and scalable webhook platform in minutes. Looking to send webhooks? Give it a try!

Edit: previous version of this post didn't have "static" in the title to keep it short (but the body did). Added it in the title for clarification.<br>Update: there is now a part 2 about using the type system effectively.<br>I've been writing software for over 20 years, and with every day that goes by I grow more certain that strong static typing is not just a good idea, but also almost always the right choice.<br>There are definitely uses for untyped languages (or language variants), for example they are much nicer when using a REPL, or for throwaway scripts in environments that are already hopelessly untyped (e.g. the shell). In almost every other case, however, strong typing is strongly preferred.<br>There are advantages to not using types, such as a faster development speed, but they pale in comparison to all of the advantages. To that I say:<br>Writing software without types lets you go at full speed. Full speed towards the cliff.

The question around strong static typing is simple: would you rather work a bit more and get invariants checked at compile-time (or type-checking time for non-compiled languages), or work a bit less and have them be enforced at runtime, or even worse not enforced even at runtime (JavaScript, I'm looking at you... 1 + "2" == 12).<br>Getting errors at runtime is a terrible idea. First, it means that you won't always catch them during development. Second, when you do catch them, it will happen in a customer facing manner. Yes, tests help, but writing tests for every possible mistyped function parameter is impossible given the endless possibilities. Even if you could, having types is much easier than testing for wrong types.<br>Types lead to less bugs<br>Types also offer annotations to code that benefit both humans and machines. Having types is a way to more strictly define the contract between different pieces of code.<br>Consider the following four examples. They all do exactly the same thing just with varying level of contract definition.<br>// Params: Name (a string) and age (a number).<br>function birthdayGreeting1(...params) {<br>return `${params[0]} is ${params[1]}!`;

// Params: Name (a string) and age (a number).<br>function birthdayGreeting2(name, age) {<br>return `${name} is ${age}!`;

function birthdayGreeting3(name: string, age: number): string {<br>return `${name} is ${age}!`;

The first one doesn't even define the number of parameters, so it's hard to know what it does without reading the docs. I believe most people will agree the first one is an abomination and wouldn't write code like that. Though it's a very similar idea to typing, it's about defining the contract between the caller and the callee.<br>As for the second and the third, because of the typing, the third will need less documentation. The code is simpler, but admittedly, the advantages are fairly limited. Well, until you actually change this function...<br>In both the second and the third functions, the author assumes the age is a number. So it is absolutely fine to change the code as below:<br>// Params: Name (a string) and age (a number).<br>function birthdayGreeting2(name, age) {<br>return `${name} will turn ${age + 1} next year!`;

function birthdayGreeting3(name: string, age: number): string {<br>return `${name} will turn ${age + 1} next year!`;

The problem is that some of the places that use this code accept user input which was collected from an HTML input (so always a string). Which will result in:<br>> birthdayGreeting2("John", "20")<br>"John will turn 201 next year!"

While the typed version will correctly fail to compile because this function excepts age to be a number, not a string.<br>Having the contract between a caller and callee is important for a codebase, so that callers can know when callees change. This is especially important for an open source library, where the callers and the callees are not written by the same group of people. Without this contract it's impossible to know how things change when they do.<br>Types lead to a better development experience<br>Typing can also be used by IDEs and other development tools to vastly improve the development experience. You get notified as you code if any of your expectations are wrong. This significantly reduces cognitive load. You no longer need to remember the types of all the variables and the function in the context. The compiler will be there with you and tell you when something is wrong.<br>This also leads to a very nice additional benefit: easier refactoring. You can trust the compiler to let you know whether a change you make (e.g. the change in our example above) will break assumptions made elsewhere in the code or not.<br>Types also make it much easier to onboard new engineers to a codebase or library:<br>They can follow the...

name types function string typing code

Related Articles