Functional composition in python

Peter Otten __peter__ at web.de
Sat Aug 28 21:13:25 CEST 2010


Dmitry Groshev wrote:

> Hello all. Some time ago I wrote a little library:
> http://github.com/si14/python-functional-composition/ , inspired by
> modern functional languages like F#. In my opinion it is quite useful
> now, but I would like to discuss it.
> An example of usage:
> 
> import os
> from pyfuncomp import composable, c, _
> 
> def comment_cutter(s):
>     t = s.find("#")
>     return s if t < 0 else s[0:t].strip()
> 
> @composable #one can use a decorator to make a composable function
> def empty_tester(x):
>     return len(x) > 0 and x[0] != "#"
> 
> path_prefix = "test"
> 
> config_parser = (c(open) >>  #or use a transformer function
>                  c(str.strip).map >> #"map" acts like a function modifier
>                  c(comment_cutter).map >>
>                  empty_tester.filter >> #so does "filter"
>                  c(os.path.join)[path_prefix, _].map) #f[a, _, b] is
> used to make a partial.
>                                                     #f[a, foo:bar,
> baz:_] is also correct
> 
> print config_parser("test.txt")
 
> Any suggestions are appreciated.

With some effort you could perhaps tweak your library to accept something 
like

config_parser = c(open) | str.strip | comment_cutter | empty_tester | 
c(os.path.join)(path_prefix, _)

This looks more like a shell pipe than a C++ print statement -- which I 
think is a good thing.

More general: Yes, I know that the functional style is contagious. However, 
I find that more traditional Python code is easier to understand. Compare:

import os

def config_parser(configfile, folder):
    with open(configfile) as lines:
        for line in lines:
            name = line.partition("#")[0].strip()
            if name:
                yield os.path.join(folder, name)

for path in config_parser("test.txt", "test"):
    print path

(at least that's what I'm guessing your code is trying to achieve)

Peter



More information about the Python-list mailing list