The thing I think most arch enemies of dynamic typing miss is the underlying economics of writing software.
~98% of software gets thrown on the trash heap before it reaches the point where it really needs to be maintained.
That last 2% of gold dust desperately needs to be maintained well and to work, but to get to the point where you have that asset you'll probably find you need to throw away an awful lot of code first.
If you write that 98% using static typing it will slow you right down - potentially to the point where you dont even get to the gold dust.
If you write that 2% with dynamic typing it will fall apart. A lot of programmers see this process without ever appreciating the fast prototyping that got it there in the first place.
I find static types actually speed up writing new code, since that's when I'm most likely to make typos in fields -- just today I had to fix some goofs where I used snake_cased fields when it was expecting camelCase. LLMs love types, and any hallucinations are instantly red-lined. Agreed on gradual typing, but I'd rather approach it from a strict language with an opt-out dynamic type like TS's 'unknown' rather than a duck-typed language with type "hints" the runtime has to always check anyway.
Structural subtyping usually hits the sweet spot for me: I can just create random structures on the fly, the type system makes sure I use them consistently, and my IDE helps me extract a named type out of them after the fact with just a few keystrokes.
I'm the same. When writing python I write some lines, run and test, write some more, run and test... with Rust I bash out lines of code for an hour then have the compiler and Clippy help me fix it all afterward.
Quite an assertion to say that static typing slows people down. I find the opposite. Beyond a few hundred lines you get a ton of productivity benefits that easily outweigh the time it takes to write types down:
1. Shorter iteration time for fixing type errors, especially things like field typos, missing arguments etc. They show up immediately as I'm typing instead of having to run a test suite (and having to write an extensive test suite).
2. You can write fewer tests to achieve the same code quality. Especially with really strong type systems like Haskell and Rust. Huge time saver.
3. IDE navigation features (go-to-definition, find-all-references) are generally faster and more reliable than grepping. I'm sure we've all had the pain of trying to grep where the `process` function is defined in a large dynamically typed codebase.
4. Auto complete works reliably.
5. You can refactor things reliably, especially renaming identifiers.
6. For multi-person projects or long-lived single-person projects it means you waste less time figuring out what code does.
IMO gradual typing isn't a good idea. Adding types after the fact is much more effort because you basically have to reverse engineer the code. And you don't get the performance benefits of "true" static types. There's a reason Dart switched away from it.
Comments
The thing I think most arch enemies of dynamic typing miss is the underlying economics of writing software.
~98% of software gets thrown on the trash heap before it reaches the point where it really needs to be maintained.
That last 2% of gold dust desperately needs to be maintained well and to work, but to get to the point where you have that asset you'll probably find you need to throw away an awful lot of code first.
If you write that 98% using static typing it will slow you right down - potentially to the point where you dont even get to the gold dust.
If you write that 2% with dynamic typing it will fall apart. A lot of programmers see this process without ever appreciating the fast prototyping that got it there in the first place.
So, this is why Im a fan of gradual typing.
I find static types actually speed up writing new code, since that's when I'm most likely to make typos in fields -- just today I had to fix some goofs where I used snake_cased fields when it was expecting camelCase. LLMs love types, and any hallucinations are instantly red-lined. Agreed on gradual typing, but I'd rather approach it from a strict language with an opt-out dynamic type like TS's 'unknown' rather than a duck-typed language with type "hints" the runtime has to always check anyway.
Structural subtyping usually hits the sweet spot for me: I can just create random structures on the fly, the type system makes sure I use them consistently, and my IDE helps me extract a named type out of them after the fact with just a few keystrokes.
I like common lisp, where sbcl will catch the worst type errors while compiling, but you can also specify types and they will speed up your code.
I'm the same. When writing python I write some lines, run and test, write some more, run and test... with Rust I bash out lines of code for an hour then have the compiler and Clippy help me fix it all afterward.
Quite an assertion to say that static typing slows people down. I find the opposite. Beyond a few hundred lines you get a ton of productivity benefits that easily outweigh the time it takes to write types down:
1. Shorter iteration time for fixing type errors, especially things like field typos, missing arguments etc. They show up immediately as I'm typing instead of having to run a test suite (and having to write an extensive test suite).
2. You can write fewer tests to achieve the same code quality. Especially with really strong type systems like Haskell and Rust. Huge time saver.
3. IDE navigation features (go-to-definition, find-all-references) are generally faster and more reliable than grepping. I'm sure we've all had the pain of trying to grep where the `process` function is defined in a large dynamically typed codebase.
4. Auto complete works reliably.
5. You can refactor things reliably, especially renaming identifiers.
6. For multi-person projects or long-lived single-person projects it means you waste less time figuring out what code does.
IMO gradual typing isn't a good idea. Adding types after the fact is much more effort because you basically have to reverse engineer the code. And you don't get the performance benefits of "true" static types. There's a reason Dart switched away from it.
Can the addition of type hints to the 2% be largely automated?