A type system would detect these cases, but TypeScript and Flow don't have great support for curried functions. Typing them is very verbose.
A type system would detect these cases, but TypeScript and Flow don't have great support for curried functions. Typing them is very verbose.
In JS is even worse because of the weak typing, if by mistake you get a curried function instead of a value, JS will happily operate on it giving you things like "hellofunction () {}". When you realize that there is a problem, it would be hard to find the actual cause of the error.
I think this is the reason why dynamic functional languages such as Clojure don't use auto-currying. I a static typed world, like Haskell's this is not a problem at all.
Partial application on the other hand is very useful and practical in JS and other dynamic languages.
(a: number) => (b: number) => (c: number) => number
Sure, the parameter names and parentheses are a bit annoying, but I wouldn't call that "very verbose". Comparable concepts in C++ or Java would be a nightmare to type out. fn(1)(2)(3)
That's a big drawback for me. Libraries like Ramda allow one or more arguments per function call: fn(1, 2, 3) === fn(1, 2)(3) === fn(1)(2, 3)
That's what makes the verbosity unbearable, as each type of call needs its own type.Here's a gist of the type definitions I'm using: https://gist.github.com/noppa/c600cc43fd44e33768efe6c6eec4a9...
I think something similar might work in TS too.
Demo: https://goo.gl/w3aPsw
Maybe just a matter of perception but it looks verbose to me.
Function<Number, Function<Number, Function<Number, Number>>>
The same in Kotlin is actually okayish: (Number) -> (Number) -> (Number) -> NumberOne reason for that is that my curried functions and their derivatives are usually named in a way that says exactly what they do.