Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good idea to have a syntax sugar to function composition in Python?

Some time ago I looked over Haskell docs and found it's functional composition operator really nice. So I've implemented this tiny decorator:

from functools import partial

class _compfunc(partial):
    def __lshift__(self, y):
        f = lambda *args, **kwargs: self.func(y(*args, **kwargs)) 
        return _compfunc(f)

    def __rshift__(self, y):
        f = lambda *args, **kwargs: y(self.func(*args, **kwargs)) 
        return _compfunc(f)

def composable(f):
    return _compfunc(f)

@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]

print (f1 >> f2 >> f3)(3) #-9
print (f4 >> f1)([1, 2]) #[1, 2, 0, 1, 2, 0]
print (f4 << f1)([1, 2]) #[1, 2, 1, 2, 0]

The problem: without language support we can't use this syntax on builtin functions or lambdas like this:

((lambda x: x + 3) >> abs)(2)

The question: is it useful? Does it worth to be discussed on python mail list?

like image 593
si14 Avatar asked Feb 17 '10 15:02

si14


People also ask

What is syntactic sugar in Python?

In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.

What is function composition Python?

Function composition is the way of combining two or more functions in such a way that the output of one function becomes the input of the second function and so on.


2 Answers

IMHO: no, it's not. While I like Haskell, this just doesn't seem to fit in Python. Instead of (f1 >> f2 >> f3) you can do compose(f1, f2, f3) and that solves your problem -- you can use it with any callable without any overloading, decorating or changing the core (IIRC somebody already proposed functools.compose at least once; I can't find it right now).

Besides, the language definition is frozen right now, so they will probably reject that kind of change anyway -- see PEP 3003.

like image 115
Cat Plus Plus Avatar answered Oct 30 '22 12:10

Cat Plus Plus


Function composition isn't a super-common operation in Python, especially not in a way that a composition operator is clearly needed. If something was added, I am not certain I like the choice of << and >> for Python, which are not as obvious to me as they seem to be to you.

I suspect a lot of people would be more comfortable with a function compose, the order of which is not problematic: compose(f, g)(x) would mean f(g(x)), the same order as o in math and . in Haskell. Python tries to avoid using punctuation when English words will do, especially when the special characters don't have widely-known meaning. (Exceptions are made for things that seem too useful to pass up, such as @ for decorators (with much hesitation) and * and ** for function arguments.)

If you do choose to send this to python-ideas, you'll probably win a lot more people if you can find some instances in the stdlib or popular Python libraries that function composition could have made code more clear, easy to write, maintainable, or efficient.

like image 45
Mike Graham Avatar answered Oct 30 '22 12:10

Mike Graham