4 ms·
This notion that functional programming is about correctness kept me away from static types and FP for the better part of my career. I mean - who cares about c
by jasim 6y ago
This notion that functional programming is about correctness kept me away from static types and FP for the better part of my career.
I mean - who cares about correctness when I'm trying to ship yet another cookie-cutter web application that I don't even know is going to see more than a thousand users in its life.
What I cared about was speed. A few bugs in production is a better trade-off than all the mathematical mumbo-jumbo and slow, meticulous programming that Typed FP seemed to demand.
But to my surprise, after getting started with ReScript/Reason/OCaml, I recognized that correctness is just a side-effect (!) of this mode of programming. (Note that unlike Haskell, OCaml is an imperative programming language with as much or as little mutation as we need. We can almost line-by-line translate a regular mutation-heavy piece of Python or JavaScript code to OCaml, if we wanted to.)
Typed FP, contrary to what I'd came to expect, is all about speed. Quoting from something I wrote a while ago:
"Refactoring a typed FP program is safe, but menial. When we say safe - it means no anxiety. There is going to be tons of mechanical work for every major type refactor - going thru all the compiler errors and fixing them one by one. That can't be avoided. We've been in multi-day refactoring sessions where we had to dredge thru page after page of compiler errors before we could even run the application. But - it is safe - we know that once it compiles, there won't be any mistakes.
That gives us the freedom to build fast and loose - and take stock periodically before we have to abstract things out and tidy up the place. We should compulsively rely on that safety. Typed FP forces us to go slow in places where a dynamic environment would've allowed us to blaze through. For all that trouble, we get unmitigated refactoring dexterity and we must exploit it to benefit from the paradigm."
There are many places where a dynamic, imperative approach is faster than a typed FP approach. But there are as many or more places where it is the other way round. I'm now fastest with this way of programming than anything else, and I wish that more literature around Typed FP communicated this rather than go about the indirect route of correctness, and expect people to pick up that correctness-by-construction results in increased velocity. That's a difficult jump to make unless one has written non-trivial amount of code in that style.
This book by Sandy - I've read the introduction and skimmed thru the Tile construction equations - is to me poetry. I'm having trouble fitting in the idealistic notion of the Escher tile to my imperfect real-world domain, but otherwise, what a book!
- Twisol 6y ago> I mean - who cares about correctness when I'm trying to ship yet another cookie-cutter web application that I don't even know is going to see more than a thousand users in its life. I feel this perspective, but I don't understand it. To me, correctness means that the program is actually doing what it's supposed to. If we don't care about correctness, isn't the particular program we're writing pretty arbitrary? Correctness doesn't seem like some ivory tower ideal to me. I want to write software that meet a need for my users. Writing correct software means uncompromisingly meeting that need.
- jasim 6y agoCorrectness and robustness happen to all software, when exposed to end-users for a long enough time. Internally the software would be a ball of mud, a fragile patchwork of incoherent code that nobody wants to touch. A lot of these programs become immutable logs - if you want to change a feature, you add more code because you're afraid to touch anything that already exist. Yet they are robust - all the bugs in the commonly traficked code paths have already been sussed out, and from outside the software looks like an impenetrable, rugged piece of craftsmanship. This has happened to me in the early years of my career (proud of the robustness, not proud of the code), and I've witnessed it so many times outside. So yeah - robustness and correctness is either a matter of correct-by-construction, or correct-over-time.
- Twisol 6y ago> Yet they are robust - all the bugs in the commonly traficked code paths have already been sussed out There are two ways this can be true: if the code paths users traffic are debugged, and if users only traffic code paths that are not buggy. In the end, all and only the code paths that are used are useful. Isn't that a truism? Like I said, I feel this perspective (and thank you for responding!). But I'm kind of sick of working on codebases that are absolutely littered with dead code paths that are hopelessly interwoven with live code paths, to the point that when you know you're breaking something, you hope you're only breaking something that isn't used. To me, it's a really depressing, fatalistic worldview. > A lot of these programs become immutable logs - if you want to change a feature, you add more code because you're afraid to touch anything that already exist. Amen to that. Can we as an industry find ways to do this better in the first place, instead of resigning ourselves to "immutable log" as an inevitability?