On Sat, Feb 8, 2020 at 4:01 AM Soni L. email@example.com wrote:
Traits are an alternative to Multiple Inheritance. They solve the problem of name conflicts by making them an ambiguity error and requiring you to disambiguate (at call site).
Okay, that sounds like a good summary. I'm not sure how useful this truly will be, given that name conflicts in multiple inheritance usually mean you're overusing MI, but sure. Let's see how far we can go with current syntax.
@do_we_need_a_class_deco_too class Trait: @trait def x(self): ... @trait def y(self): ...
@ditto class Another: @trait def x(self): ... @trait def y(self): ...
class Bar: def y(self): print("hello") @Trait.x def x(self): self.y() # resolves to Bar.y @Another.x: def x(self): raise ValueError
All the real work would be done in the @trait decorator. (There might need to be a decorator on the class too, or maybe it subclasses something.) Trait.x would then also be a decorator, and the function it decorates gets stashed into a hidden attribute such as "__traits" (meaning that they're actually "_Trait__traits" and "_Another__traits" and don't conflict), and it would return a stub that raises an error if there's a conflict. When you call Trait(obj), it would return a proxy object (think like super()) that knows which set of traits to look up; most of the magic would be done by the __traits name mangling, so it'd be pretty easy.
You wouldn't be able to have magic in the function header to do this automatically, though. How essential is that to the proposal?