public goose class A:C{ public int a;}public goose class B:A{ public int b;}public goose class C:B{ public int c;}public static void main(){ local A foo = new A; print foo.a foo.b foo.c;}
Coworker today asked how the mix-in implementation handles cycles. This will compile nicely and print 000. So umm, yeah. It handles cycles, and is by most moral standards one of the more evil things I've done in recent memory.
In a mildly less evil Tangent example, I worked quickly this evening on name collisions involving methods. Just the simple case where the methods are unrelated and should thus merely overload.
public class bar{ public int x = 4; public int plusX(int y){ return(y+x); }}public class foo:bar{ public string plusX(string y){ return(y+x.ToString()); }}public static void main(){ local foo instance = new foo; print instance.plusX(2) " " instance.plusX("cow");}
And prints 6 cow4. A little more work than I expected due to some of the binding rules regarding member access. Works now though.
Next will probably be proper virtual methods.
[edit~! (5 hours and many TF2 kills later)]
I added in support for comparing the half-built types so that one or another may be preferred during a name collision. It's mostly not there still though. There's nothing to compare half-built types and built in types (or included from a library once that exists). I also currently punt if the types being compared have any name collisions themselves.
So basically, it currently only works for the ideal conditions. Baby steps.
Example code:
public goose class A{ public virtual string whoami = "A"; }public goose class B:A{ public virtual string whoami = "B"; }public class foo{ public virtual A x = new A;}public class bar:foo{ public B x = new B;}public static void main(){ print (new bar).x.whoami;}
Which will nicely print you B. If a name collision has compatible types (and the initializers + abstract/virtual work out sanely), then the most specific type is used.
Either way that puts you at neutral or good depending on how that evaluates.