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

It is true that all type errors can also be caught by additional tests. But is this the most efficient strategy? I would think that letting the compiler find certain classes of errors should be cheaper than writing and maintaining tests for these error classes.


Indeed, as these are error classes unit tests aren't even very good at.

It can't be repeated enough: Types are universal quantifiers, tests are existential quantifiers, you'll realistically never get even close to the guarantees of a type system with tests alone.

If your unit tests are on a level with your static type system, you have basically rebuilt the static type system in your unit tests.

(And pitting unit tests against a static type system is a false dichotomy, it's good to have both.)


My point was that you rarely need to write test to catch type errors. You write tests to determine if a unit of code works as expected. In doing so you tend to exercise the conditions that cause type errors as a side effect.

Let's say foo() internally calls bar(). If I pass a given valid input to foo() it passes the wrong type to bar(). If I pass another valid input to foo() it passes the wrong value but of the right type to bar().

If you ensure full test coverage of foo() you will catch both. Type checking in your compiler will only cover the first case, so you still need the same test coverage anyway to have confidence in the code.


Full test coverage of foo() is hard to prove. Have you exercised every argument possibility, every exception that could be thrown and every global/class/instance var reference? Working with Ruby most of my career, my experience is probably not.

A good type system is much more thourough and let's your tests focus on behavior.


That's what you have coverage checkers for.

And you don't need full coverage. Aiming for full coverage is a folly - you aim to cover the API surfaces you're actually using. If you still get lots of runtime errors something is very wrong with how you test your code.

> A good type system is much more thourough and let's your tests focus on behavior.

The problem is no languages I'd be willing to use have a good type system that actually covers much.


> The problem is no languages I'd be willing to use have a good type system that actually covers much.

This is basically down to opinion, and I can't argue with it. I've collaborated on Ruby projects for about 10 years, I love the language, but my experience says a large code base, with test coverage, regularly breaks on things that most type systems wouldn't allow.

Dependencies often cause subtle breaks like this, even in big, common ones.

On top of that, this requires paranoia to avoid breaking callers. With a good type system, you can largely discard that paranoia.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: