top | item 39958574

(no title)

worddepress | 1 year ago

In Haskell it is easy. If you "forget" the last argument to a function, you get returned a function where you can provide that later on. A bit like saying "you can fill this in later". That is a "curried" function.

Example

    add 1 2 // add is curried, you can use it like this, the "normal" way, returns 3

    p = add 1 // since add is curried I can also provide just the first argument
    p 2 // and then apply the last argument to the intermediate results, returns 3
What is the point of using curried functions in JS? I am not really sure. It is not very ergonomic and I wouldn't like to use them in general. Maybe for some specific things it could be useful.

In Haskell curried form is the default and the syntax and semantics really suits it. In JS non-curried is the default and it just looks odd, and you need libraries to support it. That library you mentioned doesn't look nice to use.

discuss

order

zarzavat|1 year ago

It’s worth noting that even in Haskell, overuse of the so called point-free style is disliked for much the same reasons:

https://wiki.haskell.org/Pointfree

There is a sliding scale and even at the Haskellers have a limit of how much point-free they can take.

In JavaScript use of the style is problematic in another way: unlike Haskell in JS the length of the argument list is variable, which means that if someone adds another argument to either the caller or callee it can break the code in subtle and unexpected ways.

For this reason it’s good practice to always wrap functions being passed as arguments to another function in a lambda expression.

i.e instead of writing: g(f), you should usually write: g(x => f(x)) unless you have good reason to believe that g(f) is safe. This makes it difficult to use point-free style at all in JS.

For example arr.map(f) is generally unsafe in JS because if `f` adds an extra default argument of type number then your code will break and even TypeScript won’t let you know.

epolanski|1 year ago

All your JS/TS example says is that the `f` callback is not curried, so your point is entirely lost on me.

taneq|1 year ago

Honestly, a lot of these 'advanced' features aren't a good choice in most codebases IMO. The vast majority of 'enterprise' coding is CRUD and glue, where execution speed doesn't matter and being as simple and explicit as possible is the highest virtue. And the significant number of professional coders who worked hard to get their heads around things like pointers and printf format specifiers are still plenty productive in those kinds of codebases.

Things like currying are fun but like anything that encourages gratuitously deep call trees, they wreck your locality of reference (as a developer) and force you to 'decompile' the code in your head in order to understand it. I'm sure that a top level developer would be able to write curried JS in such a way that it was clear and readable to another top level developer, but that's not the point. The code's not for you, it's for newbie who gets stuck with it when you move on.

kerkeslager|1 year ago

I've never liked this "feature".

What if you forget, not in quotes, to give the second argument? Why on earth would you want to get a type error in a completely different part of the code because you got a function instead of an integer? Wouldn't it be desirable to have the compiler just tell you that you forgot the second argument where you forgot the second argument?

Is it really valuable to be able to do:

    p = add 1
...instead of:

    inc = (\x -> add 1 x)
...or, heaven forbid:

    inc x = add 1 x
...?

I mean, I get the idea, they're following the lambda calculus, but this is one of the things that should have been dropped when they started to expand the lambda calculus to a general purpose programming language.

bPspGiJT8Y|1 year ago

> What if you forget, not in quotes, to give the second argument?

I will get a type error and it will take me 2-3 seconds to figure out what it is about.

> Why on earth would you want to get a type error in a completely different part of the code because you got a function instead of an integer?

Why would it be in a completely different part of the code? At most it would be 2 lines away, but usually on the same line.

worddepress|1 year ago

You don't have to use type inference everywhere.

But I don't think this is a problem in practice for whatever reason. Haskell does have a lot of "big scary type error, wtf" type problems, but not from currying. Or at least it did have when I last used it 5 years ago, it may have improved in the compiler error message front.

Also it is better than JS anyway (low bar):

    >  function add(a,b) {return a + b}; add(1);

    <- NaN