I think there is a strong case that ADTs (algebraic data types) aren't so great after all. Specifically, the "tagged" unions of ADT languages like Haskell are arguably pretty clearly inferior to the "untagged" unions of TypeScript or Scala 3. Because the latter actually behave like a logical "or" rather than an artificial construct that needs to be wrapped and unwrapped.
While others have addressed the programming case for tagged unions, I want to add that, to a logician, tagged unions are the natural construct corresponding to "logical or". In intuitionistic logic (which is the most basic kind from which to view the Curry-Howard or "propositions-as-types" correspondence), a proof of "A or B" is exactly a choice of "left" or "right" disjunct together with a corresponding proof of eit…
Functional programming and reliability: ADTs, safety, critical infrastructure
81–90 of 191 posts
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#82Earlier quoted context omitted.
Wait. This doesn’t make sense to me. Statically typed programming languages cannot be deployed nor can they run with a type error that happens at runtime. Untyped languages CAN run and error out with a type error AT runtime. The inevitable consequence of that truth is this: In the spectrum of runtime errors statically typed languages mathematically and logically HAVE less errors. That by itself is the definition of m…
> Statically typed programming languages cannot be deployed nor can they run with a type error that happens at runtime. This is so completely untrue that I'm confused as to why anyone would try to claim it. Type Confusion is an entire class of error and CVE that happens in statically typed languages. Java type shenanigans are endless if you want some fun but baseline you can cast to arbitrary types at runtime and com…
What I am saying is not untrue. It is definitive. Java just has a broken type system and it has warped your view. The article is more talking about type systems from functional programming languages where type errors are literally impossible.
You should check out elm. It’s one of the few languages (that is not a toy language and is deployed to production) where the type system is so strong that run time errors are impossible. You cannot crash an elm program because the type system doesn’t allow it. If you used that or Haskell for a while in a non trivial way it will give you deeper insight into why types matter.
> Ruby is so safe in it's execution model that Syntax Errors don't invalidate the running program's soundness.
This isn’t safety. Safety is when the program doesn’t even run or compile with a syntax error. Imagine if programs with syntax errors still tried their best effort to run… now you have a program with unknown behavior because who knows what that program did with the syntax error? Did it ignore it? Did it try to correct it? Now imagine that ruby program controlling a plane. That’s not safe.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#83Earlier quoted context omitted.
Wait. This doesn’t make sense to me. Statically typed programming languages cannot be deployed nor can they run with a type error that happens at runtime. Untyped languages CAN run and error out with a type error AT runtime. The inevitable consequence of that truth is this: In the spectrum of runtime errors statically typed languages mathematically and logically HAVE less errors. That by itself is the definition of m…
> Wait. This doesn’t make sense to me. Statically typed programming languages cannot be deployed nor can they run with a type error that happens at runtime. Untyped languages CAN run and error out with a type error AT runtime. The inevitable consequence of that truth is this There is nothing inevitable about the consequence you’re imagining because statically typed languages also reject correct programs.
How does a statically typed language rejecting a correct program affect reliability? The two concepts are orthogonal. You’re talking about flexibility of a language but the topic is on reliability.
Let me be clear… as long as a language is Turing complete you can get it to accomplish virtually any task. In a statically typed language you have less ways to accomplish the same task then a dynamically typed language; but both languages can accomplish virtually any task. By logic a dynamically typed language is categorically more flexible than a static one but it is also categorically less reliable.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#84Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#85Earlier quoted context omitted.
If you have strong types, it is still possible to make a mutable thing, that will be mutated from the other end of the program and that will introduce bugs, that can be hard to find. If you are doing FP on the other hand, at least change always results in new objects, with structural sharing at most. This excludes a whole category of bugs.
> If you are doing FP on the other hand, at least change always results in new objects, with structural sharing at most. This excludes a whole category of bugs. Not if you program it with a mutable god object to mimic creating a new big state, then you have exactly the same kind of issues. The issue is if you try to program a transaction flow using object oriented programming, that is not very good, and most work pro…
Have you done any FP? That's not how you do FP.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#86Something I haven't seen talked about, though, is how powerful the type system is for constraining LLMs when using them to generate code. I was recently trying to get LLMs to generate code for a pretty vague and complex task in Haskell. I wasn't having much luck until I defined a very clear set of types and organized them into a very clear and constrained interface that I asked the LLM to code to. Then the results were much better!
Sure, you can use these same techniques in less strongly typed languages like Rust, and you can probably also use a similar approach in dynamically typed languages, but Haskell's pure functions allow you to create much stronger guard rails constraining what kinds of code the LLM can write.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#87This article seems to conflate strong type systems with functional programming, except in point 8. It makes sense why- OCaml and Haskell are functional and were early proponents of these type systems. But, languages like Racket don’t have these type systems and the article doesn’t do anything to explain why they are _also_ better for reliability.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#88Was just talking with someone the other day who used to write Haskell professionally but is now using Python. He said that in his experience when there are bugs the "blast radius" is much larger in a dynamic language like Python than in a static language like Haskell. That has been my experience as well. Something I haven't seen talked about, though, is how powerful the type system is for constraining LLMs when using…
But since purity is not encoded in Rust's type system, any function might do any kind of IO -- in particular, read from or write to disk or one of the DBs. That makes the logic much harder to reason about.
(Also, Rust's syntax is so noisy and verbose that it's harder to see what's going on, and less context fits in my head at one time. I'm getting better at paying that cost, but I wish it weren't there.)
I can't say I made the wrong decision, but I often fantasize about moving most of the logic into Haskell and just calling Rust from Haskell when I need to call TypeDB from Rust.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#89> In banking, telecom, and payments, reliability is not a nice to have. It is table stakes. Haha as someone who has worked in one of these domains using FP even - I wish the people in charge agreed with you! Reliability is a cost center and Product-oriented Builders treat it as such.
Perhaps someone can enlighten me on this. I never quite understood the sentiment of treating money-related tech as somehow more critical than others. The effects of large SaaS services failing and the bank failing can be quite similar - businesses interrupted, money lost, etc. but it’s typically not life and death, so the importance of reliability should be similar. I can understand treating social network sites as l…
The reason money-related systems often get singled out is the combination of irreversibility and auditability: a bad state transition can mean incorrect balances/settlement, messy reconciliation, regulatory reporting, and long-tail customer harm that persists after the outage is over.
That said, my point isn’t “finance is special therefore FP.” It’s “build resilience and correctness by design early”, explicit state machines/invariants, idempotency/reconciliation, and making invalid states hard to represent. Doing this from the beginning also improves the developer experience: safer refactors, clearer reviews, fewer ‘tribal knowledge’ bugs.
Re: Functional programming and reliability: ADTs, safety, critical infrastructure
#90I'm impressed by the author having made so many sensible choices in their life, yet marrying their blog content to GitHub issues.