I'm not very familiar with functional programming and Haskell in particular. I think I understand the gist of this article, and "use data structures that make illegal states unrepresentable". However, is there a similar article but written with more common languages (C#, C++, Java, Go) in mind? Or is a big part of this concept only relevant for strong functional languages with sum types and pattern matching?
masklinn|19 days ago
Java has sum types, incidentally. And pattern matching.
lock1|18 days ago
However, I don't think it's doable in languages with structural type systems like Typescript or Go's interface without a massive ergonomic hit for minimal gain. Languages with a structural type system are deliberately designed to remove the intentionality of "type T cannot be assigned to type S" in exchange for developer ergonomics.
For C#, there's F#-focused article, which I believe some of it can be applied to C# as well:F# - Railway Oriented Programming - https://fsharpforfunandprofit.com/rop/
F# - Designing with Types - https://fsharpforfunandprofit.com/series/designing-with-type...
For modern Java, there is some attempt at popularizing "Data-Oriented Programming" which just rebranded "Type-driven design". Surprisingly, with JDK 21+, type-driven style is somewhat viable there, as there is algebraic data type via `record` + `sealed` and exhaustive pattern match & destructuring.
Inside Java Blog - Data-Oriented Programming - https://inside.java/2024/05/23/dop-v1-1-introduction/
Infoq - Data-Oriented Programming - https://www.infoq.com/articles/data-oriented-programming-jav...
For Rust, due to the new mechanics introduced by its affine type system, there is much more flexibility in what you could express in Rust types compared to more common languages.
Rust - Typestate Pattern - https://cliffle.com/blog/rust-typestate/
Rust - Newtype - https://rust-unofficial.github.io/patterns/patterns/behaviou...
masklinn|18 days ago
Go only has structural interfaces, concrete types are nominative, and this sort of patterns tends to be more on the concrete side.
Typescript is a lot more broadly structural, but even there a class with a private member is not substitutable with a different class with the same private member.