On 5/14/07, Phillip J. Eby <[EMAIL PROTECTED]> wrote: > At 03:43 PM 5/14/2007 -0700, Guido van Rossum wrote: > > > Chaining using the first argument can be implemented using a bound > > > method object, which gets performance bonuses from the C eval loop > > > that partial() objects don't. (Of course, when RuleDispatch was > > > written, partial() objects didn't exist, anyway.) > > > >Sounds like premature optimization to me. We can find a way to do it > >fast later; let's first make it right. > > As I said, when RuleDispatch was written, partial() didn't exist; it > was less a matter of performance there than convenience. > > > >True. So are you working with Tim Delaney on this? Otherwise he may > >propose a simpler mechanism that won't allow this re-use of the > >mechanism. > > PEP 367 doesn't currently propose a mechanism for the actual > assignment; I was waiting to see what was proposed, to then suggest > as minimal a tweak or generalization as necessary. Also, prior to > now, you hadn't commented on the first-argument-class rule and I > didn't know if you were going to reject it anyway. > > > >super is going to be a keyword with magic properties. Wouldn't it be > >great if instead of > > > >@when(...) > >def flatten(x: Mapping, nm: next_method): > > ... > > nm(x) > > > >we could write > > > >@when(...) > >def flatten(x: Mapping): > > ... > > super.flatten(x) # or super(x) > > > >or some other permutation of super? > > Well, either we'd have to implement it using a hidden parameter, or > give up on the possibility of the same function being added more than > once to the same function (e.g., for both Mapping and some specific > types). There's no way for the code in the body of the overload to > know in what context it was invoked. > > The current mechanism works by creating bound methods for each > registration of the same function object, in each "applicability chain". > > That doesn't mean it's impossible, just that I haven't given the > mechanism any thought, and at first glance it looks really hairy to > implement -- even if it were done using a hidden parameter. > > > >Or do you see the need to call > >both next-method and super from the same code? > > Hm, that's a mind-bender. I can't think of a sensible use case for > that, though. If you're a plain method, you'd just use super. If > you're a generic function or overloaded method, you'd just call the > next method. > > The only way I can see you doing that is if you needed to call the > super of some *other* method, which doesn't make a lot of sense. In > any case, we could probably use super(...) for next-method and > super.methodname() for everything else, so I wouldn't worry about > it. (Which means you'd have to use super.__call__() inside of a > __call__ method, but I think that's OK.) > > > >Do note that e.g. in IronPython (and maybe also in Jython?) > >exec/eval/compile are 10-50x slower (relative to the rest of the > >system) than in CPython. > > This would only get done by @overloadable, and never again thereafter. > > > >It does look like a clever approach though. > > Does that mean you dislike it? ;-) > > > > > Hm. I'll need to give some thought to that, but it seems to me that > > > it's sort of like having None defaults for the missing arguments, and > > > then treating the missing-argument versions as requiring type(None) > > > for those arguments. Except that we'd need something besides None, > > > and that the overloads would need wrappers that drop the extra > > > arguments. It certainly seems possible, anyway. > > > > > > I'm not sure I like it, though. > > > >C++ and Java users use it all the time though. > > Right, but they don't have keyword arguments or defaults, > either. The part I'm not sure about has to do with interaction with > Python-specific things like those. When do you use each one? One > Obvious Way seems to favor default arguments, especially since you > can always use defaults of None and implement overloads for > type(None) to catch the default cases. i.e., ISTM that cases like > range() are more an exception than the rule. > > > > > It's not obvious from the first > > > function's signature that you can call it with fewer arguments, or > > > what that would mean. For example, shouldn't the later signatures be > > > "range(stop)" and "range(start,stop)"? Hm. > > > >I don't know if the arg names for overloadings must match those of the > >default function or not -- is that specified by your PEP? > > It isn't currently, but that's because it's assumed that all the > methods have the same signature. If we were going to allow > subset-signatures (i.e, allow you to define methods whose signature > omits portions of the main function's signature), ISTM that the > argument names should have meaning. > > Of course, maybe a motivating example other than "range()" would help > here, since not too many other functions have optional positional > arguments in the middle of the argument list. :) > > > >My own trivially simple overloading code (sandbox/overload, and now > >also added as an experiment to sandbox/abc, with slightly different > >terminology and using issubclass exclusively, as you recommended over > >a year ago :-) has no problem with this. Of course it only handles > >positional arguments and completely ignores argument names except as > >keys into the annotations dict. > > Yeah, none of my GF implementations care about the target methods' > signatures except for the next_method thingy. But with variable > argument lists, I think we *should* care. > > Also, AFAIK, the languages that allow different-sized argument lists > for the same function either don't have first class functions (e.g. > Java) or else have special syntax to allow you to refer to the > different variations, e.g. "x/1" and "x/2" to refer to the 1 and 2 > argument versions of function x. That is, they really *are* > different objects. (And Java and C++ of course have less > comprehensible forms of name mangling internally.) > > Personally, though, I think that kind of overloading is a poor > substitute for the parameter flexibility we already have in > Python. That is, I think those other languages should be envying > Python here, rather than the other way around. :)
Perhaps. Though C++ *does* have argument default values. Other use cases that come to mind are e.g. APIs that you can pass either a Point object or two (or three!) floats. This is not a natural use case for argument default values, and it's not always convenient to require the user to pass a tuple of floats (perhaps the three-floats API already existed and its signature cannot be changed for compatibility reasons). Or think of a networking function that takes either a "host:port" string or a host and port pair; thinking of this as having a default port is also slightly awkward, as you don't know what to do when passed a "host:port" string and a port. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com