std.typecons wrap interface with NVI
TheFlyingFiddle
theflyingfiddle at gmail.com
Sat Feb 1 22:36:27 PST 2014
On Sunday, 2 February 2014 at 01:19:22 UTC, Matthew Dudley wrote:
> This is the general outline of what I'm trying to do:
>
>
>
> import std.typecons; //wrap
>
> import std.stdio;
>
>
> interface FooBar
> {
> public:
> void foo();
> void bar();
>
> final void both() // NVI
> {
> foo();
> bar();
> }
> }
>
> class Baz
> {
> public:
> void foo() { writeln("foo"); }
> void bar() { writeln("bar"); }
> }
>
> void main()
> {
> auto baz = new Baz();
> auto foobar = baz.wrap!(FooBar)();
> // causes this wall-o-text error --
> http://pastebin.com/Pa5dHQtN
> // Which at the end says:
>
> // /usr/local/Cellar/dmd/2.064.2/import/std/typecons.d(2779):
> Error: static assert "Source Baz does not have structural
> conformance to (FooBar)"
>
> }
>
>
> I'm still learning D, but this seems like it should work. If I
> explicitly implement FooBar in Baz, everything's groovy, but
> this isn't. Is this a bug in wrap or am I misunderstanding the
> intention of wrap or NVI?
You are getting the point of NVI i think, that part is correct. I
don't know why NVI dosn't work together with wrapping but i would
assume it is a bug. Conseptually NVI does not change the behavior
of the wrapped object so it shouldn't be a problem. (Abstract
classes are a problem here though see below).
As far as wrap goes i am not sure what the intention behind it
is. It would be a cool feature if it allowed wrapping of structs
but... it dosn't. It could have some use in avoiding the need of
writing adapter classes for code you can't change but other then
that it should imho be avoided. Templates and interface
inheritance in general makes the feature unessasary.
> Also as a side note, if I use an abstract class instead of an
> interface, things explode in similarly large wall-o-text
> fashion. Is there a reason for abstract classes aren't or can't
> be used for wrap?
class FooBar
{
abstract void foo();
void bar() { writeln("Hello from FooBar.bar"); }
}
class Baz
{
void foo() { writeln("Hello from Baz.foo"); }
voir bar() { writeln("Hello from Baz.bar"); }
}
void main()
{
auto baz = new Baz();
baz.bar();
auto wrapped = baz.wrap!(FooBar);
wrapped.bar(); //Which bar should be called?
}
Wrapping a type into an interface should not change the behaviour
of the wrapped types operations. In the example above what would
the wrapped.bar() call do? Would it call bar in FooBar? or bar in
Baz? maby both? There is no clear defined rule of what to do
here. I'm guessing this is why they decided to not support
implementation wrapping. (Note it could have been defined but
it's not.) Also wrapping does try to simulate how Go does duck
typing and there is no inheritance there so i'm guessing that was
a factor in the design.
More information about the Digitalmars-d-learn
mailing list