We program with constructs. We have programming languages. We use particular libraries, and those things, in and of themselves, when we look at them, like when we look at the code we write, have certain characteristics in and of themselves.
But we're in a business of artifacts. Right? We don't ship source code, and the user doesn't look at our source code and say, "Ah, that's so pleasant."
-- Rich Hickey, simple made easy
i would like to talk about this tweet:
If developers are software "engineers", then being told to develop an app with Scala instead of Haskell is like being mandated to build a bridge out of plywood instead of steel.— Mark Hopkins (@antiselfdual) May 3, 2018
from what i can tell, Mark is a pretty smart guy and probably a good programmer. also his tweet "did well", so i feel a little less bad about what i'm about to do with the tweet, which is critique it.
the first thing i think we need to do is crystallize what the "bridges" we build are. they're binaries, right? that's why we call them "builds." this should be obvious to us, but i think we oftentimes forget it. i also think our bridges include other things we construct, for example processes (here meaning a series of actions or steps taken in order to achieve a particular end) or execution environments. but they're not source code! outside the context of this tweet, i've seen people get tripped up on this a bunch. we need to think of the outputs of the development process as being binaries, not as being code.
my issue with the tweet is that Mark is conflating properties of the code (or construct, as Hickey says) with properties of the artifact. i'd guess that Mark believes that qualities like purity, a more syntactically-nice type system, and much-less-accessible mutability are things that can add strength to our "bridges". this is a sentiment that i think is widely shared by many in our profession. but, again, source code isn't executed. these qualities are qualities of our code and, by definition, cannot be inherited by the artifact. the only value these qualities provide us is in how they affect the production of the artifact.
so let's talk about them like that. i truly believe that capturing side effects in the type system, like haskell does, improves a programmer's ability to reason about what the outputs of her programs will be. what a program's outputs are going to be is definitely a property of the artifact, big win for haskell here. but haskell's runtime execution model is inhibitory to the same programmer being able to reason about how her artifact executes compared to a language like java or scala. changing or even understanding the performance profile of a haskell artifact is going to be much more difficult than other languages.
my point is not that there is a tradeoff (although there definitely is), it's that in order for us to compare our tools, the thing we should be looking at is what impacts those tools have on the production of artifacts. our experience as programmers naturally centers around code and the experience of writing it because that's what we spend our time doing. however our job is to produce binaries; code is just a byproduct