It’s only hype because it’s imprecisely stated. Static type systems make entire classes of bugs impossible at runtime. The stronger (read less permissive) the type system, the more classes of bugs cannot occur.
It’s only hype because it’s imprecisely stated. Static type systems make entire classes of bugs impossible at runtime. The stronger (read less permissive) the type system, the more classes of bugs cannot occur.
Everything's a trade-off, the question is which approach is best for your application. Your average website doesn't warrant as much rigor as a Mars rover.
Dynamic typing only increases development speed for the first few thousands lines of a solo programmer project. After that it is, in my personal experience, a significant drag on development speed.
Furthermore, dynamic typing makes modifications and new features significantly harder to write. Turning compile-time bugs into runtime bugs is a catastrophic decrease in development speed.
That’s my personal experience at least. YMMV.
> dynamic typing makes modifications and new features significantly harder to write
Depends on what you're doing I suppose.
Adding a parameter to an object? With dynamic typing you just add it to the object in literally any location, no issues. With static typing you might just need to refactor half your codebase if you have lots of interfaces. Have fun resolving merge conflicts with your team.
Not only that, but (in Java as an example) serialization codes for objects will change unless you planned for that previously (you didn't), making old objects impossible to load. A completely new bug that's created solely by static types. And it's not the only one.
Maybe it's an issue with Java. In Rust if I add a new field, I just wrap it in an Option.
When de-serialized, old objects have a None, new objects with the field have a Some. When serializing it's just `Some (5)` instead of `5`, if it's an int.
No runtime crashes from nulls, either.
1) Statically typed languages with inference don’t require time spent writing signatures.
2) I know I’ve spent time chasing down bugs in dynamically typed software that would have been caught by a type checker.
3) I also know I’ve spent time writing tests for conditions in dynamically typed code that wouldn’t pass a type checker.
What are some strong examples of this? Haskell does an amazing job with it. Java technically supports some amount of inference, but it doesn’t reduce verbosity by all that much. Apart from those I haven’t run into it.
Type checking also introduces its own set of additional bugs by the virtue of object incompatibility, that do not exist at all in dynamically typed languages (or are handled correctly every time by the compiler/interpreter automatically).
Take as an example exchanging objects over sockets, rest, files, etc. Whenever the object definition changes in another piece of the software stack the statically typed parts will crash upon receiving the updated objects, even if it's just one new param added that would've been fine otherwise if dynamically typed (or say change from a float to a double which can be irrelevant). A nightmare in systems with lots of moving parts.
One might say that's working as intended, and it of course is, but it also forces you to fix and recompile all of that for no real net gain. Hence the longer dev time I mentioned.
I've spent years working with statically typed languages, and I honestly don't think I'll ever go back to them in any professional capacity.
Anecdotally, this is not true for C++ using JSON or msgpack, since those are self-describing formats where extra fields are safe to ignore.
And it's not even true for Rust using serde, which writes the serializing / de-serializing code for you. serde_json will also ignore unknown fields when parsing, and you can preserve the original object as a `serde_json::Value` in case you want to pass unknown fields downstream as opaques.
Protocol buffers and Flat Buffers also have solutions to this, and all 4 of these formats are pretty popular in both static and dynamic languages.
Even if you write a custom TLV format, this is not that hard to deal with.
Was this common in the static code you worked with? You weren't just casting objects to `char *` and doing a `memcpy`, I hope?
Now, being able to assert that a field is present in an object is a basic and valuable use-case for static typing. However, the developers felt that even this basic level of static type checking added too much friction whenever they had to update systems.
https://capnproto.org/faq.html#how-do-i-make-a-field-require...
You appear to completely misunderstand what static typing means. Runtime crashes due to type mismatches are exactly what static typing prevents.
(Well you could, but then you'll be introducing a whole set of problems if the other system has a static type system that behaves differently from your application's static type system)
Aaaahg it burns. I basically am going through and first annotating, then upgrading.
Interestingly enough, py2 was smart enough to automatically load things in the correct format. Loading a binary file? Get bytes. Loading a text file? Get a string. Py3 has worse functionality now, all for the sake of consistency.
I am not sure that that is correct. Type inference significantly decreases development time imho, and access to compiler errors means significantly less testing time because a certain class of errors is avoided.
Personally, I find that my productivity w/ Haskell was significantly higher than with python exactly because of the type system even though I have 3x the experience in years w/ Python.
I have inherited (hah) a project at work and had to introduce all sorts sanity checks (mypy, pylint, etc) as pre-commit hooks to make my life easier wrt bug hunting.
To use that review as an authoritative statement is ingenuous, to say the least.