On 7/29/07, Talin <[EMAIL PROTECTED]> wrote: > Phillip J. Eby wrote: > > At 08:25 AM 7/27/2007 -0700, Guido van Rossum wrote: > >> Basic GFs, great. Before/after/around, good. Other method > >> combinations, fine. But GFs in classes and subclassing? Not until we > >> have a much better design. > > > > Sounds reasonable to me. The only time I actually use them in > > classes myself is to override existing generic functions that live > > outside the class, like ones from an Interface or a standalone generic. > > I've been thinking about this quite a bit over the last week, and in > particular thinking about the kinds of use cases that I would want to > use GFs for. > > One idea that I had a while back, but rejected as simply too much of a > kludge, was to say that for GFs that are also methods, we would use > regular Python method dispatching on the first argument, followed by GF > overload dispatching on the subsequent arguments. > > The reason that this is a kludge is that now the first argument behaves > differently than the others. > > (Pay no attention to the specific syntax here.) > > class A: > @overload > def method(self, x:object): > ... > > class B(A): > @overload > def method(self, x:int): > ... > > b = B() > b.method("test") // Method not found > > With regular GFs, this example works because there is a method that > satisfies the constraints - the one in A. But since the first argument > dominates all of the decision, by the time we get to B, the overloads in > A are no longer accessible. Its as if each subclass is in it's own > little GF world. > > However, even though this is clumsy from a theoretical standpoint, from > a practical standpoint it may not be all that bad. Most of the time, > when I want to declare a GF that is also a method, I'm just using the > class as a namespace to hold all this stuff, and I really don't care > much about whether subclasses can extend it or not. I'm not using the > type of 'self' to select different implementations in this case.
FWIW, this dispatching on self before overloading on the rest of the arguments is what C++ does, and I think also what Java does. To get the parent class's methods to participate in overloading, you have to say using the_parent::method; which looks pretty similar to Phillip's method = the_parent.method except that using can appear anywhere within a class, while the method assignment looks like it needs to appear first. Unfortunately, this seems to surprise people, although I don't have any experience about whether an alternative would be better or worse. A lot of times, I write: class Parent { virtual int method(int i, string s) = 0; int method(Bar b) { return method(b.i, b.s); } int method(Quux q, Foo f) { return method(q.i, q.t + f.x); } // Note that the non-virtual methods forward to the virtual one. // Although the visibility would be the same if they were virtual too. }; class Child : public Parent { virtual int method(int i, string s) { return do_something(i, s); } }; and am then surprised that Child c; c.method(Bar(...)); fails to compile. (Because I forgot the using declaration in Child. Again.) So the possibility is practically clumsy, but there's a precedent for it. -- Namasté, Jeffrey Yasskin _______________________________________________ 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