Hello, this is an interesting and non-typical article. I enjoyed reading it.
However, I would not agree that Haskell can forgo currying nor would I agree that currying is not fundamental to functional programming.
Lambda calculus defines all functions (abstractions) to take exactly one input and produce exactly one output. Thus, currying is a fundamental property of any lambda calculus and the only tool it has to work with functions taking multiple arguments.
Since Haskell is built on lambda calculus and is semantically a typed lambda calculus itself, currying is not really an optional feature, but rather a fundamental property of the language. As you mentioned in the article, all functions in Haskell are single input functions (hence the strange type signatures). This means that it is actually impossible to apply any function without currying coming into play. For example, let's take a look at the following code:
sub :: (Num a) => a -> a -> a
sub first second = first - second
main = print (sub 7 2)
The function sub is not called using two arguments. This is what actually happens:
main = print ((sub 7) 2)
The function is applied to the number 7. This application returns a new function which is applied to the number 2 finally returning the number 9. All functions (and their applications) in Haskell work like this.
Taking currying away from Haskell would render it useless. You can, of course, allow functions to take more than one argument in the first place. However, by doing this, Haskell would seize to be a lambda calculus and a purely functional language. I would not say that they "decided to apply currying to function calls". Functions and function calls are where currying comes from and it is actually inevitable.
If by saying that Haskell could forgo currying you meant that currying doesn't really have any practical applications aside from providing consistent conceptual purity, I would also have to disagree :). The main use case of currying is partial application of functions. I believe this concept is as important to functional programming as inheritance is to OOP.
P.S. I realize some of the things I mentioned here are explained in the article or in one of the prior comments. I've decided to reiterate them for the sake of completeness and clarity :)
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.