In article <(E-Mail Removed)>,

"Alan G Isaac" <(E-Mail Removed)> wrote:

> Given a list of functions, it seems there must be a

> Pythonic approach to composition. Something like

>

> def compose(fns): return lambda x: reduce(lambda f,g: f(g),fns)(x)

>

> This will not work because the argument 'x' is not "inside".

> What is the proper formulation?

>
If you are only concerned with unary functions, then composition is

fairly trivial to deal with:

def compose(*fns):

def id(x): return x

def c2(f, g):

def h(x): return f(g(x))

return h

return reduce(c2, fns, id)

However, if you want to deal with functions that may take multiple

arguments, you must be a little more clever. Here's one way that seems

to work okay:

def compose(*fns):

def id(*args): return args

def box(res):

if isinstance(res, (list, tuple)):

return res

else:

return (res,)

def unbox(res):

if isinstance(res, (list, tuple)) and len(res) == 1:

return res[0]

else:

return res

def c2(f, g):

def h(*args):

return unbox(f(*box(g(*args))))

return h

return reduce(c2, fns, id)

For instance:

def f1(a, b):

return (a / b, a % b)

def f2(a, b):

return a + b

def f3(a):

return a + 2

h = compose(f3, f2, f1)

h(5, 3)

==> 5

This will work, but it's not the most efficient possible solution. You

could defer unboxing until the end by defining another intermediate

function.

Cheers,

-M

--

Michael J. Fromberger | Lecturer, Dept. of Computer Science

http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA