2

Hypothetical situation - can a currying function have an unknown number of arguments (kind of like varargs) Eg in Python:

addByCurrying(1)(2)(3)(4)

Should equal 10

addByCurrying(5)(6)

Should equal 11

How could I implement it?

vikarjramun
  • 353
  • 2
  • 9
  • You can't do that in the most straightforward way. That would mean that `addByCurrying(1)(2)` is both a number and a function, which isn't possible. – Tanner Swett Aug 24 '16 at 02:37
  • 4
    Have a look at [Is it possible to have currying and variadic function at the same time?](http://programmers.stackexchange.com/q/286231) – jscs Aug 24 '16 at 02:39
  • Funny thing I discovered while playing around a bit: `(lambda x: x (x)) ((lambda a: lambda b: lambda c: a (b)) (lambda x: x (x)))` takes an argument and returns a _new_ instance of itself, meaning you can pass as much arguments as you want. – user6245072 Aug 24 '16 at 06:54
  • @Tanner Swett could Church Encodings help on that? – user6245072 Aug 24 '16 at 06:55
  • 2
    Possible duplicate of [Is it possible to have currying and variadic function at the same time?](http://programmers.stackexchange.com/questions/286231/is-it-possible-to-have-currying-and-variadic-function-at-the-same-time) – Frank Aug 24 '16 at 09:03
  • @user6245072 Not really. From the perspective of Python, Church encodings aren't numbers; they're functions which represent numbers. Not only that, but their behavior is inconsistent with what vikarjramun is trying to do. – Tanner Swett Aug 24 '16 at 12:22

2 Answers2

3

I recently answered a question on S.O regarding this exact situation. You can't do this with traditional functions in Python.

You can do this by taking advantage of callables though, overloading the __call__ dunder of an int subclass.

In short, return a new instance of your self with the updated value (+ here):

class addByCallable(int):
    def __call__(self, v):
        return type(self)(self + v)

Now, you call it and get this 'form' of currying:

addByCallable(1)(2)(3)  # 6

Which is as close as you can get to doing this in Python.

  • 1
    Actually this is a great answer! Overloading __call__ is a creative solution that I wouldn't have even thought of. So to do this for another class, I would just define a __call__ function for it, that uses the value of self to return the same class, but also is a function! That's exactly what I was hoping for! – vikarjramun Aug 25 '16 at 00:15
  • "but also is a function" isn't the exact terminology i'd use :-P. It is also callable, that is, it can *behave* as a function, that's really all we need here. – Dimitris Fasarakis Hilliard Aug 25 '16 at 01:53
1

This is not possible since there is no way the function could know if it should return a number or a curried function.

There are various way of "cheating" to achieve some thing somewhat like this, for example you could call with no arguments in order to get the number rather than a function:

addByCurrying(1)(2) --> curried function
addByCurrying(1)(2)() --> the number 3

Which trick is most appropriate depends on what you are trying to achieve.

JacquesB
  • 57,310
  • 21
  • 127
  • 176