Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add functions

I have looked all over but it is a hard topic to search for without lots of noise. I want to do something like this:

def f(arg):
  return arg * arg

def add(self, other):
  return self * other

f.__add__ = add

cubefunction = f + f

But I get errors on the assignment to cubefunction like:

TypeError: unsupported operand type(s) for +: 'function' and 'function'

Is there no function algebra possible in python or am I just making a dumb mistake?

edit: much later, I was reading Python's official intro to functional programming (http://docs.python.org/howto/functional.html), and towards the bottom it references a third party package "functional" (http://oakwinter.com/code/functional/documentation/), which can compose functions, ie:

>>> from functional import compose
>>> def add(a, b):
...     return a + b
...
>>> def double(a):
...     return 2 * a
...
>>> compose(double, add)(5, 6)
22
like image 358
user318904 Avatar asked Nov 04 '10 20:11

user318904


People also ask

Can you add two functions?

Just like we can add and subtract numbers, we can add and subtract functions. For example, if we had functions f and g, we could create two new functions: f + g f+g f+g and f − g f-g f−g .

What are the step in adding function?

To add or subtract functions, just add or subtract the values at each point where it makes sense. If the functions are given by formulas, you can just add or subtract the formulas (it doesn't matter whether you plug in values before or after).


2 Answers

I don't think you can do this. However, using the __call__ magic method lets you define your own callable class which acts as a function and upon which you can define __add__:

>>> class FunctionalFunction(object):
...     def __init__(self, func):
...             self.func = func
...
...     def __call__(self, *args, **kwargs):
...             return self.func(*args, **kwargs)
...
...     def __add__(self, other):
...             def summed(*args, **kwargs):
...                     return self(*args, **kwargs) + other(*args, **kwargs)
...             return summed
...
...     def __mul__(self, other):
...             def composed(*args, **kwargs):
...                     return self(other(*args, **kwargs))
...             return composed
...
>>> triple = FunctionalFunction(lambda x: 3 * x)
>>> times_six = triple + triple
>>> times_six(2)
12
>>> times_nine = triple * triple
>>> times_nine(3)
27

Here + is overloaded to pointwise addition, and * to composition. Of course, you can do anything you like.


Interesting question for the Python gurus: why does the following not work (filthy hack though it is)?

>>> from types import MethodType, FunctionType
>>> f = lambda: None
>>> f.__add__ = MethodType(lambda self, other: "summed!", f, FunctionType)
>>> f.__add__(f)
'summed!'
>>> f + f
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'function' and 'function'
like image 125
Katriel Avatar answered Oct 29 '22 03:10

Katriel


I think what you mean to do is:

cubefunction = (lambda x: add(f(x), f(x)))
like image 24
Ross Light Avatar answered Oct 29 '22 02:10

Ross Light