[Python-3000] PEP 3124 - Overloading, Generic Functions, Interfaces, etc.

Phillip J. Eby pje at telecommunity.com
Fri May 11 01:20:26 CEST 2007


At 09:59 AM 5/11/2007 +1200, Greg Ewing wrote:
>Phillip J. Eby wrote:
>>As I said above (and in the PEP), *all* before and after methods 
>>are always called, unless an exception is raised somewhere along the way.
>
>>   "Before" methods are invoked most-specific method first, with
>>   ambiguous methods being executed in the order they were added.  All
>>   "before" methods are called before any of the function's "primary"
>>   methods (i.e. normal ``@overload`` methods) are executed.
>
>Well, it wasn't clear to me at all from the PEP that
>this is how it works. The above paragraph doesn't say
>anything about @around methods, for example,

That's because @around methods haven't been introduced at that point 
in the PEP; the following section introduces @around and explains 
that @arounds are called before the befores, etc.  For example, part 
of the section describing @around methods says:

   The ``__proceed__`` given to an "around" method will either be the
   next applicable "around" method, a ``DispatchError`` instance,
   or a synthetic method object that will call all the "before" methods,
   followed by the primary method chain, followed by all the "after"
   methods, and return the result from the primary method chain.

Of course, it's also stated in the PEP that it's basically copying 
CLOS's "standard method combination", but I really should add 
appropriate references for that.


>>>For that matter, what if there is simply another
>>>decorator @Foo that is defined to always_override
>>>@Around? The precedence between that and your
>>>@Debug decorator then appears to be undefined.
>>If so, then you'll get an AmbiguousMethods error (either when 
>>defining the function or calling it) and thus be informed that you 
>>need another override declaration.
>
>I can see a problem with this. If Library1 defines a
>method that always overrides an @around method, and
>Library2 does the same thing, then if I try to use
>both libraries at the same time, I'll get an exception
>that I don't know the cause of and don't have any
>idea how to fix.

Actually, that would require that Library1 and Library2 both add 
methods to a generic function in Library3.  Not only that, but *those 
methods would have to apply to the same classes*.  So, it's actually 
a lot harder to create that situation than it sounds.

In particular, notice that if Library1 only uses its combinators for 
methods applying to its own types, and Library2 does the same, they 
*cannot* create any method ambiguity in the third library's generic functions!

Of course, outside of debug hooks, adding custom combinators to 
somebody else's generic function probably isn't a very good idea in 
the first place, at least for instances of *that library's types* or 
of *built-in types* -- which is the only way to produce a conflict 
between two libraries that don't otherwise know about each 
other.  (That is, if L1 and L2 don't know each other, they can hardly 
be registering methods for each other's types with a common generic function.)

Meanwhile, in CLOS the set of allowed qualifiers for a generic 
function's methods is decided by the function itself, so there's no 
way for you to add foreign method types at all.  I personally think 
that's a little too restrictive, though, as it not only goes against 
"consenting adults", but it also effectively rules out "true" 
aspect-oriented programming.

By the way, I feel I should mention that although I disagree with a 
lot of your arguments, I *do* appreciate your taking the time to find 
possible edge or corner failure conditions and "unintended 
consequences".  So please don't let my poking of holes in your poking 
of holes in the PEP, stop you from trying to poke more holes in it.  :)



More information about the Python-3000 mailing list