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.

Reply via email to