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

> You could of course argue that by preventing the user from doing certain things you avoid some classes of errors. However, I will in turn argue that by forcing the user to write code for the benefit of the type checker often results in convoluted solutions that are hard to understand and maintain. So, you just end up trading one set of problems for another.

Funny, this is exactly the opposite of my take from a type system like Haskell's. The thing is, whether it's enforced by types or not, the same invariants exist in your code. The only difference is that in one case they are checked explicitly at compile time, and the other case they are hidden and can blow up your programs.

If anything, explicit invariants make code easier to maintain and understand.




Except that they're not the same. Static typing restricts you to a set of statements that can be verified by the type checker. This is a subset of all valid statements, otherwise you could just type check code in any language at compile time.

Static typing makes many dynamic patterns either difficult or impossible to use. For example, Ring middleware becomes pretty much impossible in a static language https://github.com/ring-clojure/ring/wiki/Middleware-Pattern...

The pattern here is that the request and response are expressed as maps. The request map is passed through a set of middleware functions, and each one can modify this map in some way.

A dynamic language makes it possible to write middleware libraries that know absolutely nothing about each other, and compose seamlessly. A static language would require you to provide a full description of every possible permutation of the request map, and every library would have to conform to it. This creates coupling because any time a library needs to create a new key that only it cares about, the global spec needs to be modified to support it.

My experience is that immutability plays a far bigger role than types in addressing the problem of maintainability. Immutability as the default makes it natural to structure applications using independent components. This indirectly helps with the problem of tracking types in large applications as well. You don't need to track types across your entire application, and you're able to do local reasoning within the scope of each component. Meanwhile, you make bigger components by composing smaller ones together, and you only need to know the types at the level of composition which is the public API for the components.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: