Oops. They're now nicely immutable little things that return new things when bound with types.
I decided in the past few days that the name collision and inheritance cleanup needs three parts. Part one will be converting the mix-in operator from working on well-defined types to the half-defined types during compilation. Part two will be converting type comparison to the half-defined types available at compilation. Part three will be auto-generating new types for inherited member-methods.
That will allow (respectively):
- name collisions to be resolvable for cases where the types are identical. Abstract and virtual and initializer resolution should work.
- name collisions to be resolvable (or less punt-able at least) where the types are not identical. There's likely to be some cases where it's indeterminable. This is going to be the hardest part.
- methods -> method groups, virtual dispatch, snazzy stuff.
I got part one done tonight, which also included a mechanism for block comparison and some cleanup on the built-in types. Example!:
public class bar{ public int x = 4;}public class foo:bar{ public virtual int x = 0; public int x = 4; public abstract int x; }public class a{ public virtual string moo = "a";}public class b:a{ public virtual string moo = "b";}public static void main(){ print (new foo).x " \r\n"; print (new b).moo;}
(the multiple declarations per class is odd, but allowed for now. It simulates inheritance, which mechanically adds members from the inheritees to the bottom of the declaration [and are then consolidated to 1 per name])
This code works fine now, printing:
4b
bar::x is consolidated into foo::x since they have the same initializer. foo::x = 4 beats out its brethren because it's not virtual (or abstract). virtual on fields implies that the initializer may be overriden. The second half of the program shows the picking if both parts of the name collision are virtual; the type doing the inheriting (or to the left of the mix operation) wins.