kachayev / fn.py

Functional programming in Python: implementation of missing features to enjoy FP
Other
3.35k stars 204 forks source link

@composable decorator #27

Open kachayev opened 11 years ago

kachayev commented 11 years ago

Special @composable decorator to bring new functionality to function:

berrytj commented 10 years ago

This seems interesting, are you still thinking about it?

kachayev commented 10 years ago

@berrytj Yeah, I still think about it. I just don't want to make obvious mistake: to write decorator which will require special decorators order in each case. Which means that I want @composable decorator to be composable itself.

berrytj commented 10 years ago

(Stating the obvious for a moment.) composable must return a class for operator overrides to work. So any decorator that returns only functions will fail if called after composable, e.g.:

@memoize
@composable
def double(n):
    return n*2

(double * sum)([1, 2])  # => TypeError

I can only think of two ways around this, neither ideal. The first is to modify your decorators inline:

def classdecorator(decorator):
  def inner(f):
    if isinstance(f, types.FunctionType):
      return decorator(f)
    else:
      f.__call__ = decorator(f.__call__)
      return f
  return inner

@classdecorator(memoize)
@composable
def double(n):
  return n*2

(double * sum)([1, 2])  # => works

The second is to use libraries whose decorators have already undergone this operation (to support classes masquerading as functions). The toolz folks might allow that functionality addition.