[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