|
From: Kevin B. <kb...@ca...> - 2001-08-07 18:13:06
|
john coppola wrote:
> It would be nice if a python class could leverage the
> speed of java, while having the flexibility of Python.
> We should in theory be able to do this using a Mix-In
> approach.
I think the "ghosting" approach is the wrong approach for this.
The example you cited is trivially solved by multiple inheritance, as you pointed out:
...
> import jSpam # true java class
> class Dummy: pass
>
> Class Foo(Dummy,jSpam):
> def __init__(self,name):
> self.name=name
>
> Now, in theory this code should work:
>
> foo=Foo("foo")
>
> This code bombs because inhereting from jSpam has
> interfered with our inheritence from Dummy.
...
So multiple inheritance seems the right way to approach this (it gives you the ghosting feature, all the multiple inheritance/mixins features, and does it in established Python syntax).
Early versions of jpython allowed multiple inheritance of Java classes. Later versions disabled it explicitly, mostly because it wasn't supported in jpythonc. I believe this was a mistake, but I have yet to put my code where my mouth is, so I should probably shut up about it. But here goes anyway. :-)
Ideally, Python code should not care whether a class instance is implemented in Python or in Java (or C...), including when you try to inherit from it.
I haven't investigated the code, but I expect it wouldn't be hard to re-enable.
Here's the FAQ entry that talks about it the history:
http://www.jython.org/cgi-bin/faqw.py?req=show&file=faq03.001.htp
This links to: http://mail.python.org/pipermail/jpython-interest/1998-April/000213.html
and a bad link, that should probably be replaced with:
http://mail.python.org/pipermail/jpython-interest/1999-June/001874.html
http://mail.python.org/pipermail/jpython-interest/1999-January/001162.html
I'd propose that we allow the multiple inheritance behavior, and make jythonc encode that behavior in some rational way based on delegation (multiple inheritance in Python doesn't _have_ to make to inheritance in Java, otherwise we couldn't implement Python on the JVM).
This makes jythonc's job a bit harder - but only for classes that use multiple inheritance.
The basic approach would be to have the derived class implementation inherit from the _first_ base class. Any other "base classes" become a contained member as shown below. This lets single inheritance generate exactly the code it does today, and supports multiple inheritance in a reasonable way.
Issues (and suggestions):
- access to protected methods/data of base classes (not needed, because Jython doesn't support it)
- derived methods delegating to base classes (provide 'super_method' that calls super.method)
- base class methods that call derived methods - template method pattern (derived method delegates to method on combined class)
- methods with the same name in two base classes (delegate to method on combined class)
- methods of X that access both A and B (delegate to method on combined class)
- data members with the same name in two base classes (really painful - maybe leave that as a restriction in jythonc?)
class X( A, B, C ):
def MyCMethod( self ):
# do stuff, then
return C.MyCMethod( self )
becomes:
public class X extends A
{
public X( args )
{
super( a_args );
b = new B_X( this, b_args );
c = new C_X( this, c_args );
}
// overridden methods of A, B, and C
public RETURNVALUE MyCMethod()
{
// do stuff, then
return c.super_MyCMethod();
}
// non-overridden methods of just B and C delegate to b and c
// clients need to access fields of B & C and
// pass to pass B & C references to other code
// these could be protected w/ accessor methods
public B b;
public C c;
// may want to add a 'convenience member'
public A a = this;
}
class B_X extends B
{
protected X x;
B_X( X x, b_args )
{
super( b_args );
this.x = x;
}
// overridden methods of B delegate to x
}
class C_X extends C
{
protected X x;
C_X( X x, c_args )
{
super( c_args );
this.x = x;
}
// overridden methods of C delegate to x
public RETURNTYPE MyCMethod()
{
return x.MyCMethod();
}
// for any methods that are called from X code, generate the following:
public RETURNTYPE super_MyCMethod()
{
return super.MyCMethod( ARGS );
}
}
But again, no code to support the proposal at this point, but I'd appreciate feedback on the idea.
:-) / :-(
kb
|