top | item 46979298

(no title)

lock1 | 18 days ago

  > Or is a big part of this concept only relevant for strong functional languages with sum types and pattern matching?
It need not strictly be a pure functional language for type-driven style to be usable. Type-driven style only requires the fact that some type cannot be assigned to another type, so it's kind of possible to do even in a language like C, as `int a = (struct Foo) {};` would get rejected by C compilers.

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.

  > However, is there a similar article but written with more common languages (C#, C++, Java, Go) in mind?
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...

discuss

order

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

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.