5 ms·
I think you confuse currying with partial application.
by whilenot-dev 3y ago
I think you confuse currying with partial application.
- kerkeslager 3y agoAre you saying this to be helpful, or just to show you're smarter? If you're saying this to be helpful, you should probably explain more. Currying is a subset of partial application, so I suspect the person you're responding to is just being a bit loose with their wording, as opposed to not understanding the topic.
- whilenot-dev 3y agoI 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 functools.partial etc.
- kerkeslager 3y agoOkay, 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 extremely counterproductive. I'm suggesting that you could be a better reader by trying to understand what people are trying to say even if they don't communicate it exactly the way you want them to. For example, no one in this comment chain is confused about what currying or partial application are, so it's a bit rude that you've assumed people are confused because you didn't take the time to figure out what people were trying to communicate. Instead, because people didn't say things exactly the way you would have said it, you jumped in with corrections. If you take a step back and resist the urge to correct people, can you understand how "Currying is a subset of partial application" is true?
- whilenot-dev 3y ago> ...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" a function "up" (as in you don't need to know all arguments beforehand in the same context anymore) - Partial application "narrows" a function "down" (as in arguments are contained within the context of the partially applied function) "Currying is a subset of partial application" is true in the same sense as if "subtraction is a subset of addition". Sure, you can subtract negative values to have addition and add negative values to have subtraction, but that can't be your point, is it? > If you take a step back and resist the urge to correct people... Please keep it on topic.
- kerkeslager 3y ago> 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 to say it. > - Currying "widens" a function "up" (as in you don't need to know all arguments beforehand in the same context anymore) > - Partial application "narrows" a function "down" (as in arguments are contained within the context of the partially applied function) So you're saying that I'm "widening" the function "up" when I do: increment = add 1 invert = div 1 ...? But I'm "narrowing" the function "down" when I do: increment = (\x -> add 1 x) halve = (\x -> div x 2) ...? When I curry `add` above, isn't the argument 1 contained within the context of the partially applied function? When I partially apply `div` above, don't I no longer have to know all the arguments (i.e. I no longer need to know the denominator 2)? It sure seems like this up/down wide/narrow wording you're fixated on isn't a particularly better descriptions of what's going on with currying and partial application. It mean, maybe it's just my font, but the partial applications are a bit wider on my screen. ;P > "Currying is a subset of partial application" is true in the same sense as if "subtraction is a subset of addition". Sure, you can subtract negative values to have addition and add negative values to have subtraction, but that can't be your point, is it? I'm not sure I understand that analogy to say it's my point. Are you saying you would behave condescendingly toward someone who said "subtraction is a subset of addition" too? > Please keep it on topic. The topic skybrian started was derailed when you decided to "correct" him because you didn't make any effort to understand what he was trying to say. Your behavior is the topic now because your behavior became a problem.
- threatofrain 3y agoI thought it was somewhat the reverse — that the original motivation was to simulate multi-arity functions in a setting that only allows unary functions.
- bPspGiJT8Y 3y agoI 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?
- jraph 3y agoSay 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.
- Hirrolot 3y agoCurrying and partial application are dualities (think of them as function introduction/function elimination), so neither subsumes the other one. However, I agree with the wording of the original comment: when you _pass_ some arguments to a constructor and then to a method, this is (at least conceptually) partial application.
- kerkeslager 3y ago> Currying and partial application are dualities (think of them as function introduction/function elimination), so neither subsumes the other one. Could you say more? I'm not sure I understand what you're saying here.
- skybrian 3y agoYou can think of them as equivalent ways to write the same code. There are mechanical rewrites to go from one to the other, and these rewrites work in any direction. Which way is more readable depends on circumstances. When a function needs a lot of parameters to do a calculation, these parameters can be arbitrarily grouped into records and supplied in any order. Languages have convenient syntaxes for certain ways of grouping parameters together. For example, a closure creates a group of parameters in the form of a function.
- xeonmc 3y agoCurrying wraps, partial application unwraps.
- kazinator 3y ago> Currying is a subset of partial application No, it isn't; it's a different operation. Currying refers to building (effectively) functions of multiple arguments out of only one argument functions (such as in a language that has only those). A curried function is not understood to have been applied, partially or otherwise; none of its arguments have been bound to values, thereby reducing its arity. Partial application is an operation that requires one or more arguments. Currying does not require arguments; rather, the result of currying requires arguments (all of them). There is a sort of partial application (effectively) going on when the curried function is applied to the arguments, which has to be done one argument at a time through the chain. At each step, one more argument is bound, and fewer remain.