Skip to content

Instantly share code, notes, and snippets.

@non
Last active August 29, 2015 13:55
Embed
What would you like to do?
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.
@milessabin
Copy link

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?

@milessabin
Copy link

Yeah, pareto optimality would be nice ... you'll be lucky to get it though ;-)

@non
Copy link
Author

non commented Jan 29, 2014

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).

@milessabin
Copy link

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.

@non
Copy link
Author

non commented Jan 29, 2014

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).

@non
Copy link
Author

non commented Jan 29, 2014

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.

@milessabin
Copy link

Doesn't Spire count?

@non
Copy link
Author

non commented 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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment