Live data from Hacker News

Functional programming and reliability: ADTs, safety, critical infrastructure

blog.rastrian.dev

101–110 of 191 posts

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

#101

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

[deleted]

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

#103

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.

> In fact, I'd argue that all you need for reliability is determinism and tests of all equivalent scenarios.

Any insights as to how to get effective determinism without pure functions?

Pure functions win here because we only have to reason about the function arguments. Reasoning is easier when you have to less of it! Without pure functions, the state space explodes, because anything anywhere could have a side-effect — madness, I say! — so how would you figure out equivalent states? Special case inspection I suppose?

There is a continuum between "anything goes" and "pure functions". From a certain light, all the varieties of encapsulation can be seen as explorations of this theme. (An idea: perhaps there are languages where side-effects can be circumscribed in ways that don't rely on the high bar of pure functions?)

The arguments against pure functions appear to be somewhat contingent: current adoption levels, practice, convenience, and taste. Things that are contingent have a way of changing over time as new methods emerge and new values take hold.

I don't hold shallow human preferences in high regard. As an example, many humans and organizations in practice trade security for convenience, at significant cost — especially when that cost is external to them.

At the same time, onerous tasks encourage work-arounds. This is the crux of it I think: unless people perceive the value of pure functions (to do what they want to do), some will seek shortcuts. So we need some combination of (1) making them easier to work with; (2) motivating people to aspire to higher principles; namely, high quality software that does not open to door to exploitation, misuse, botnets, etc; and/or (3) internalize the external costs.

As an example of (3), if people and companies faced predictable and commensurate costs when their flawed software inflicts harm on others, they would be more inclined to care about correctness.

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

#104

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

I've found it useful in limited cases for writing optics which can be incredibly obtuse, sometimes boilerplatey, and yet ultimately accomplish what in other languages might be considered utterly trivial use cases... consider the following prompt and output:

    reply with one-line haskell source code ONLY: implement the function projectPair :: (Field1 s s a a, Field2 s s b b) => Lens s s (a, b) (a, b)

    lens (\s -> (s^._1, s^._2)) (\s (a,b) -> s & _1 .~ a & _2 .~ b)
... which can be shown to satisfy the three lens laws. If you can understand the types it is generally true that the implementation falls out much more easily, in a similar vein as "show me your tables, and I won't usually need your flowchart; it'll be obvious."

I suppose LLMs are good for this and other extremely constrained forms of boilerplate production. I consider it an incremental improvement over go codegen. Everything else I still tend to hand-write, because I don't consider source code production the bottleneck of software development.

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

#105

Earlier quoted context omitted.

Not if proving so is more expensive to do than not. Reliability is only a means. Not the end. Also the human parts of the business would need to be simplified in order to model them. If deviate from the model that could invalidate it.

Agree on the economics. I’m not arguing for full formal proofs; I’m arguing for low-cost enforcement of invariants (ADTs/state machines/exhaustiveness) that makes refactors safer and prevents silent invalid states. Human processes will always drift, so you enforce what you can at the system boundary and rely on reconciliation/observability for the rest.

You can also argue that debugging time can be expensive but static checks reduce debugging. This is much more true when it's concurrency errors.

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

#106
post #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 eit…

When A and B are disjoint, you don't need the tag unless you for some reason you require that `Maybe> != Maybe` holds true and don't like the collapsing semantics of unions where `Maybe> == Maybe`

In practice, the cohabitants in Option/Result types are almost always disjoint. So you spend time wrapping/unwrapping Some/Ok/Err for no value add.

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

#107
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

> but in C, you pretty much always want the tag

We aren't discussing unions in memory layout, but in type systems. This also clearly indicates you aren't qualified for this discussion.

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

#108

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…

> […] 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. I’ve used languages with an approach like this. The difference in what I’ve used is that you separate the conventional part from the rest of the name with a space (or maybe a colon), then only refer to the value by the non-conventional part for the rest of the scope.…

I don't get your 2nd sentence: "The difference in what I’ve used" ... Can you give an example, and name the language used?

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

#109
post #2

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

The term "functional programming" is so ill-defined as to be effectively useless in any kind of serious conversation. I'm not aware of any broadly accepted consensus definition. Sometimes people want to use this category to talk about purity and control of side effects and use the term "functional programming" to refer to that. I would advocate the more targeted term "pure functional programming" for that definition.…

> The term "functional programming" is so ill-defined as to be effectively useless in any kind of serious conversation.

This is important. I threw my hands up and gave up during the height of the Haskell craze. You'd see people here saying things like LISP wasn't real FP because it didn't match their Haskell-colored expectations. Meanwhile for decades LISP was *the* canonical example of FP.

Similar to you, now I talk about specific patterns and concepts instead of calling a language functional. Also, as so many of these patterns & concepts have found their way into mainstream languages now, that becomes even more useful.

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

#110

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

this makes me want to move to a haskell (or any hard fp language) shop in 2026..
Post reply on HN