Functional composition in python
Peter Otten
__peter__ at web.de
Sat Aug 28 15:13:25 EDT 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