2

I have a function f: (a, b, c = 5, d = 0) -> {...} that takes between 2 and 4 arguments.

I want to pass a "bound" version of this function that always uses the defaults for the last arguments, but uses specific values (say 1 and 2) for the first two arguments. That is, I want g: () -> f(1, 2).

If I were to do partial application, I would get g': (c = 5, d = 0) -> f(1, 2, c, d). That is, partial application wouldn't enforce the zero-argument nature of g that I desire, instead giving me g' which takes between 0 and 2 arguments.

What is the technique for getting g from f called, if anything?

Domenic
  • 110,262
  • 41
  • 219
  • 271
  • 1
    `f` already has the default arguments, so why wouldn't currying `g: () -> f(1, 2)` work for you? – Matt Ball Jun 02 '11 at 16:28
  • 2
    I do not understand how this question is related to currying. The problem you are describing does not seem to be related to making a function take one argument and return another function, which is what currying is. – murgatroid99 Jun 02 '11 at 16:39
  • As @murgatroid99 pointed out, this has nothing to do with currying... I think you mean "partial application", which is something a lot of people confuse with currying. I know of no particular name for the technique you're describing. – Tom Crockett Jun 02 '11 at 16:52
  • @murgatroid99, @pelotom: You guys are right, I was talking about partial application, not currying. How embarassing -_-. – Domenic Jun 02 '11 at 16:59
  • @Matt Ball I don't understand what you mean. I want `g` to take 0 arguments, instead of between 0 and 2. – Domenic Jun 02 '11 at 17:00
  • @ShreevatsaR I am working in JavaScript. But that should be pretty irrelevant. I know how to _implement_ what I am describing; I just don't know what to call it. – Domenic Jun 02 '11 at 17:01
  • @Domenic: What Matt means is that the function `g: () -> f(1,2)` takes precisely 0 arguments, not between 0 and 2. (If your language doesn't allow such a definition that's another matter.) – ShreevatsaR Jun 02 '11 at 18:43
  • @ShreevatsaR: Yes, my point was that I want `g`. But instead, partial application gives me `g'`. What is the name of the technique that gives me `g`? – Domenic Jun 02 '11 at 18:57
  • @Domenic: "partial application gives me `g'`" — I don't see why that's inevitable. Surely it depends on the language etc.: whether "partial application" supports specifying the arity of g, exactly when the default arguments are bound, etc. In any case, perhaps this is your real question: given a function `f(a, b, c=5, d=0)` with optional arguments, what is the function `t(f)(a,b) = f(a,b,5,0)` which takes exactly 2 arguments? Then the `g` you want would just be partial application on `t(f)`. (Or, equivalently, `t(g')` where `g'` is the function with 2 optional arguments you mentioned above.) – ShreevatsaR Jun 02 '11 at 20:58
  • @ShreevatsaR thanks for the clarifying remarks; I think you are right on all counts. Please feel free to post that in answer form, along with either a name for the `t` operation or a statement that the `t` operation doesn't have a name that you know of, and I'll accept it. Thanks! – Domenic Jun 03 '11 at 07:33

1 Answers1

2

Posting my comment as an answer: it seems that this question has little to do with functional programming or currying or partial application, but is instead precisely about taking a function that takes optional arguments that have defaults, and making a new function with no optional arguments in which the default arguments have been fixed.

Call this conceptual transformation T. Assuming for some reason that partial application means that optional arguments remain optional (which need not be universal, but then again, the familiar functional programming languages — Haskell etc. — don't even have optional arguments), there are at least two ways to get g from f.

    • Take f: (a, b, c = 5, d = 0) -> {....} which takes 2 to 4 arguments.
    • Generate the new function T(f) : (a,b) -> {...} which takes exactly 2 arguments. That is, T(f)(a,b) = f(a,b) = f(a,b,5,0).
    • Now do partial application on T(f) fixing its two arguments as 1 and 2, and call the resulting function g. That is, g() = T(f)(1,2) = f(1,2) = f(1,2,5,0).

    • Take f: (a, b, c = 5, d = 0) -> {....} which takes 2 to 4 arguments.
    • Do partial application on f fixing its first two arguments as 1 and 2, and call the resulting function g'. That is, g' : (c=5, d=0) -> f(1, 2, c, d). It takes between 0 and 2 arguments.
    • Generate the new function T(g) : () -> {....} which takes exactly 0 arguments. That is, T(g)() = g'() = g'(5, 0) = f(1, 2, 5, 0).

In any case, the quandary in the question seems to hinge on T, rather than any aspect of functional programming or currying or partial application. I don't know if T has enough of a point to have a standard name, but something like "fixing/binding default arguments" should be fine.

ShreevatsaR
  • 38,402
  • 17
  • 102
  • 126