4 ms·
2. TypeScript's type checker, at least in its current state, has been downright painful to work with for functional programming with functional composition and
by lewisl9029 8y ago
2. TypeScript's type checker, at least in its current state, has been downright painful to work with for functional programming with functional composition and higher order functions in general, with errors that are incredibly opaque and unhelpful, and its poor inference introduces so much seemingly avoidable type-related verbosity that it completely distorts the signal to noise ratio in our code.
A prime example for this is ramda's pipe function: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ramda/index.d.ts#L2148 https://github.com/DefinitelyTyped/DefinitelyTyped/blob/mast...
A simple function that composes functions together in reverse order requires:
1) The definition to be an exhaustive list of all the variations of input functions that pipe can accept (which of course would technically require an infinite number of declarations to fully specify, so ramda had to call it quits at 10).
2) The user of pipe to specify output types for every single function being composed at every step, even though that should be possible to infer using the return type of each function in the pipeline.
These kinds of limitations plague our codebase everywhere we try to define higher order functions in our own code as well, because it means we have to ask users of the function to specify the result of the function argument as a generic parameter even though it should be perfectly inferrable from the function argument itself, and the noise buildup becomes exponential as you start composing higher order functions together due to pipe suffering the same limitation. The issue also rears its head when using higher order components with recompose, which we make heavy use of as well.
I'd love to hear how other teams working with functional programming in TypeScript work with these limitations. Perhaps we're missing something fundamental that could vastly improve our experience?
- lewisl9029 8y ago3. TypeScript only supports positional generic parameters (i.e. you can't give them names). It's well known that positional semantics don't scale when it comes to argument lists, because when changing the API of something with a positional argument list, adding an argument in an arbitrary position becomes a breaking change that requires all usages to be updated. Unfortunately, part of the fallout from point 2 means we often need to define higher order functions that require a decent number of generic parameters, all of which have to be positional due to this limitation. There's a hack that we discovered that allows you to have poor-man's named generics by using a single generic argument with named properties, inspired by this comment: https://github.com/Microsoft/TypeScript/pull/23696#issuecomment-408717985 https://github.com/Microsoft/TypeScript/pull/23696#issuecomm... But it's incredibly verbose, and doesn't support optional generic arguments or defaults as far as I can tell. We still use it despite this, because we believe the verbosity and having to specify every generic argument is the lesser of two evils compared to offering APIs that requires breaking changes for every addition. But that we have to make this choice points to a glaring omission in the design of the type system.
- phiresky 8y agoYou can kind of give generics names by declaring them in an interface and passing T extends Interface as the generic parameter
- woah 8y agoThis is probably not what you wanted to hear, but I’m glad they don’t optimize for Ramda. On projects where I’ve had to use it, it just generally results in a bunch of fanciful syntax flourishes from the Ramda enthusiast on the team. They’ll jump on anything that looks like array manipulation, eager to try some neat Ramda tricks. In the end a “dumb” solution with loops usually ends up being shorter and simpler (not to mention, much easier on the memory without all the copying), and this is the style of code that Typescript optimizes for.
- _Codemonkeyism 8y ago... and then they go, leave the code behind and make another team happy.
- phiresky 8y agoYou realize that your problems with Rambda were mostly fixed in TS3.4?