[Python-Dev] PEP 443 - Single-dispatch generic functions
steve at pearwood.info
Fri May 24 12:53:54 CEST 2013
On 24/05/13 15:09, Nick Coghlan wrote:
> On Fri, May 24, 2013 at 8:40 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>> I don't think that they will. Being able to register multiple types with a
>> single call reads very naturally to me, while multiple decorators still
>> looks weird. Even after many years of seeing them, I still get a momentary
>> "What the hell...?" moment when I see two decorators on one function. That's
>> only going to be increased when both decorators are the same (apart from the
>> argument). The double decorator form above looks to me as weird as:
>> x = func(a)
>> x = func(b)
>> would. I have to stop and think about what is going on, and whether or not
>> it is a mistake.
> The difference is that this idiom quickly becomes familiar and unexceptional:
> def fun_floating_point(arg1, arg2):
I initially wrote a reply about the nature of ambiguity, why register(float, Decimal) should not be considered ambiguous, why stacked decorators that are near-duplicates are a code smell, blah blah blah. But for the sake of brevity I'm going to skip it. The important point that you make is here:
> Is that multiple dispatch? Or is it registering for single dispatch on
> multiple different types?
> Sure, we could pick the latter meaning for the standard library, but
> existing generic function implementations (cited in the PEP) use the
> tuple-of-types notation for multiple dispatch.
This is an excellent point I had not considered.
By the way, it seems to me that Guido's multimethod implementation referenced in the PEP actually uses a single decorator argument per function argument, not a tuple-of-types:
def foo(a, b):
...code for two ints...
You have convinced me: ambiguous or not, for the sake of future expansion I agree that multiple positional arguments to the register method should be left for some hypothetical multiple-dispatch generics:
@fun.register(float, Decimal) # not yet supported, but maybe someday
would mean "first argument is a float, second argument is a Decimal".
But that still leaves open how to specify single dispatch on more than one type:
> stacking registration decorators is
> just a new idiom to become accustomed to.
Python built-ins and the standard library already have a standard idiom for specifying multiple values at once. A tuple of types is the One Obvious Way to do this:
which matches the same standard idiom that should be familiar to most people:
isinstance(obj, (float, Decimal))
issubclass(cls, (float, Decimal))
And of course it is forward-compatible with our hypothetical future multiple-generics.
More information about the Python-Dev