# Function chaining in Python

## Question:

On Codewars.com I encountered the following task:

Create a function

`add`

that adds numbers together when called in succession. So`add(1)`

should return`1`

,`add(1)(2)`

should return`1+2`

, …

While I’m familiar with the basics of Python, I’ve never encountered a function that is able to be called in such succession, i.e. a function `f(x)`

that can be called as `f(x)(y)(z)...`

. Thus far, I’m not even sure how to interpret this notation.

As a mathematician, I’d suspect that `f(x)(y)`

is a function that assigns to every `x`

a function `g_{x}`

and then returns `g_{x}(y)`

and likewise for `f(x)(y)(z)`

.

Should this interpretation be correct, Python would allow me to dynamically create functions which seems very interesting to me. I’ve searched the web for the past hour, but wasn’t able to find a lead in the right direction. Since I don’t know how this programming concept is called, however, this may not be too surprising.

How do you call this concept and where can I read more about it?

## Answers:

I don’t know whether this is *function* chaining as much as it’s *callable* chaining, but, since functions *are* callables I guess there’s no harm done. Either way, there’s two ways I can think of doing this:

### Sub-classing `int`

and defining `__call__`

:

The first way would be with a custom `int`

subclass that defines `__call__`

which returns a new instance of itself with the updated value:

```
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
```

Function `add`

can now be defined to return a `CustomInt`

instance, which, as a callable that returns an updated value of itself, can be called in succession:

```
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44) # and so on..
50
```

In addition, as an `int`

subclass, the returned value retains the `__repr__`

and `__str__`

behavior of `int`

s. *For more complex operations though, you should define other dunders appropriately*.

As @Caridorc noted in a comment, `add`

could also be simply written as:

```
add = CustomInt
```

Renaming the class to `add`

instead of `CustomInt`

also works similarly.

### Define a closure, requires extra call to yield value:

The only other way I can think of involves a nested function that requires an extra empty argument call in order to return the result. I’m **not** using `nonlocal`

and opt for attaching attributes to the function objects to make it portable between Pythons:

```
def add(v):
def _inner_adder(val=None):
"""
if val is None we return _inner_adder.v
else we increment and return ourselves
"""
if val is None:
return _inner_adder.v
_inner_adder.v += val
return _inner_adder
_inner_adder.v = v # save value
return _inner_adder
```

This continuously returns itself (`_inner_adder`

) which, if a `val`

is supplied, increments it (`_inner_adder += val`

) and if not, returns the value as it is. Like I mentioned, it requires an extra `()`

call in order to return the incremented value:

```
>>> add(1)(2)()
3
>>> add(1)(2)(3)() # and so on..
6
```

If you want to define a function to be called multiple times, first you need to return a callable object each time (for example a function) otherwise you have to create your own object by defining a `__call__`

attribute, in order for it to be callable.

The next point is that you need to preserve all the arguments, which in this case means you might want to use Coroutines or a recursive function. But note that **Coroutines are much more optimized/flexible than recursive functions**, specially for such tasks.

Here is a sample function using Coroutines, that preserves the latest state of itself. Note that it can’t be called multiple times since the return value is an `integer`

which is not callable, but you might think about turning this into your expected object ;-).

```
def add():
current = yield
while True:
value = yield current
current = value + current
it = add()
next(it)
print(it.send(10))
print(it.send(2))
print(it.send(4))
10
12
16
```

You can hate me, but here is a one-liner ðŸ™‚

```
add = lambda v: type("", (int,), {"__call__": lambda self, v: self.__class__(self + v)})(v)
```

Edit: Ok, how this works? The code is identical to answer of @Jim, but everything happens on a single line.

`type`

can be used to construct new types:`type(name, bases, dict) -> a new type`

. For`name`

we provide empty string, as name is not really needed in this case. For`bases`

(tuple) we provide an`(int,)`

, which is identical to inheriting`int`

.`dict`

are the class attributes, where we attach the`__call__`

lambda.`self.__class__(self + v)`

is identical to`return CustomInt(self + v)`

- The new type is constructed and returned within the outer lambda.

The pythonic way to do this would be to use dynamic arguments:

```
def add(*args):
return sum(args)
```

This is not the answer you’re looking for, and you may know this, but I thought I would give it anyway because if someone was wondering about doing this not out of curiosity but for work. They should probably have the “right thing to do” answer.

Simply:

```
class add(int):
def __call__(self, n):
return add(self + n)
```

If you are willing to accept an additional `()`

in order to retrieve the result you can use `functools.partial`

:

```
from functools import partial
def add(*args, result=0):
return partial(add, result=sum(args)+result) if args else result
```

For example:

```
>>> add(1)
functools.partial(<function add at 0x7ffbcf3ff430>, result=1)
>>> add(1)(2)
functools.partial(<function add at 0x7ffbcf3ff430>, result=3)
>>> add(1)(2)()
3
```

This also allows specifying multiple numbers at once:

```
>>> add(1, 2, 3)(4, 5)(6)()
21
```

If you want to restrict it to a single number you can do the following:

```
def add(x=None, *, result=0):
return partial(add, result=x+result) if x is not None else result
```

If you want `add(x)(y)(z)`

to readily return the result *and* be further callable then sub-classing `int`

is the way to go.