|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.|
Yeah, pareto optimality would be nice ... you'll be lucky to get it though ;-)
I totally agree that I'm ignoring qualitative things like beauty and whatnot, which is definitely a problem. I certainly like some programs more than others!
So, besides time-constrained programming competitions, I guess I have had experiences where I started working on something I knew absolutely nothing about. I've done this with static and dynamic types and I would say that I found the "activation energy" lower with dynamic types. This can apply to a domain I'm totally ignorant of, or a project that's too big to contemplate doing on my own.
For instance, the text editor I wrote (about 10K lines of Python) evolved as I wanted to add features and fix bugs, and didn't have an up-front design. It's possible that the (immense) amount of energy I put into it between 2006 and 2011 would have been much lower with static types, but it's also possible I would never have gotten an initial prototype working well enough to get excited, stick with it, add features, etc. Using it in a day-to-day way was a huge motivation to make it better/faster.
I think I could probably write a better version of this editor in Scala (or Idris or whatever) these days, but I have a good idea of what design will work and why, and what types I'll need. It's possible it would have worked just as well then, but it's also possible I would have struggled and given up (not having enough energy/intelligence/etc for the up-front cost).
One thing that strikes me as a little odd is the timing: types are first and tests come later? Really? Isn't that just a strawman ... surely nobody really thinks that's an accurate picture? TBH, I don't even think it's a good approximation.
From my completely personal and annecdotal PoV, I do sketching first to rough out a structure and then refine and rework. Types and (some) tests work for me for the initial phase, but I could easily imagine someone with different preferences putting more emphasis on tests up front. But either way this really doesn't feel like the kind of periodization you're you're claiming.
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).
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?
Jan 30, 2014
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).
Apologies if my reading was excessively literal minded. I think the idea of the "area under the curve" and front vs. back loading is useful. I think that it would probably wise to have at least two dimensions though: one for costs, one for benefits, without the assumption that they are directly commensurable.
I'm also wondering if your experience of extremely time constrained programming competitions is shaping the way you're thinking about this? If it is, do you think your conclusions carry over to less constrained circumstances?