After like ten or fifteen hours of trying to understand what currying is, I still have no idea, and frankly don't care. If I see it in a codebase it'd just be a big red flag to avoid that job altogether.
After like ten or fifteen hours of trying to understand what currying is, I still have no idea, and frankly don't care. If I see it in a codebase it'd just be a big red flag to avoid that job altogether.
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.
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.
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.
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.
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.
You should really screen capture yourself coding sometime. On a large codebase you're lucky if the compiler even runs in 10 seconds.
> 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.
Because possibly you return the partial assuming it's a number, and try to use it somewhere else, possibly even in another file.
Sorry, I must've been more explicit instead of implying certain usage patterns. What I meant here is that I have a hard time imagining this happening because I would start working on a function by writing its type signature. Unless my types check out, I won't be able to mark this function as "done" and jump to another part of code. So the situation "you return the partial assuming it's a number" simply can not happen, that's exactly what type checking is for. By the time I use it in another place, it has to already have been type checked.
I think writing out type signatures is The Right Way, but it does take time, and The Right Way doesn't always happen on complicated projects with close deadlines.
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);
<- NaNI have doubts on whether this is a sincere attempt at understanding the concept. The linked wiki page is like a five minute read and that's enough to understand the concept at a user's level.
What I suspect is that something else is tripping you up and causing code readability issues; but since you didn't know what currying is you incorrectly ascribed currying as the problem.
Software is in good hands.
When you're writing Haskell, you should write idiomatic Haskell. Currying is part of that. It's a trivial concept and we use it liberally at work. If you're writing JavaScript though, I think it's a different story. I don't think JavaScript lends itself to FP in the way that Haskell or Elm does, and trying to make it do that only makes a project harder to work on.
The entire codebase was like that. It stood out to me as the work of someone who was very smart but worked alone and never had to work with a team, and never considered what someone trying to retrace his mental process would have to go through. He left zero documentation or comments, built the whole thing in a rush, sold it to another company, and we were the ones hired later to clean up his mess.
Some of it was very good. He was really good at efficiently encoding low level network traffic over packet encodings he invented or heavily modified. Seemed like he would've been a brilliant signals engineer or cryptologist. But having to work with his ordinary business logic code was pretty nightmarish, if interesting from a reverse engineering and psychology point of view.
It's just not how I would ever want to write code meant for mere mortals. But then again, he's a multi millionaire now and I'm a rando nobody living paycheck to paycheck, so I'm in no place to judge lol.
If he had not made such a big mess, you might not be getting this paycheck to clean it up. I think they call this “creating scope for other people” at big companies, real staff engineer stuff. =)
f a b = g(a,b) = f' b a
(x^2)^3 = x^(2*3) = (x^3)^2"Whoever has the gold makes the rules"
(*maybe the ones who spent their summers at Artek were learning "whoever makes the rules has the gold"?)
just my 2 ct
Maybe you could recall which learning materials you used?
Dynamically typed functional retrofit on with no type checking though? Hell no, that's a write-once read-never mess of unmaintainable shite.
(I also have been on a team with The Guy Who Wanted To Ramda, and I'm someone who writes build scripts in ocaml)
Inheriting that codebase felt like watching one of those serial killer dramas... obviously a really smart guy, but with a psychology unlike most people I've ever met, and really hard to follow as a normal person. I still see him with a mixture of respect, awe, curiosity, and wonder.
The thing is, none of the stuff he gave is was actually complicated. It's just a basic business dashboard. But he reinvented almost every single part of it in totally nonstandard ways that the whole project was less about coding and more about anthropology and forensic psychology.
Uncurried:
((x, y) => x * y)(3, 5) === 15
Curried:
(x => y => x * y)(3)(5) === 15
If you don't understand that, your problem is that you don't understand anonymous functions (lambdas), not that you don't understand currying.