A package with lisp-like generic functions for python 3.
Project description
=============================================
GF3: Lisp-Like Generic Functions For Python 3
=============================================
Overview
========
`gf` lets you write generic functions
`generic functions <http://en.wikipedia.org/wiki/Generic_function>`_
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:
.. code:: python
@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.
.. code:: python
@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(")")
.. _special instance methods of a python object:
http://docs.python.org/2/reference/datamodel.html#special-method-names
Installation
------------
As usual :mod:`gf3` can be installed with `pip`, like this:
.. code-block:: shell
pip install gf3
Documentation
-------------
The whole documentation is available at in the following formats
HTML
http://gf3.klix.ch (Also servers as :mod:`gf`'s homepage)
PDF
http://gf3.klix.ch/gf3.pdf
Changes
-------
A short sketch of the changes done in each release.
Release 0.2.2
~~~~~~~~~~~~~
The following was change 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 [#]_ and a new upload was needed.
Release 0.2.0
~~~~~~~~~~~~~
The following was change 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 [#]_.
* The package name for PyPi is now ``gf3``.
.. _parameter annotations: https://docs.python.org/3/reference/compound_stmts.html#grammar-token-parameter
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.
Release 0.1.1
~~~~~~~~~~~~~
This was the initial release.
.. [#] Silly me discovered about the shutdown of pythonhosted.org
after version 0.2.0 was uploaded.
.. [#] Of course this is not possible with standard python classes
and their instances.
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.
GF3: Lisp-Like Generic Functions For Python 3
=============================================
Overview
========
`gf` lets you write generic functions
`generic functions <http://en.wikipedia.org/wiki/Generic_function>`_
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:
.. code:: python
@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.
.. code:: python
@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(")")
.. _special instance methods of a python object:
http://docs.python.org/2/reference/datamodel.html#special-method-names
Installation
------------
As usual :mod:`gf3` can be installed with `pip`, like this:
.. code-block:: shell
pip install gf3
Documentation
-------------
The whole documentation is available at in the following formats
HTML
http://gf3.klix.ch (Also servers as :mod:`gf`'s homepage)
http://gf3.klix.ch/gf3.pdf
Changes
-------
A short sketch of the changes done in each release.
Release 0.2.2
~~~~~~~~~~~~~
The following was change 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 [#]_ and a new upload was needed.
Release 0.2.0
~~~~~~~~~~~~~
The following was change 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 [#]_.
* The package name for PyPi is now ``gf3``.
.. _parameter annotations: https://docs.python.org/3/reference/compound_stmts.html#grammar-token-parameter
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.
Release 0.1.1
~~~~~~~~~~~~~
This was the initial release.
.. [#] Silly me discovered about the shutdown of pythonhosted.org
after version 0.2.0 was uploaded.
.. [#] Of course this is not possible with standard python classes
and their instances.
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.
Source Distribution
gf3-0.2.2.tar.gz
(32.3 kB
view hashes)