Documentation

The functional package offers a number of tools common in functional-paradigm programming. This page provides documentation on the functions and classes that ship with the functional package.

Those looking to learn more about functional programming are encouraged to do a Google search for "python functional programming". There's a wealth of material on the Internet on this subject.

Other tools that will be of interest to functional programmers:

A.M. Kuchling has written a good HOWTO for functional programming in Python that covers the above-mentioned modules and more.

Back on this site, I've started a functional cookbook, containing practical applications of functional's tools.

Index

  • compose - function composition
  • filter - find every item in a sequence that matches a given predicate
  • flip - reverse the arguments to a function
  • foldl - reduce a sequence to a single value
  • foldr - like foldl, but starts from the right
  • id - the identity function
  • map - apply a function to every item in a sequence
  • partial - partial function application
  • scanl - like foldl, but shows its work
  • scanr - like foldr, but shows its work

functional

compose

compose(outer, inner, unpack=False)

compose implements function composition. In other words, it returns a wrapper around the outer and inner callables, such that the return value from inner is fed directly to outer. That is,

>>> def add(a, b):
...     return a + b
...
>>> def double(a):
...     return 2 * a
...
>>> compose(double, add)(5, 6)
22

is equivalent to

>>> double(add(5, 6))
22

The unpack keyword is provided to work around the fact that Python functions are not always fully curried. By default, it is expected that the inner function will return a single object and that the outer function will take a single argument. Setting the unpack argument causes compose to expect a tuple from inner which will be expanded before being passed to outer. Put simply,

compose(f, g)(5, 6)

is equivalent to

f(g(5, 6))

while

compose(f, g, unpack=True)(5, 6)

is equivalent to

f(*g(5, 6))

filter

filter(function, iterable)

Apply function to every element of iterable, returning those elements for which function returned a true value. filter() is fully equivalent to

[x for x in iterable if function(x)]

Basically, functional.filter() works in much the same way as Python's filter() built-in, except functional's version...

  • ...iterates over subclasses of str, unicode and tuple correctly.

  • ...doesn't support the None nonsense that the built-in does.

  • ...always returns a list, unlike the built-in.

flip

flip(func)

flip wraps the callable in func, causing it to receive its non-keyword arguments in reverse order.

If func is not callable, a TypeError exception will be raised.

Example:

>>> def triple(a, b, c):
...     return (a, b, c)
...
>>> triple(5, 6, 7)
(5, 6, 7)
>>>
>>> flipped_triple = flip(triple)
>>> flipped_triple(5, 6, 7)
(7, 6, 5)

foldl

foldl(func, start, iterable)

foldl takes a binary function, a starting value (usually some kind of 'zero'), and an iterable. The function is applied to the starting value and the first element of the list, then the result of that and the second element of the list, then the result of that and the third element of the list, and so on.

This means that a call such as

foldl(f, 0, [1, 2, 3])

is equivalent to

f(f(f(0, 1), 2), 3)

foldl is roughly equivalent to the following recursive function:

def foldl(func, start, seq):
    if len(seq) == 0:
        return start

    return foldl(func, func(start, seq[0]), seq[1:])

Speaking of equivalence, the above foldl call can be expressed in terms of the built-in reduce like so:

reduce(f, [1, 2, 3], 0)

foldr

foldr(func, start, iterable)

foldr is much like foldl, except it starts with the last element, rather than the first element like foldl does. This means that a call such as

foldr(f, 0, [1, 2, 3])

is equivalent to

f(1, f(2, f(3, 0)))

The difference can be seen in the following example:

>>> def minus(a, b):
...     return a - b
...
>>> foldl(minus, 0, [1, 2, 3])
-6
>>> foldr(minus, 0, [1, 2, 3])
2    
>>>

foldr is roughly equivalent to the following recursive function:

def foldr(func, start, seq):
    if len(seq) == 0:
        return start

    return func(seq[0], foldr(func, start, seq[1:]))

Note that unlike foldl, foldr cannot be expressed in terms of the built-in reduce function.

id

id(obj)

The identity function. id takes any object and simply returns that object with an updated reference count.

>>> obj = object()
>>> id(obj) is obj
True
>>>

map

map(function, iterable)

Apply function to every element of iterable, returning a list of the results. map() is fully equivalent to

[function(x) for x in iterable]

Basically, functional.map() works in much the same way as Python's map() built-in, except functional's version...

  • ...takes only a single iterable.

  • ...doesn't support the None nonsense that the built-in does.

partial

partial(func, *args, **kwargs)

Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments kwargs. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override kwargs. Roughly equivalent to:

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

The partial is used for partial function application which "freezes" some portion of a function's arguments and/or keywords resulting in a new object with a simplified signature. For example, partial can be used to create a callable that behaves like the int() function where the base argument defaults to two:

>>> basetwo = partial(int, base=2)
>>>
>>> basetwo('10010')
18
>>>

The section on partial taken from http://docs.python.org/dev/lib/module-functional.html.

scanl

scanl(func, start, iterable)

Like foldl, but produces a list of successively reduced values, starting from the left.

scanl(f, 0, [1, 2, 3])

is equivalent to

[0, f(0, 1), f(f(0, 1), 2), f(f(f(0, 1), 2), 3)]

scanl returns a iterator over the result list. This is done so that the list may be calculated lazily.

The first argument to scanl must be callable or a TypeError will be raised. Likewise, a TypeError will be raised if the iterable argument is not capable of iteration.

scanr

scanr(func, start, iterable)

Like foldr, but produces a list of successively reduced values, starting from the right.

scanr(f, 0, [1, 2, 3])

is equivalent to

[f(1, f(2, f(3, 0))), f(2, f(3, 0)), f(3, 0), 0]

scanr returns a iterator over the result list. This is done so that the list may be calculated lazily.

The first argument to scanr must be callable or a TypeError will be raised. Likewise, a TypeError will be raised if the iterable argument is not capable of iteration.

functional