Cookbook

So, you've read the basic documentation, but you need some more concrete examples of how to use these bizarre new functions? Well, you've come to the right place. This page aims to provide some easy-to-understand, practical illustrations of functional's capabilities.

An attempt has been made to order these examples by difficulty, ascending. Of course, since I wrote the module and the documentation, my ideas about "easy" might not quite mesh with yours. If you find one of these examples in need of further explication, don't hesitate to drop me a line.

A multi-function compose()

Left to its own devices, functional.compose() will only compose two functions. That's enough for most situations, but every know and then, you might find yourself needing to compose three or four or n functions. Here's how to write a multi-function compose() using some other functional tools:

from functional import partial, compose

multi_compose = partial(reduce, compose)

multi_compose() makes an appearance in several other examples on this page.

For bonus points, multi_compose() is defined in what's known as tacit or point-free programming, meaning that the function's arguments are implicit.

An auto-stringifying join

One of my biggest annoyances with using "".join(...) to join a list is that they first have to be converted to strings. This is unsightly and something I wish the join() method did on its own. Let's write a join() function that will automatically stringify its arguments.

from functional import partial, compose
                    
join = compose("".join, partial(map, str))

A walk-through:

  • partial(map, str) is roughly equivalent to

    def f(args):
        return map(str, args)
  • The call to compose() turns wraps this in another function, yielding something like this:

    def g(args):
        return "".join(map(str, args))

If bound methods make you squeamish, we can get the same effect using operator.concat():

from functional import partial, compose, foldl
from operator import concat

join = compose(partial(foldl, concat, ''), partial(map, str))

A functional-style __hash__() method

An example pulled from real life, using the join() function we defined earlier. This calculates a hash for an object by hashing some of the object's attributes, concatenating those stringified hash values, then hashing the resulting long string.

from functional import partial, compose

join = compose("".join, partial(map, str))
                    
def __hash__(self):
    attrs = ['__class__', 'foo', 'bar', 'baz']
    return hash(join(hash(getattr(self, attr)) for attr in attrs))

This method is somewhat inefficient, in that it iterates over attrs twice: once in the generator expression, then again in join(). This can be overcome by defining a more specific join() function:

from functional import partial, compose
                    
hashing_join = compose("".join, partial(map, compose(str, hash)))

def __hash__(self):
    attrs = ['__class__', 'foo', 'bar', 'baz']
    return hash(hashing_join(getattr(self, attr) for attr in attrs))
functional