A package with lisp-like generic functions.
Project description
Overview
gf lets you write generic functions generic functions with multi-methods, that dispatch on all their arguments.
Simple Example
>>> from gf import generic, method >>> add = generic() >>> type(add) <type 'function'>
Lets define add for two integers:
>>> @method(int, int) ... def add(n0, n1): ... return n0 + n1
Lets test it:
>>> add(1, 2) 3
Calling add with instances of other types fails:
>>> add("Hello ", "World") Traceback (most recent call last): ... NotImplementedError: Generic '__main__.add' has no implementation for type(s): __builtin__.str, __builtin__.str
Of course add can also by defined for two strings:
>>> @method(basestring, basestring) ... def add(s0, s1): ... return s0 + s1
Now our hello world example works:
>>> add("Hello ", "World") 'Hello World'
add can also be defined for a string and an integer:
>>> @method(basestring, int) ... def add(s, n): ... return s + str(n)
Thus we can add a string and a number:
>>> add("You ", 2) 'You 2'
Python’s Special Methods
gf.Object implements (nearly) all of the special instance methods of a python object as a generic function. The package includes a rational number implementation that makes heavy use of this feature:
@method(object, Rational)
def __add__(a, b):
"""Add an object and a rational number.
`a` is converted to a `Rational` and then both are added."""
return Rational(a) + b
@method(Rational, object)
def __add__(a, b):
"""Add a rational number and an object.
`b` is converted to a `Rational` and then both are added."""
return a + Rational(b)
gf.Object also has a more Smalltalk means of overwriting object.__str__ and object.__repr__ using a file like object. Again the rational example is instructive about its usage.
@method(Rational, Writer)
def __out__(rational, writer):
"""Write a nice representation of the rational.
Denominators that equal 1 are not printed."""
writer("%d", rational.numerator)
if rational.denominator != 1:
writer(" / %d", rational.denominator)
@method(Rational, Writer)
def __spy__(rational, writer):
"""Write a debug representation of the rational."""
writer("%s(", rational.__class__.__name__)
if rational.numerator != 0:
writer("%r", rational.numerator)
if rational.denominator != 1:
writer(", %r", rational.denominator)
writer(")")
Changes
A short sketch of the changes done in each release.
Release 0.1.3
The following was changed in Release 0.1.3:
Added variadic methods, e.g. multi-methods with a variable number of arguments.
Improved the long description text a bit and fixed bug in its markup.
Fixed invalid references in the long description.
Release 0.1.2
The following was changed in Release 0.1.2:
Added a generic functions for gf.Object.__call__.
Added a gf.go.FinalizingMixin.
gf.generic now also accepts a type.
Improved the exception information for ambiguous calls.
Fixed some documentation glitches.
Release 0.1.1
This was the initial release.
Acknowledgements
Guido van Rossum created the core of this package. I just renamed some things and added some convenience stuff. Thank you Guido!
Copyright
© 2006 Python Software Foundation. © 2006-2013 Gerald Klix.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.