digitalmars.D.learn - std.typecons wrap interface with NVI
- Matthew Dudley (38/38) Feb 01 2014 This is the general outline of what I'm trying to do:
- TheFlyingFiddle (38/77) Feb 01 2014 You are getting the point of NVI i think, that part is correct. I
- Dicebot (8/8) Feb 02 2014 `wrap` has relatively simple meaning: for any interface I and
- Matthew Dudley (5/13) Feb 02 2014 That's kinda what I suspected was happening.
- Jesse Phillips (5/19) Feb 01 2014 It seems that wrap is expecting your type to implement both(). I
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? 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?
Feb 01 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.
Feb 01 2014
`wrap` has relatively simple meaning: for any interface I and class C it generates class C' inheriting I and implementing all methods of I in terms of forwarding calls to methods of C with same name and signature. What does happen here is that `wrap` was not implemented with NVI in mind and tries to override `both` in C' which, of course, can't work. File an enhancement request for `wrap` to become aware of NVI.
Feb 02 2014
On Sunday, 2 February 2014 at 11:07:41 UTC, Dicebot wrote:`wrap` has relatively simple meaning: for any interface I and class C it generates class C' inheriting I and implementing all methods of I in terms of forwarding calls to methods of C with same name and signature. What does happen here is that `wrap` was not implemented with NVI in mind and tries to override `both` in C' which, of course, can't work. File an enhancement request for `wrap` to become aware of NVI.That's kinda what I suspected was happening. I've added it to bugzilla: https://d.puremagic.com/issues/show_bug.cgi?id=12064 Thanks guys
Feb 02 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(); } }It seems that wrap is expecting your type to implement both(). I think this should be considered a bug and placed in bugzilla. On another note: import std.typecons: wrap;
Feb 01 2014