Hacker News new | ask | show | jobs
by MobiusHorizons 261 days ago
For certain classes of dynamically typed languages the unit test serves the function that a compiler or linter would perform just by running the code on any input to ensure it can run at all. Basically since these checks are runtime instead of compile time, you have to run the code to get even basic syntactical checking. I think ruby, python and JavaScript all used to use unit tests in this way. These days static analysis tooling is much more advanced and can provide much of the same benefit without running the code, but I think this is where the idea of 100% line coverage comes from.

Strong typing certainly doesn’t remove the need for testing, but it does change what type of issues you test for. And for certain classes of boring code that just transform or move data, a single integration test can give you all the assurance you need.

1 comments

That is because typing in this case is converting a semantic (run time) property into a trivial property (T/F).

It is just making a trade off that is often a reasonable pragmatic default, but if taken as an absolute truth, can lead to brittle systems stuck in concrete.

Not all problems can be reduced to decision problems, which is what a trivial property is.

For me looking at how algebraic data types depend on a sum operation that uses either tagged unions or disjoint unions is a useful lens into the limits.

Note that you can use patterns like ports and adapters which may help avoid some of that brittleness, especially with anti-corruption layers in more complex systems/orgs or where you don’t have leverage to enforce contracts.

But yes if you can reduce your problems to decision problems where you have access to both T and F via syntactic or trivial semantics you should.

But when you convert pragmatic defaults to hard requirements you might run into the edges.