Live data from Hacker News

Currying

wiki.haskell.org

61–70 of 134 posts

Re: Currying

#61

Earlier quoted context omitted.

You're assuming that the poster doesn't understand what currying is and you're jumping in with a correction which is kinda rude. Instead of assuming you know better and jumping in with a correction, could you reread that post and assume that the person knows what they're talking about but isn't communicating exactly the way you would have communicated it? I.e., read with the intent of understanding intent, rather tha…

> but isn't communicating exactly the way you would have communicated it? My answers are almost always less intented for the person who's post I'm responding to, but more for a general audience. As others have already posted the part about "currying isn't partial application", and I mainly wanted to add a (hopefully) understanable example. And I would say that taking the OP's post as if he doesn't exactly know, what…

> My answers are almost always less intented for the person who's post I'm responding to, but more for a general audience

Same. I don't expect you're going to admit your mistake, but I'm pointing it out because the general audience is the sort of audience who is prone to this mistake (which I only know because I myself have been corrected for making this mistake).

> As others have already posted the part about "currying isn't partial application", and I mainly wanted to add a (hopefully) understanable example.

And in doing so, you're making the same mistake as those other posters, by assuming skybrian doesn't know what currying and partial application are. You're not doing your audience any favors by painting skybrian's post as if he said something wrong.

> And I would say that taking the OP's post as if he doesn't exactly know, what currying means in comparison to partia application _is_ the more favourable interpretation of their post.

How so?

Re: Currying

#62
Currying makes positional only parameters look cooler and fancier. It's a trap. Labeled arguments is the way to go for 99% of all parameters. Accidental currying is horrible.

Re: Currying

#63

Earlier quoted context omitted.

> ...can you understand how "Currying is a subset of partial application" is true? It isn't true and i can understand why someone would make that statement. Currying and partial application both come from a functional mindset that treats functions as data, and like data also functions can be transformed. Currying and partial application both satisfy a transformation depending on a desired context: - Currying "widens"…

> It isn't true and i can understand why someone would make that statement It is true, and you are smart enough to understand it if you stop assuming you're the only one who understands the topic. I'm specifically sticking with the wording "Currying is a subset of partial application" to make the point that you can understand what someone is trying to say even if they don't say it exactly the way you would like them…

Neither of your examples does curry a function. The first one partially applies it (the Haskell way), the second one wraps the partial application in a redundant lambda (Haskell again). I think that's where the confusion is, let me also try to use the Haskell syntax...

This is an add function with two arguments:

  add :: (Int, Int) -> Int
  add (x, y) = x + y
At the moment it can not be partially applied, so let's curry it:

  -- addCurr :: Int -> Int -> Int
  addCurr = curry add
Now let's partially apply it for an increment function:

  -- increment :: Int -> Int
  increment = addCurr 1
> When I curry `add` above, isn't the argument 1 contained within the context of the partially applied function?

You didn't curry it, you partially applied it. This was possible, because your function add was already curried.

Re: Currying

#64

Earlier quoted context omitted.

Okay, I understand what you're saying, and you're right, but you're missing my point and doubling down on the same mistake again. Language is inherently imprecise and communication is never perfect. When people say something, it's rude to assume they are wrong or don't understand something because they don't say it exactly the way you would have said it. This is extremely common in technical communication and it's ex…

> no one in this comment chain is confused about what currying or partial application are I can't agree here either... I know it from my own experience when i first learned about currying and partial application.

It does not appear to me that skybrian is first learning about currying and partial application, and I'm not first learning about currying or partial application in this thread either.

Your play at humility that you didn't understand currying and partial application in the past kinda falls flat if you then go on to less-humbly assume that everyone else in the conversation is stuck where you once were.

Re: Currying

#65

Earlier quoted context omitted.

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…

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…

> 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.

Re: Currying

#66

Earlier quoted context omitted.

> but isn't communicating exactly the way you would have communicated it? My answers are almost always less intented for the person who's post I'm responding to, but more for a general audience. As others have already posted the part about "currying isn't partial application", and I mainly wanted to add a (hopefully) understanable example. And I would say that taking the OP's post as if he doesn't exactly know, what…

