Interface Limitations in D
Elmar
chrehme at gmx.de
Mon Sep 20 13:24:50 UTC 2021
On Monday, 20 September 2021 at 08:32:46 UTC, Alexandru Ermicioi
wrote:
> On Sunday, 19 September 2021 at 20:00:11 UTC, Elmar wrote:
>> * **`interface`s do not permit overriding defaults**
>>
>> D's interfaces don't allow default implementations of static
>> and non-static functions unlike Java. This makes class
>> implementations more verbose and promotes code duplication
>> because you need to repeat the default implementation in every
>> implementing class, even if you don't care.
>>
>> ...
>>
>> Abstract classes are no replacement because, first, you
>> cannot inherit multiple abstract classes and, second, abstract
>> classes implement partial incomplete behaviour while
>> interfaces don't implement behaviour.
>
> You can use mixin template that will contain default
> implementation of an interface.
>
> You can also declare final functions in interfaces, which can
> partially serve for first case mentioned.
>
> Best regards,
> Alexandru
Thanks, Alexandru. Final functions won't do it however, if you'd
like to override the given implementation in classes.
---
I want to add: after writing the post I found phobos-functions
`autoImplement`, `blackHole` and `whiteHole` in `std.typecons`
which automatically implement interface methods in some way.
Providing default implementation support seems not more difficult:
```D
mixin Interface!("MyInterface",
q{
static immutable PI = 3.141592f;
default static immutable CONSTANT = 0.0f;
float toImplement(string s);
default float isDefaulted()
{
return (CONSTANT ^^ PI) % toImplement(r"tau"));
}
});
```
Providing default method implementations without code duplication
and too much verbosity could work by defining the default method
implementations as **compile-time token strings**. The above
would generate
```D
interface MyInterface
{
final static immutable PI()
{
return 3.141592f;
}
static immutable CONSTANT();
enum DEFAULT_CONSTANT = q{{
return 0.0f;
}};
float toImplement(string s);
float isDefaulted();
enum DEFAULT_isDefaulted =
q{{
return (CONSTANT ^^ PI) % toImplement(r"tau"));
}};
}
```
Then people can either `mixin (DEFAULT_foo)` explicitly (in the
class implementation) or use something like `mixin
DefaultImplement!MyInterface;` to automatically implement missing
DEFAULT_... token strings.
The solution is artificial but a limited simplistic
implementation could use (compile-time) regex for this.
RegEx:
I don't know, whether D's engine would support matching balanced
braces but my feeling assumes no. And the documentation
description confirms myself. Simplicity over expressivity makes
it harder to do the job with Regex and which might be
disappointing for programmers from the scripting realm. I'd find
a PCRE engine more practical. Worst-Case Performance does not
matter if you know how to avoid the worst-case.
More information about the Digitalmars-d
mailing list