A package with lisp-like generic functions for python 3.
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) <class 'function'>
Lets define add for two integers:
>>> @method() ... def add(n0: int, n1: int): ... 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() ... def add(s0: str, s1: str): ... 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() ... def add(s: str, n: int): ... 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() def __add__(a: object, b: Rational): """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: Rational, b: object): """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() def __out__(rational: Rational, writer: 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() def __spy__(rational: Rational, writer: 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(")")
Installation
As usual gf3 can be installed with pip, like this:
pip install gf3
Documentation
The whole documentation is available at in the following formats
- HTML
- http://gf3.klix.ch (Also servers as gf’s homepage)
- http://gf3.klix.ch/gf3.pdf
Changes
A short sketch of the changes done in each release.
Release 0.2.4
The following was changed in Release 0.2.4:
- The push-method accepts an identation string for identing writers.
- The methods push and pop now accept arbitrary arguments in the general case.
- Successfully tested the whole framework with Python 3.5.
Release 0.2.3
The following was changed in Release 0.2.3:
- Fixed the long description.
- Wrote some documentation about changing the implementation class of a generic function.
Release 0.2.2
The following was changed in Release 0.2.2:
- Write more documentation. Especially documented the merge and the isgeneric functions.
- Consistency between the long text and on PyPi and the documentation.
Release 0.2.1
Needed to bump the version information, because the homepage in the package-information was wrong [1] and a new upload was needed.
Release 0.2.0
The following was changed in Release 0.2.0:
- Ported the whole module to Python 3.6 and Python 3.7.
- Exclusively uses parameter annotations to specify the types to dispatch on.
- Added standard conforming default implementations for methods like __add__. All these methods now raise a proper TypeError instead of raising a NotImplementedError.
- Added some means to write generic functions that dispatch types only. This is the generic function equivalent of a class-method.
- Added some means to dispatch on single objects. This is the equivalent adding methods to class-instances [2].
- The package name for PyPi is now gf3.
Release 0.1.4
The following was fixed in Release 0.1.4:
- Fixed an issue with variadic methods. Sometimes definitions of variadic methods added after the method was already called where not added.
- Specified and implemented a precedence rule for overlapping variadic methods of generic functions.
- Improved generated documentation for variadic methods.
- Fixed the markup of some notes in the documentation.
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.
Acknowledgements
Guido van Rossum created the core of this package. I just renamed some things and added some^H^H^H^H oodles of convenience stuff. Thank you Guido!
Copyright
© 2006-2013 Python Software Foundation. © 2013-2018 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.