This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The analogy is comparing writing programs to buying goods: | |
writing a program with static types is equivalent to buying | |
with cash, and writing a program with dynamic types is | |
equivalent to buying with credit. | |
The "cost" in either case is mental energy and time. When I | |
write a program with static types I spend a lot of effort up | |
front, guided by the type system and compiler, to handle edge | |
cases and generate a totally correct solution. I have to | |
fully-understand any libraries I'm using and characterize | |
the problem in terms of types. | |
When I write a program with dynamic types, I typically get | |
something I can run much faster, but then I struggle through | |
compose/test/debug cycles until the program is eventually | |
correct. The energy cost here is spread out (potentially | |
over days or weeks) instead of happening earlier. | |
The correct program is the thing I am buying in this analogy, | |
not the currency I'm spending. |
To be clear, I find a ton of joy in working with static types so that when my program compiles it often works correctly without bugs.
I am just trying to reconcile this with the fact that I haven't yet written any large personal tools comparable to those I built in Python back when that was my go-to language.
Doesn't Spire count?
Well, Spire is an interesting case. I mean, it's a big project, but as a library it's pretty modular. Also, there have been many collaborators (which is something a good type system has made way easier).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So, I don't know where types and tests came into things, since I was mostly talking about dynamic vs static types.
What I am really talking about is building types/tests into an upfront design, getting things "working" (compiling/passing), then moving on, versus implementing something, seeing it work in an ad-hoc way, moving on, and then returning to fix bugs/refactor/whatever later as needed. Dynamic types are compatible with either strategy, but static types are less amenable to getting something fuzzy working in an ad-hoc way.
I certainly don't spend days in a laboratory slowly building types, so I imagine my workflow is somewhat similar to yours. But I've never built a large project (game, editor, whatever) from start to finish in static types by myself, so usually the static type projects I've work on are smaller and more constrained (building an R-Tree, building a segmented sieve, implementing some algorithms, interval arithmetic, etc).