> My answers are almost always less intented for the person who's post I'm responding to, but more for a general audience Same. I don't expect you're going to admit your mistake, but I'm pointing it out because the general audience is the sort of audience who is prone to this mistake (which I only know because I myself have been corrected for making this mistake). > As others have already posted the part about "curry…

It's ironic that your responses come off as much more rude and condescending than the comment in question.

Re: Currying

#67

Earlier quoted context omitted.

I don't read it that way, no. Currying is a process to transform a function that takes multiple arguments into higher order functions that take one argument at a time to enable partial application (as written in the article). The partial application of a function is a different transformation of a function. Some languages provide partial application without currying a function - JavaScript has bind , Python has funct…

I thought it was somewhat the reverse — that the original motivation was to simulate multi-arity functions in a setting that only allows unary functions.

I don't really understand the distinction between "multi-arity" and "unary" functions. In my mental model, all functions are unary, it's just that in "traditional", non-FP languages it's more common to pack arguments into tuples. That is `(a, b, c) => ...` in JS is a unary function which takes a tuple of 3 items. But the thing is, FP has tuples too (and in Haskell, with pretty much the same syntax), it's just that most of the time arguments aren't packed into tuples.

So could you elaborate to me where the distinction lies here and why is there a need to "simulate" things?

Re: Currying

#68

Earlier quoted context omitted.

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…

> 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.

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

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.

Re: Currying

#69

Earlier quoted context omitted.

> It isn't true and i can understand why someone would make that statement It is true, and you are smart enough to understand it if you stop assuming you're the only one who understands the topic. I'm specifically sticking with the wording "Currying is a subset of partial application" to make the point that you can understand what someone is trying to say even if they don't say it exactly the way you would like them…

Neither of your examples does curry a function. The first one partially applies it (the Haskell way), the second one wraps the partial application in a redundant lambda (Haskell again). I think that's where the confusion is, let me also try to use the Haskell syntax... This is an add function with two arguments: add :: (Int, Int) -> Int add (x, y) = x + y At the moment it can not be partially applied, so let's curry…

Okay, that's a fair critique, let it not be said I can't admit when I'm wrong. I shouldn't have used `curry` as a verb there, as my point was about the concept of currying rather than the specific curry function.

My mistake there doesn't negate my larger point, but I've gotta go touch grass.

Re: Currying

#70

Earlier quoted context omitted.

I thought it was somewhat the reverse — that the original motivation was to simulate multi-arity functions in a setting that only allows unary functions.

I don't really understand the distinction between "multi-arity" and "unary" functions. In my mental model, all functions are unary, it's just that in "traditional", non-FP languages it's more common to pack arguments into tuples. That is `(a, b, c) => ...` in JS is a unary function which takes a tuple of 3 items. But the thing is, FP has tuples too (and in Haskell, with pretty much the same syntax), it's just that mo…

Say you are dealing with a callback mechanism that takes a function and (only) one value to pass:

   function c(f, v) { ... f(v) ... }

But what you actually need this callback mechanism to call is a function that takes two arguments. No default values.

    function f2(a, b) { ... }
There's no way in js that c is going to call f2 and set its b parameter to something. You can't set v to be a tuple so b will be filled:

    c(f2, "value") => b will be undefined.

    c(f2, [1, 2]) => a will be set to [1, 2].
you need to wrap f2 for this when calling c:

    function wrapf2(b) { return f2("fixed a", b) }
Or you can make c deconstruct v, or use apply:

    function c(f, v) { ... f(...v) ...  }
    function c(f, v) { ... f.apply(null, v) ...  }
but then v always needs to be an array:

    c(f, [1])
    c(f, [1, 2])

    c(f, 1) // fails
This is why in Javascript, multi-arity is different from unary with tuples. JS doesn't have tuples as a primitive / first-class type anyway. In some math notations we don't make the difference, but in most programming languages there's a distinction. Your model where functions are always unary but can take tuples, and (v) is the same as v, is correct (and useful when the distinction doesn't matter and is just annoying to deal with), but doesn't match the way many programming languages actually work. I believe even in most functional programming languages, (v) is different from v, you also said it.

In assembly, different parameters are in fully separate registers or stack entries. Interestingly, you could imagine representing tuples as C structs (that can have only one member) and always pass structs, and passing a one-member struct will actually have the exact same effect as passing a value of a primitive type.

Post reply on HN