Hi everyone!
My name is Justin Lubin, and I’m here to talk about
how statically-typed functional programmers author code.
So, what exactly is statically-typed functional programming?
Well, there’s many different statically-typed functional programming languages, each with
their own unique set of distinguishing attributes, such as Haskell, OCaml, SML, Elm, F#, and many more.
But they all share a common set of features and norms that differentiates them from other
classes of languages, including expressive type systems, strong static guarantees, and
an emphasis on small and reusable functions free of side effects.
The question that I set out to answer is: How do the specific affordances of statically-typed
functional programming affect the way programmers author code?
Now, why should we even care about this?
Well, such a study could give a foundation for useful and usable tooling for these languages.
It could enable more ergonomic language design going forward.
It could provide eased on-ramps into these languages’ communities by introducing newcomers
to how programs tend to actually be constructed.
And it could serve as a template for studies of other understudied programmer audiences.
And this last point is one that I’d really like to emphasize.
Even if you personally aren’t interested in statically-typed functional programming in particular,
I really encourage you to think about how the methodology that I use in this
study could be applied to an understudied group of programmers that you care about.
Along those lines, let’s actually talk about the method that I used in this study.
I did a grounded theory analysis of thirteen statically-typed functional programming sessions.
This included eight live sessions over Zoom where participants first completed some functional
programming tasks that I assigned, then engaged in a semi-structured interview about their
experiences both in the study and prior to it.
The other five sessions were livestreams taken from the websites YouTube and Twitch.
My goal in including the livestreamed sessions was to diversify the programming tasks that
I observed, with the hope of increasing the ecological validity of my findings.
I will also briefly mention that this study is ongoing work.
In particular, I’m working on more grounded theory including a total of 30 programming sessions.
I’m also working on an experimental evaluation of this theory, using quantitative methods
to test its robustness and predictivity.
And, lastly, I’m also working on situating the implications that my findings have for tool design.
So, without further ado: How do statically-typed functional programmers author code?
Well, my theory comprises four main categories: type construction, focusing techniques, hierarchical
and opportunistic programming, and mental models and expressing intent.
At a high level, my answer to the question of how statically-typed functional programmers author code is this:
They start by iteratively constructing types to model their problem domain and encode design decisions.
They leverage types to help themselves focus by relying on the compiler as an assistant
and using these types to help decompose their tasks.
When faced with a difficult or unknown problem domain, they complement this systematic style
of programming with an exploratory one, the details of which are highly varied.
And, lastly, no matter the style of programming, they have diverse mental models and express
their intent in many ways, not all of which produce valid code.
While I’d love to talk about all four of these categories in this video, I really only
have time for one, so let’s take a look at this second category here: focusing techniques.
One interesting way participants focused on tasks at hand was relying on their compiler
not just for corrective feedback, but as a guiding assistant.
For many participants, error messages from their compiler were not just an obstacle to
their running program, but actually served to direct their implementation.
One common instance of this was using compiler error messages as an auto-updating to-do list,
or, what participants referred to as “following the errors.”
The way this strategy works is as follows: The programmer has a code modification in
mind and expresses their intent to complete it by modifying just a small part of the program,
thereafter immediately running their compiler on the code despite being fully aware that
the code will not compile.
From there, the compiler presents the programmer with a list of sub-tasks to complete the transformation—
the programmer can just follow the errors.
As one participant put it: “It broke a lot of stuff, but it was super nice because I
made the change and the type checker told me: ‘This no longer type checks; here’s
all the places where it goes wrong.’
And I can just go through and fix all the type errors, and that essentially is doing the change.”
But types were not just for the compiler.
Participants also used types to structure their top-down decomposition of problems in
a fine-grained manner, a strategy many participants referred to as “following the types.”
One participant noted: “I find types really help me just organize … it’s very important
for me to be able to just chunk different parts of functionality, and … once I’ve
gotten down the type signature, I can just focus on this function and not think about
really anything outside of it.”
Another participant described how types freed his brain from unnecessary context: “Just
like, actually typing this out, and sitting here, kinda freed my brain of this outer context.”
So, that is (part of) my grounded theory of how statically-typed functional programmers author code.
Here are some reasons why we might care, and here is a high-level overview of my theory.
I’d be delighted to talk more about any of these points, or answer any questions that
you might have!
Lastly, I’d like to give a huge thanks to my PhD advisor Sarah Chasins for her guidance
on this project, and to my undergraduate advisor Ravi Chugh for the insightful conversations
that led to the development of the questions addressed by this study.
Thanks for listening!