-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default implementations in interfaces #70
Default implementations in interfaces #70
Conversation
Two questions:
interface XY {
var x:Int;
var y:Int;
function set(x:Int, y:Int):Void {
this.x = x;
this.y = y;
}
}
class Util {
public static function set(scope:XY, x:Int, y:Int):Void {
// this?
IPoint.set(scope, x, y);
// or this?
IPoint.set(x, y, scope);
}
}
|
I don’t think this will work. I recommand the abstract class proposal, for a few reasons:
|
The first argument should be (this), like abstract (https://try.haxe.org/#dbEde). So
I think calling interface methods with interface N {
public function sample():Void {
trace("N");
}
}
class M {
public function sample():Void {
trace("M");
}
}
class O implements N extends M {
public override function sample():Void {
// `super.method()` should be only for class method.
super.sample(); // M
}
} |
In other hand, abstract class may not have implementation for all methods, and we will not able to use
It is actually possible. The Conflict section is the solution. |
This seems like an anti-feature to me... I don't want implementation details in my interfaces. I also don't want multiple inheritance (at least not as a default/first-class behavior). I'd really like interfaces to be simple "contracts". If we need multiple inheritance in a library, I'd like it to use some other keyword/pattern so that the behavior there is clearly specified. Multiple inheritance code requires you to better understand the field resolution patterns at work for the resulting class. I don't want to worry about all this every time I see the "implements" keyword. |
I'm with Justin on this and share the same concerns. |
My proposal seems too short to respond to the concerns. I'll make some additions to this proposal. |
I don't like this feature and I think interfaces should be pure contracts. I can agree with one valid use-case for this: backward compatibility and I know C# recently added such feature exactly for this case, but they made it very explicit and awkward to use as a general "mixin /multiple-inheritance" feature to discourage people from abusing it. And I don't think Haxe needs this at the moment as we haven't reached .NET level of ecosystem complexity yet :) So for now, "there's a macro for that". (c) One part that I think is somewhat useful is real |
I added detail. An important point is |
As I remember, this feature was already rejected by the team: |
We have decided to reject this proposal in our haxe-evolution meeting yesterday. The reasons were already stated: We don't like having code in interfaces because it mixes concepts. While there might be some merit to this in the Java world, it is not a good fit for Haxe. |
Interesting -- I have no comment on the implementation as proposed, but I do love my tl,dr: I like def impl, it has its place, but it's workable as a macro (vs getting everyone to agree on one implementation.) As for "the interface should be separate from the implementation / pure contract" -- that's one use case of interfaces. I'd suggest "the interface implies (some set of) the implementation" is a distinct and equally valid use case, that's more DRY. Whatever you call it -- decorator / mix-in / default implementation -- it's deciding that some features don't fit neatly into a class hierarchy. And interface defaults is DRY while retaining Haxe's type-safe features. e.g. I have an My events / pubsub classes, my controller classes, my display classes -- all implement It's really quite tidy. But, it works fine as a macro, and naturally, I'm partial to the way I did it. 😉 😛 |
why not implement partial interfaces, but require explicit definition @:partial
interface Example {
public function doSomething():Void {
trace("does something");
}
} |
Thinking about this after learning haskell and rust, this turns interfaces into traits, which I think would be a very good thing. Traits in general imho are a better model for inheritance as it allows multi inheritance. |
why not add traits? yes, I know this is a huge feature, but that seems like the only hope for a feature like this getting in |
An alternative to abstract class(#69).
Rendered version