On Aug 29, 5:14 am, Steven D'Aprano <st...@remove-this- cybersource.com.au> wrote: > On Sat, 28 Aug 2010 21:30:39 +0400, 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] != "#" > > Why do you need a decorator to make a composable function? Surely all > functions are composable -- it is the nature of functions that you can > call one function with the output of another function. > > > > > 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") > > print (c("[x ** %s for x in %s]")[2, _] << c(lambda x: x * 2).map)([1, > > 2, 3]) > > > Any suggestions are appreciated. > > Did you expect us to guess what the above code would do? Without showing > the output, the above is just line noise. > > What does c() do? What does compose() do that ordinary function > composition doesn't do? You say that "map" acts as a function modifier, > but don't tell us *what* it modifies or in what way. Same for filter. > > So anyone not familiar with C syntax, the use of << is just line noise. > You need to at say what you're using it for. > > -- > Steven
Yep, it's my mistake. I thought this syntax is quite intuitive. Here is some explanations in code: @composable def f1(x): return x * 2 @composable def f2(x): return x + 3 @composable def f3(x): return (-1) * x @composable def f4(a): return a + [0] @composable def sqrsum(x, y): return x ** 2 + y ** 2 print f1(2) #4 print f2(2) #5 print (f1 << f2 << f1)(2) #14 print (f3 >> f2)(2) #1 print (f2 >> f3)(2) #-5 print (c(float) << f1 << f2)(4) #14.0 print (sqrsum[_, 1] << f1)(2) #17 print (sqrsum[_, _].map)([1, 2, 3, 4, 5]) #[2, 8, 18, 32, 50] print (c(lambda x: x * 2).map >> c("[x * %s for x in %s]")[3, _])([1, 2, 3]) #[6, 12, 18] Generally, f1 >> f2 means "lambda x: f2(f1(x))" or "pass the result of f1 to f2". But in python function can return only one value, so a composable function should be a function of one argument. So some form of making partial is needed, and here comes a f[a, b, _] notation, which means "substitute 3rd argument of f, first twos are a and b". Finally, we need some form of syntactic sugar for this: c(map)[c(f),_], so we have a "map" modifier, which transforms function F to an isomorphism or mapping between lists. For example, c(lambda x: x * 2).map is equal to lambda x: map(lambda y: y * 2, x). "Filter" modifier is the same thing for boolean functions. >What does c() do? What does compose() do that ordinary function >composition doesn't do? I need c() or composable() to make an objects with overloaded operators. All in all, all this stuff is just a syntactic sugar for nested functions, maps and filters, which brings a new semantics for old operators (so one can call it edsl). -- http://mail.python.org/mailman/listinfo/python-list