Converting f(x) into f([x]) using decorator in python

480 Views Asked by At
class foo(object):
        def __init__(self,f):
                self.f = f
        def __call__(self,args_list):
                def wrapped_f(args_list):
                        return [self.f(*args) for args in args_list]
                return wrapped_f(args_list)

if __name__=='__main__':

        class abc(object):
                @foo
                def f(a,b,c):
                        return a+b+c

        a = range(5)
        b = range(5)
        c = range(5)
        data = list(zip(a,b,c))
        print(abc.f(data))

I wrote this a few years back. When you decorate any function f(X) with @foo it becomes f(list of Xs).

What is this process called? What is it? What is its functional programming name?

Its not currying. I know simple map9(f,list of Xs) could have done it.

What are decorators/operation of decorating called mathematically?

4

There are 4 best solutions below

0
On

There are two transformations performed on your original function:

  1. it is converted from a function of three arguments to a function that takes a 3-tuple
  2. conversion from a function of a 3-tuple to a function that takes a list of 3-tuples

First transformation
In Haskell, there is a function called uncurry, documented here. (This is a two-argument version; 3-, 4-, ... versions could be easily created, too).

Second transformation
Also in Haskell, there are sets of functions with lift in their names. Here's a page on the Haskell wiki about lifting. I think that page explains it better than I could:

Lifting is a concept which allows you to transform a function into a   
corresponding function within another (usually more general) setting.

So in your case, you're lifting a function from operating on tuples to operating on a list of tuples.


Notes:

  • the OP asked for the mathematical name for decorators. I don't know what that would be, but I've heard that Haskell is supposed to be like executable mathematics, so I think Haskell's terminology is a good starting point. YMMV.
  • the OP asked for the FP name of these processes. Again, I don't know, but I assume that Haskell's terminology is acceptable.
0
On

In a functional language like Haskell, you would do this by partially applying the map function to a function which takes a tuple of arguments, resulting in a function which takes a list of argument tuples. As Jochen Ritzel pointed out in another answer, even in Python you can implement this pretty trivially using functools.partial.

Therefore I suppose this process is called "partial application of map", or some such thing. I'm not aware of any particular name for this special case.

2
On

They are simply called Decorators. What it does can be called function chaining or function annotation, but I looked around quite a bit and found no special functional/mathmatical name for this process besides those 2 (chaining/annotation).

PEP Index > PEP 318 -- Decorators for Functions and Methods

On the name 'Decorator'

There's been a number of complaints about the choice of the name 'decorator' for this feature. The major one is that the name is not consistent with its use in the GoF book [11]. The name 'decorator' probably owes more to its use in the compiler area -- a syntax tree is walked and annotated. It's quite possible that a better name may turn up.

0
On

Decorators just have special syntax, but there are no rules what decorators can return and no mathematical description. They can be any callable after all.

Your function is just a partially applied starmap:

from functools import partial
from itertools import starmap

def foo(f):
    return partial(starmap, f)