Hacker News new | ask | show | jobs
by apiguy 886 days ago
Not being able to run a 15 year old codebase on a < 1 month old runtime without making some modifications has nothing to do with static or dynamically typed languages.

But first - why don't we point out that the bulk of the issues the author faced had nothing at all to do with types? The issues were primarily with syntax changes.

Regardless - with a statically typed, compiled language, you find these issues at compile time. With any other language you find them at runtime. Either way, you'd have to fix a whole lot before you deploy the code, and just because you prefer to find your exceptions at compile time doesn't mean that it's the best way to find them.

1 comments

> just because you prefer to find your exceptions at compile time doesn't mean that it's the best way to find them.

It is indeed the best way to find them. At compile time, you get errors for all possible paths a program will take.

For dynamic languages like Ruby you will get an error only if the program takes a path through problematic code and then Ruby will flag the error. This means a runtime error could lie latent in your codebase for many more weeks and months. Only if a rare condition triggers a code path that contains the incompatibility. This is also why refactors in languages like Ruby are more difficult and conservative. As you're never sure you fixed everything.

This seems like a semi-moot point considering that after you've updated something you (presumably) also run an automated test suite and (have someone) test the application manually.

I've also had various occasions where code compiled successfully but no longer worked as intended.

The automated test suite can check many code paths but compilation of a statically typed language checks all possible code paths.

Put another way, automated test suites give you an extremely high level of assurance when using a statically typed language. When your test suite passes in the new version Ruby, you're happy but there still could be cases left that you've not dealt with in rarely triggered code paths/conditions.

The problem with this argument is that you never mention the costs or trade-offs of a statically typed language. You presume that you get the benefits for free and I'm certain that is not the case. The worst systems I've ever worked on were ones with complex and poor types and type hierarchies.
What are the costs of a Ruby incompatibility just waiting to be discovered in production ? You can't assume you wrote tests to exercise every possible branch in every method in every object ?

The costs of static typing are reasonable as long as you're not using a fancy dependently typed language. Ask companies that are maintaining long running software -- types help. The investment is there in the beginning, the payoff is over the lifetime of the project.

If types are complex and poorly defined, you can change them ! The compiler will help you evolve your system through type errors. If you have a poorly structured program in a dynamically type language like Ruby then it becomes more difficult to evolve your system fast and with confidence. You're always asking -- have I missed something out ?

I've been writing software for a long time in many different types of languages. I've led many software teams for a long time that use different languages and tech stacks. I have not seen any measurable difference in productivity or defect rate across different languages. I have also looked at all of the research on this and it is inconclusive at best.

Ultimately, I think that choice of language is one of the least significant predictors of outcomes, yet it's one of the most debated and obsessed over.

Edit: I thought it would be helpful to give examples of what I think is more important. Good CI/CD practives, good observability, robust test and staging environments, etc have been far more important in my experience than static vs dynamic language choice.