Live data from Hacker News

Functional programming and reliability: ADTs, safety, critical infrastructure

blog.rastrian.dev

21–30 of 191 posts

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

#21
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 tends to get in the way of complex error handling.

Agree. In Java, Streams allow you to process collections in a functional style. This feature enables concise, expressive data manipulation with operations like map, filter, and reduce.

Some people point out that Java's checked exceptions spoil the simplicity and elegance of Streams by forcing you to handle exceptions.

But that's not a reason to not have checked exceptions, it is a reason to not do functional style composition when methods can throw exceptions. Streams was invented for collections, which tend not to throw exceptions. If proper error handling is important don't do Streams.

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

#22
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…

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 programmers do revolves around involves flows. But when it doesn't then functional programming isn't a very good or reliable solution.

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

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

Most of the time when I use untagged unions, I end up adding a tag and logic to case on it anyway…

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

#24
All the line items are decent things, worth doing, but the claim about how much following the line items would improve reliability is super exaggerated.

> [Most production incidents] are due to the code entering a state that should never have been possible.

I have never seen evidence that this is even remotely true, and I've been looking at software reliability research in the last few months.

Instead, it is more true that most production incidents are due to the system entering into one of thousands of unsafe states which were possible and latent in production potentially for years. In a sufficiently complex system—all interesting and important software projects—functional programming is not strong enough a tool to prevent even a sliver of potential accidents.

> Arguments that these degraded conditions should have been recognized before the overt accident are usually predicated on naïve notions of system performance. System operations are dynamic, with components (organizational, human, technical) failing and being replaced continuously. — https://how.complexsystems.fail/

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

#25

Earlier quoted context omitted.

You don't need a strong type system or even really ANY compile-time type system for this strategy to work! I use all these techniques in plain JS and I can still get the benefits of correct-by-construction code style just by freezing objects and failing fast.

Is this a methodology you use at work or only for personal projects ? I'm curious how common this culture is among companies/teams.

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), and it shouldn't take long at all for people to learn the highly consistent naming conventions that tip you off to what type of data is being handled. The result is that I'd expect that it would only be a handful of days learning the mental model for the codebase before the average person would find it far easier to read the JS code as opposed to TS code, thanks to the lower amount of visual clutter.

I also ship code super fast. When I find bugs I just fix them on the spot. When I find variables named wrong, I just rename them. The result that I often smash bugfixes and features and cleanup together and have a messy git history, but on the flip side you'll never find bugs or naming deceptions that I've left sitting for years. If something is wrong and I can reproduce it (usually easy in functional code), the debugger and I are going to get to the bottom of it, and quickly. Always and only forward!

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

#27
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 tends to get in the way of complex error handling. Agree. In Java, Streams allow you to process collections in a functional style. This feature enables concise, expressive data manipulation with operations like map, filter, and reduce. Some people point out that Java's checked exceptions spoil the simplicity and elegance of Streams by forcing you to handle exceptions. But that's not a reason to not have checke…

The Java streams are cool and I like them, but they're not a replacement for a functional type system or a functional language.

`map` is a lot more than a fancy for-loop for lists and arrays; it's about abstracting away the entire idea of context. Java streams aren't a substitute for what you have in Haskell.

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

#28

Earlier quoted context omitted.

Is this a methodology you use at work or only for personal projects ? I'm curious how common this culture is among companies/teams.

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 encountered. Problems which in other companies I had learn to assume would never be resolved would actually consistently get fixes! Well, at that time. This was before the algorithm was fully enshittified and before the disastrous technopolitical developments in the way facebook and facebook messenger interact with each other.

Perhaps the most direct inspiration I took from there though was from the wonderful "opaque types" feature that Flow supports (https://flow.org/en/docs/types/opaque-types/) which for reasons known only to Hejlsberg and God, Typescript has never adopted; thus most people are unfamiliar with that way of thinking.

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

#29
It's acceptable to state, without evidence, that functional programming and static typing make things more reliable.

But this isn't a falsifiable claim. We cannot possibly know if this is true or not.

- Not all of banking and telecom use functional programming or even static typing.

- Functional programming often leads to write-only incomprehensible code; the exact opposite of what you need to have a reliable system.

- There's no hard evidence that static typing improves reliability. Only vibes and feels.

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

#30
A few mention on tests, but I expected more. The main value of pure functions is that now their behavior is representative in tests. In fact, I'd argue that all you need for reliability is determinism and tests of all equivalent scenarios. functional programming (and immutability) are only helpful to the extent that it's easier to have representative tests, but not necessarily required.
Post reply on HN