[Python-ideas] Function composition (was no subject)

Steven D'Aprano steve at pearwood.info
Sat May 9 20:16:43 CEST 2015


On Sat, May 09, 2015 at 11:38:38AM -0400, Ron Adam wrote:

> How about an operator for partial?
> 
>           root @ mean @ map $ square(xs)

Apart from the little matter that Guido has said that $ will never be 
used as an operator in Python, what is the association between $ and 
partial?

Most other operators have either been used for centuries e.g. + and - or 
at least decades e.g. * for multiplication because ASCII doesn't have 
the × symbol. The barrier to using a completely arbitrary symbol with no 
association to the function it plays should be considered very high.

I would only support an operator for function composition if it was at 
least close to the standard operators used for function composition in 
other areas. @ at least suggests the ∘ used in mathematics, e.g. 
sin∘cos, but | is used in pipelining languages and shells and could be 
considered, e.g. ls | wc.

My own preference would be to look at @ as the closest available ASCII 
symbol to ∘ and use it for left-to-right composition, and | for 
left-to-right function application. E.g.

(spam @ eggs @ cheese)(arg) is equivalent to spam(eggs(cheese(arg)))

(spam | eggs | cheese)(arg) is equivalent to cheese(eggs(spam(arg)))

also known as compose() and rcompose().

We can read "@" as "of", "spam of eggs of cheese of arg", and | as 
a pipe, "spam(arg) piped to eggs piped to cheese".

It's a pity we can't match the shell syntax and write:

spam(args)|eggs|cheese

but that would have a completely different meaning.


David Beazley has a tutorial on using coroutines in pipelines:

http://www.dabeaz.com/coroutines/

where he ends up writing this:

    f = open("access-log")
    follow(f,
           grep('python',
           printer()))


Coroutines grep() and printer() make up the pipeline. I cannot help but 
feel that the | syntax would be especially powerful for this sort of 
data processing purpose:

    # could this work using some form of function composition?
    follow(f, grep('python')|printer)



-- 
Steve


More information about the Python-ideas mailing list