Refactoring Kotlin type-signatures for fun and profit
In which I derive the core type signatures of http4k from an unexpected source, by using refactoring and FP techniques more commonly associated with coding.
TL;DR
“You can apply simple refactoring and functional techniques such as substitution and currying to refine function signatures. Free of any implementation detail, defining system concepts in this way can be a refreshingly powerful technique.”
On a recent episode of TalkingKotlin exploring http4k, we discussed with Hadi Hariri the origins of http4k had been inspired by the original “Your Server as a Function” (SaaF) paper. I noted that the pattern described within was the same as the one used in the Java Servlet Filter API and that we’d derived the final http4k core types of HttpHandler
and Filter
from it.
Just to double check that I wasn’t misremembering, I thought it would be fun to revisit the process. On looking back, this turned out to be remarkably similar to the journey we’d take when refactoring code, but at a more conceptual level. In that vein, we can map the various steps onto the powerful refactoring functions that come with IntelliJ.
To revisit, the Java Servlet Filter API defines the following:
If we transpose these signatures into Kotlin, we get:
As http4k is a library heavily inspired by functional programming, we then want to make our types immutable, whereas the Servlet types are reliant on mutating the HTTP messages. In order for the functions to remain pure and side-effect free, we should return an immutableServletResponse
from our service instead of mutating it and returningUnit
, so let's use Change Signature (Cmd+F6) to do that:
We can then Change Signature (Cmd+F6) again to reorder the parameters of the Filter
:
One thing that is common in more functional languages, but that we can’t currently do in the IDE (hint hint JetBrains!) is to apply currying to split the Filter
into a higher-order function (ie. one which returns another function):
By doing this we can see that we can make a substitution for FilterChain
into Filter
as the type signatures match:
Finally, we can do some Kotlin replacement and Renaming (Shift+F6) to get us back to the http4k types that we know and love:
So there you have it. Turns out that Everything old is (actually) new again!
Enjoyed this post? You can read all of my tech writings at https://dentondav.id/writing.