dart-lang / language

Design of the Dart language
Other
2.65k stars 201 forks source link

Sugar for simulated higher-kinded types through type defunctionalization. #844

Open modulovalue opened 4 years ago

modulovalue commented 4 years ago

Languages without higher-kinded types (HKT) have libraries for functional programming that make use of simulated HKT through [2014] Type defunctionalization (1.3).

Examples: TypeScript: fp-ts Swift: bow Java: HKT & highj Kotlin: arrow

They require quite a bit of boilerplate which does make them impractical in day to day use.

This is not a topic that I expect to receive much interest and support anytime soon. Also, I'm not an expert on that topic, but I've come across the limitations of dart when trying to employ techniques that are more common in the FP world. And with this issue I'd like to ask the language team if they could provide their thoughts on adding support (or rather sugar) for simulated HKT through type defunctionalization.

Note: The dart specification explicitly says Dart does not, and will not, support higher-kinded types I assume that this decision has been made in the context of 'real' higher-kinded types. I want to be clear, I'm opening this issue in the context of supporting simulated higher-kinded types through type defunctionalization (or any other technique).

modulovalue commented 1 year ago

This issue was opened three years ago. Back then, simulating higher kinded types wasn't really practical. Many features were added to Dart (static extension methods, typedefs over values, null safety) that make this possible (and even practical!) now.

Sealed classes and exhaustive matching over subtypes will make this even safer.


There are at least two packages that make use of simulated higher kinded types:

They can be consulted for advice on how to implement simulated higher kinded types in Dart.


I claim that it is now quite practical* to work with simulated higher kinded types. It involves a non trivial amount of boilerplate, but there are some cases where it is justified if more safety or generality is needed.

For any functional programmers coming across this issue, here is a short summary of what I've experienced:

I plan to share examples for some them once I find a nice way to implement GADTs in Dart.

(* I would recommend having a custom code generator)