Skip to content

Instantly share code, notes, and snippets.

@jbochi
Created September 29, 2012 11:29
Show Gist options
  • Save jbochi/3803739 to your computer and use it in GitHub Desktop.
Save jbochi/3803739 to your computer and use it in GitHub Desktop.
function composition in python
class O():
def __repr__(self):
return "<" + ' *o* '.join(map(repr, self.funs)) + ">" if self.funs else "<composer>"
def __init__(self, funs=None):
self.funs = funs if funs else []
def __rmul__(self, other):
other_funs = other.funs if isinstance(other, O) else [other]
return O(other_funs + self.funs)
def __mul__(self, other):
other_funs = other.funs if isinstance(other, O) else [other]
return O(self.funs + other_funs)
def __call__(self, *args):
result = args
for fun in reversed(self.funs):
result = apply(fun, result) if isinstance(result, tuple) else fun(result)
return result
o = O()
def test_one_argument():
neg = lambda x: -x
half = lambda x: x / 2
assert (abs *o* neg)(2) == 2
assert (neg *o* abs)(2) == -2
assert (neg *o* abs *o* half)(-4) == -2
assert (half *o* neg)(-4) == 2
def test_two_arguments():
import math
add_vectors = lambda a, b: map(sum, zip(a, b))
length = lambda a: math.sqrt(sum([x * x for x in a]))
negate_vector = lambda a: [-x for x in a]
subtract_vectors = lambda a, b: add_vectors(a, negate_vector(b))
distance = length *o* subtract_vectors
assert distance([2, 2], [-1, -2]) == 5
@hltbra
Copy link

hltbra commented Oct 1, 2012

Didn't like the o syntax suggar. I prefer using a composite function:

def compose(*funcs):
    def newf(*args):
        result = args
        for f in funcs:
            result = apply(f, result) if isinstance(result, tuple) else f(result)
        return result
    newf.__name__ = '<composite of ' + ', '.join(map(repr, funcs)) + '>'
    return newf


def half(x):
    return x / 2.0

def opposite(x):
    return -x


half_and_opposite = compose(half, opposite)

print half_and_opposite(120)
print half_and_opposite.__name__

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment