Live data from Hacker News

Functional programming and reliability: ADTs, safety, critical infrastructure

blog.rastrian.dev

71–80 of 191 posts

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#71
post #16

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 either A or B. The "choice tag" is part of the "constructive data" telling us how to build our proof of "A or B". Translated back into the language of code, the type "A | B" would be exactly a tagged union.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#72
post #12

Strong types: yes, it’s definitely better Functional programming: no, functional programming as in: the final program consists in piping functions together and calling the pipe. In my opinion, that tends to get in the way of complex error handling. The problem being that raising Exceptions at a deep level and catching them at some higher level is not pure functional programming. So your code has to deal with all the…

That's only a problem when you decide that the way to do error handling is exceptions. When you go with a strongly typed functional programming language, you throw exceptions away, and the fact that something can error, and what kinds of errors it can produce, are encoded into the type system.

So yes, generating errors at a deep level and catching them at a higher one is a normal pard of the system design, it's purely functional, ando nothing strange happens, in very large systems. You ADT the errors, pipe up entire families of them, and select what you manage. It's significantly easier than exceptions, in the sense that I can be sure when I've validated the error.

It's practical, and typically one dedicates less code to the error handling than, say, yor typical enterprise Java program that is terrified of runtime exceptions and null checks every step of the way. In fact, I'd argue this is the main selling point of strongly typed FP.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#73
post #62

Earlier 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…

> Java type shenanigans are endless if you want some fun but baseline you can cast to arbitrary types at runtime and completely bypass all compile time checks.

For this reason Java is a bad example of a typed language. It gives static typing a bad rep because of its inflexible yet unreliable type system (only basic type inference, no ADTs, many things like presence of equality not checked at compile time etc ) Something like ocaml or fsharp have much more sound and capable type systems.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#75

Earlier quoted context omitted.

I'm not personally aware of any companies doing this in plain JS aside from my own (I am co-founder/CEO of a two-person startup). I really like working in plain JS. It feels malleable where TS code feels brittle, almost crystalline. Even though I don't have compile-time types there's still only a small handful of different shapes of objects in the core of my software (far fewer than the average TS codebase, I'd wager…

I should add a few more things: much of how I got here was exposure to Facebook's culture. Move fast and break things. React with prop types. Redux. Immutable.js. I did UI there on internal tools for datacenter operators and it was a drinking-from-the-firehose experience with exposure to new programming philosophies, tools, and levels of abstraction and refactoring velocity beyond anything I had previously encountere…

Yes, I am wondering if opaque types would be difficult to implement somehow in TypeScript? It should really be part of TypeScript if at all reasonably possible.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#76

> 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.

Yep, in practice a lot of orgs treat reliability as a cost center until an outage becomes a headline or a regulatory incident. I’ve seen the same tension in payments/banking: product pressure wins until the risk is visible. Part of why I like “make invalid states unrepresentable” approaches is exactly that: it’s one of the few reliability investments that can pay back during feature work (safer refactors, fewer regre…

I've seen reliability become incident level and then 3mo later execs are on our ass because we didn't fix another crisis fast enough.

and this company is hugely successful. so i've learned that the biggest competitive advantage in fintech is flagrant disregard for correctness and compliance.

i'm glad i have a csuite with the stones to execute that. i am way too principled.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#77
post #62

Earlier 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…

There are different levels of static typing

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#78

Earlier quoted context omitted.

Honestly, as someone else who does a lot of data plumbing, there is so much FTP servers with excel sheets being used as the means for official clearance processes. There are constant data bugs in the feeds provided by major exchanges, market makers, etc, and so many iffy business rules that are basically all encoded in 100+ tab excel sheets. Maybe this article focuses on a very specific niche of banking, but most of…

I’ve worked in Brazilian banking stacks that were literally FTP + spreadsheets for years. So yes, the ecosystem is often messy and protocols can be flaky. That’s exactly why I argue for stronger internal modeling: when the boundary is dirty, explicit state machines/ADTs + exhaustiveness + idempotency/reconciliation help ensure bad feeds don’t silently create invalid internal states.

I totally agree as a fellow fintech engineer. It was a battle getting approval for all that from Product for us. While we were battling for it, we rushed multiple projects without literally any of it. And then spent a year+ each time cleaning up the mess.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#79

> 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 less critical, of course.

Re: Functional programming and reliability: ADTs, safety, critical infrastructure

#80
post #70
post #68

Earlier quoted context omitted.

> > For the tagged case you would have to change all(!) the call sites > Yeah, that's exactly why I want a tagged union; so when I make a change, the compiler tells me where I need to go to do updates to my system, instead of manually hunting around for all the sites. You don't have to do anything manually. There is nothing to do. Changing the return type of a function from String|Null to String is completely safe, t…

The String|null example is just a nullable type; it's not an interesting use of unions either way. The conversation starts when it's Foo|Bar|Baz I'm unfamiliar with typescript, so in that language I don't have an opinion either way, but in C, you pretty much always want the tag

C doesn't support any untagged unions (or intersections) in the modern sense. In a set-theoretic type system, if you want to call a method of Foo, and the type of your variable is Foo|Bar|Baz, you have to do a type check for Bar and Baz first, otherwise the compiler won't compile.
Post reply on HN