Closed posxposy closed 5 years ago
What you might want here instead is similar to Java abstract methods, that forces children classes to implement certain methods defined in their superclass.
@ncannasse
What you might want here instead is similar to Java abstract methods, that forces children classes to implement certain methods defined in their superclass.
Well, that's a half of problem :) To be fair, I picked up default implementations from Java too. Both things are useful and flexible. Maybe it is possible to support both features? Abstract methods in classes and default implementations in interfaces. That may improve Haxe as a language and made it more rich as for me, and reduce unnecessary boilerplate code in some situations.
I just wanted to add that this is already possible using macros, e.g. with tink_lang
partial implementations (though implementing this manually in macros is pretty easy also).
But I think proper traits (which is essentially what this is, given that your default
allows both variable and method fields) might be interesting to have without having to go into macroland.
I don't want code in interfaces.
I would be open to abstract methods Java-style though, though I didn't really think the implications through yet.
I agree with @simn. Interfaces should stay interfaces. And the proposed feature is better to be designed and implemented as "classic" abstract classes, which I'd like to see in Haxe type system some day.
@Simn
I would be open to abstract methods Java-style though
Well, this idea actually comes from Java too:
// A simple program to Test Interface default
// methods in java
interface TestInterface
{
// abstract method
public void square(int a);
// default method
default void show()
{
System.out.println("Default Method Executed");
}
}
Example from here: https://www.geeksforgeeks.org/default-methods-java/
But, would be nice to see "classic" abstract classes (as @RealyUniqueName says) in Haxe instead of "default" things in interfaces. Why not :)
I think static functions/variables would be convenient in enums and interfaces, otherwise you have to make pairs of classes, which can be annoying .
Just chiming in to say, I like interface default implementations, they're very handy. I have built a macro implementation, and it's a little slow and a little hairy - so in that respect, it'd be nice if it was a built-in feature.
In my implementation, I've (ab)used metadata, which happens to keep the implementation separated (in the metadata) out of the pure interface definition:
package;
@:autoBuild(util.DefaultImplementations.apply_defaults({
some_var:"hello world",
get_is_bar:
{
return some_var == "bar";
},
set_is_bar:
{
// Note: variable name 'input_value' is defined in the interface below
if (input_value) some_var = "bar";
return input_value;
}
}))
interface IFoo
{
public var some_var:String;
public var is_bar(get,set):Bool;
public function get_is_bar():Bool;
public function set_is_bar(input_value:Bool):Bool;
}
The most hairy part is that, while it's building fields for the given class, it doesn't know which interface triggered the macro. So it scans all the interfaces of the class (and parent classes) to find the one matching the fields provided in the metadata. It needs the interface, because while the metadata provides the Expr
, the interface provides the Field
definition.
I say abused metadata, because technically I don't think metadata supports generic expressions per the manual... but it does work in both Haxe 3 and 4. Although vshaxe isn't always happy about it -- some if-defs have been necessary.
One downside of separating the interface definition from the implementation is that the method parameter names, e.g. input_value
, is in the interface, and must be used in the implementation.
ETA: Oh, and it's sometimes handy to @:final
a default method to disallow classes from providing an implementation:
some_method: @:final {
...
}
I don't think metadata supports generic expressions per the manual...
I think that's perfectly valid:
arguments to compile-time metadata can be any valid expression.
This has been rejected by nay votes of @ncannasse, @nadako, @RealyUniqueName and @Simn.
Rendered version