[Python-Dev] Call for defense of @decorators
Phillip J. Eby
pje at telecommunity.com
Sat Aug 7 01:58:46 CEST 2004
At 01:38 AM 8/7/04 +0200, Christian Tismer wrote:
>Ronald Oussoren wrote:
>
>>Whoops, I used the wrong word, I meant 'generic functions' instead of
>>'generic example'. He's doing something like this:
>>@when("isinstance(db, OracleDB")
>>def storeInDB(db, object):
>> pass
>>@when("isinstance(db, BerkelyDB")
>>def storeInDB(db, object):
>> pass
>
>Why is this needed? Can't we continue to use
>
>if isinstance(db, OracleDB):
> def storeInDB(db, object):
> pass
>
>if isinstance(db, BerkelyDB):
> def storeInDB(db, object):
> pass
No... the equivalent code generated is more like:
def storeInDB(db,object):
if isinstance(db,OracleDB):
...
elif isinstance(db,BerkleyDB):
...
with these important differences:
* The behavior can be defined modularly, with different modules
contributing possible execution paths, rather than requiring the function
body to be defined in a single place. This makes functions "open" to
extension, by adding more cases. For example, one might define a generic
function to visit various document node types, and then developers who add
new node types can write additional cases for the existing visitor function.
* The dispatch algorithm supports multiple dispatch on arbitrary
conditions on any parameters, even though the example Ronald gave only does
single-dispatch on one parameter. 'and', 'or', and 'not' can be used to
construct complex predicates.
* An arbitrary number of tests may be applied to arbitrary expressions
involving the parameters, but for each invocation of the function, each
expression will be computed at most once and each test will be performed at
most once, no matter how many 'when()' invocations comprise the total
generic function body. Conditions which are "less discriminating" will be
tested after conditions that are "more discriminating", in order to avoid
computing expressions that may not have any effect on what implementation
is finally selected.
* The hierarchy of 'if' tests is automatically generated, based on
logical implication relationships between the predicates, overlapping of
ranges, etc. This removes a lot of tedious reasoning and coding that a
human programmer would otherwise have to do to ensure a correct decision
tree when the input is just a bunch of "business rules".
The net effect is to have generic functions in Python, similar to those of
Lisp or Dylan, but with the addition of arbitrary predicate evaluation, as
in the research language Cecil. If you're curious about the basic concept
and algorithm, see:
http://citeseer.ist.psu.edu/chambers99efficient.html
and the current Python implementation can be found in the CVS trunk version
(1.0a0) of PyProtocols. It does not yet support constrained evaluation
order, but it does extend the Chambers and Chen algorithm to support
efficient range and equality comparisons (e.g. for numbers and strings),
and has other extensions to support dispatching on class and interface
using Python's particular MRO rules, which are a bit different from those
of Dylan, Lisp, and Cecil.
More information about the Python-Dev
mailing list