Re: Derived type
thanks, i tried 2 variants: ```d struct Tnew {TBase payload; alias payload this;} ``` ```d enum Tnew : Tbase {init = Tbase.init} ``` both works, but 1-st not allow "2 level" cast: ```d struct Xptr {void* payload; alias payload this;} //Xptr based on void* struct Xobj {Xptr payload; alias payload this;} //Xobj based on Xptr Xptr xptr = cast(Xptr) null; //OK Xobj xobj = cast(Xobj) null; //ERROR Xobj xobj = cast(Xobj) cast(Xptr) null; //OK, needs both levels explitity ``` ```d enum Xptr : void* {init = (void*).init} //Xptr based on void* enum Xobj : Xptr {init = Xptr.init} //Xobj based on Xptr Xptr xptr = cast(Xptr) null;//OK Xobj xobj = cast(Xobj) null;//OK ``` so "enum" variant is better for me, thanks!
Re: Derived type
On Thursday, 1 April 2021 at 12:07:17 UTC, WebFreak001 wrote: You can add a custom init value if you want to allow one: ```d enum Xobj : void* { init = null } ``` Thank you!
Re: Derived type
On Tuesday, 30 March 2021 at 19:02:09 UTC, novice2 wrote: [...] Strange syntax. Behavour exactly what i want, but this code not works for me :( enum Xobj : void*; Xobj var; //DMD Error: enum test7.Xobj forward reference of Xobj.init You can add a custom init value if you want to allow one: ```d enum Xobj : void* { init = null } ```
Re: Derived type
On Wednesday, 31 March 2021 at 12:09:33 UTC, Basile B. wrote: yeah template instances are identified using the parameters identifiers, then the alias is just a syntactic shortcut to that, not producing a new symbol with a unique mangle... so, no way to generate struct with parametrized name by template or mixin template? That being said you can still use a string mixin if the messages have to be correct ... thank you!
Re: Derived type
On Wednesday, 31 March 2021 at 04:49:50 UTC, novice3 wrote: On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote: struct Typedef(TBase) { TBase payload; alias payload this; } alias Xobj = Typedef!(void*); This is how std.typecons.Typedef made, IMHO. The problem is this code generate struct with name "Typedef!(void*)", then compiler show this name (not "Xobj") in messages: https://run.dlang.io/is/eEI2yC void* bad; foo(bad); Error: function foo(Typedef!(void*) obj) is not callable using argument types (void*) cannot pass argument bad of type void* to parameter Typedef!(void*) obj yeah template instances are identified using the parameters identifiers, then the alias is just a syntactic shortcut to that, not producing a new symbol with a unique mangle... but the message is correct assuming you want void* to be rejected. That being said you can still use a string mixin if the messages have to be correct --- string genTypeDef(TBase)(string name) { return "struct " ~ name ~ "{" ~ TBase.stringof ~ " payload; alias payload this;}"; } mixin(genTypeDef!(void*)("Xobj")); void foo (Xobj obj) {} ---
Re: Derived type
On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote: struct Typedef(TBase) { TBase payload; alias payload this; } alias Xobj = Typedef!(void*); This is how std.typecons.Typedef made, IMHO. The problem is this code generate struct with name "Typedef!(void*)", then compiler show this name (not "Xobj") in messages: https://run.dlang.io/is/eEI2yC void* bad; foo(bad); Error: function foo(Typedef!(void*) obj) is not callable using argument types (void*) cannot pass argument bad of type void* to parameter Typedef!(void*) obj
Re: Derived type
On Tuesday, 30 March 2021 at 19:33:31 UTC, novice2 wrote: On Tuesday, 30 March 2021 at 19:12:29 UTC, Ali Çehreli wrote: "Derived type" is used in the context of object oriented programming at least in D Sorry, i use wrong termin. I just want create new type Tnew, based on exist type Tbase. Tnew have same allowed values, same properties, same allowed operations as Tbase. Compiler should distinguish New from Tbase. Allowed implicit cast Tnew to Tbase. Prohibited implicit cast Tbase to Tnew. Allowed exlicit cast Tbase to Tnew. That's precisely what the alias this feature is intended to do. https://dlang.org/spec/class.html#alias-this Thanks, this is what i want. I just think that Typedef do it for me, hide this boilerplait code. That's not the intended purpose of the Typedef template. Its documentation explicitly says it "allows the creation of a unique type which is based on an existing type". The keyword there is *unique*.
Re: Derived type
On Tuesday, 30 March 2021 at 19:47:41 UTC, novice2 wrote: My tries to make template for struct and alias this: // variant 1 template Typedef(alias Tnew, Tbase) { struct Tnew { Tbase payload; alias payload this; } } you must give a name to the template specialization, using alias [1], also the TypeDef declaration can be highly simplified: --- struct Typedef(TBase) { TBase payload; alias payload this; } alias Xobj = Typedef!(void*); void foo (Xobj obj) {} --- [1]: https://dlang.org/spec/declaration.html#alias
Re: Derived type
My tries to make template for struct and alias this: // variant 1 template Typedef(alias Tnew, Tbase) { struct Tnew { Tbase payload; alias payload this; } } Typedef!(Xobj, void*); void foo (Xobj obj) {} //compiler Error: no identifier for declarator Typedef!(Xobj, void*) // variant 2 mixin template Typedef(alias Tnew, Tbase) { struct Tnew { Tbase payload; alias payload this; } } mixin Typedef!(Xobj, void*); //compiler Error: undefined identifier Xobj
Re: Derived type
On Tuesday, 30 March 2021 at 19:12:29 UTC, Ali Çehreli wrote: "Derived type" is used in the context of object oriented programming at least in D Sorry, i use wrong termin. I just want create new type Tnew, based on exist type Tbase. Tnew have same allowed values, same properties, same allowed operations as Tbase. Compiler should distinguish New from Tbase. Allowed implicit cast Tnew to Tbase. Prohibited implicit cast Tbase to Tnew. Allowed exlicit cast Tbase to Tnew. but your examples indicate you need something else. How about the 'alias this' feature? Thanks, this is what i want. I just think that Typedef do it for me, hide this boilerplait code.
Re: Derived type
On 3/30/21 6:28 AM, novice3 wrote: > I want create derived type in D "Derived type" is used in the context of object oriented programming at least in D but your examples indicate you need something else. How about the 'alias this' feature? import std.stdio; struct Xobj { void* value; alias value this; } void main() { int i; auto var = Xobj(); writeln(var); int j; var = } alias this is for implicit conversions, from Xobj to void* in this case. Ali
Re: Derived type
On Tuesday, 30 March 2021 at 14:45:12 UTC, WebFreak001 wrote: Xobj can then be used interchangeably with void*, so all void* arguments accept Xobj and all Xobj arguments accept void*. yes, i understand alias, and i dont want such behaviour If you want a type-safe alias that makes all void* arguments accept Xobj but not Xobj arguments to accept void* yes, this is that i search you can use `Typedef` like you linked. Problem with Typedef template - code alias Xobj = Typedef!(void*) not generate type named "Xobj", but type named "Typedef!(void*, null, null)". This makes compiler error messages unusable. enum Xobj : void*; ``` This allows explicit conversion in both ways using cast, but only allows implicit conversion from Xobj to void*, not from void* to Xobj: Strange syntax. Behavour exactly what i want, but this code not works for me :( enum Xobj : void*; Xobj var; //DMD Error: enum test7.Xobj forward reference of Xobj.init
Re: Derived type
On Tuesday, 30 March 2021 at 13:43:52 UTC, Mike Parker wrote: the straightforward way is just to use an alias. i cant use alias - compiler cannot distinguish base type and alias, and cannot catch programmer errors Buf if you need a more concrete type, you can use alias this in a struct: I think Typedef template should do this struct for me. Thanks Mike, this way is what i wanted struct Xobj { private void* payload; alias payload this; } Xobj good; foo(good);//nice foo(cast(Xobj)null); //explicit cast allowed - nice foo(null);//no implicit cast disallowed - compiler error - nice void* bad; foo(bad); //compiler distinguish type - error - nice I think Typedef template should do this struct for me. Problem with Typedef template - code alias Xobj = Typedef!(void*) not generate struct named "Xobj", but struct named "Typedef!(void*, null, null)". This makes compiler error messages unusable. I will try to make template for struct. But template is black magic for me :)
Re: Derived type
On Tuesday, 30 March 2021 at 14:45:12 UTC, WebFreak001 wrote: When i adapt C code, i see new type creation: The typedef in C in D is just an alias: ``` alias Xobj = void*; ``` I totally overlooked the part about porting from C. Yes, this is the way to go in that case.
Re: Derived type
On Tuesday, 30 March 2021 at 13:28:55 UTC, novice3 wrote: Hello. When i adapt C code, i see new type creation: typedef void* Xobj; Or code like this: struct _Xobj; typedef struct _Xobj *Xobj; I want create derived type in D, found std.typecons.Typedef template, and write: alias Xobj = Typedef!(void*, (void*).init); But compiler use long type name in error messages, like this: Error: function test6.foo(Typedef!(void*, null, null) obj) is not callable using argument types (void*) cannot pass argument bad of type void* to parameter Typedef!(void*, null, null) obj This messages dont help me understand, which type should i use. What i should change? Or Typedef template should be changes? Any Typedef alternatives? The typedef in C in D is just an alias: ``` alias Xobj = void*; ``` Xobj can then be used interchangeably with void*, so all void* arguments accept Xobj and all Xobj arguments accept void*. If you want a type-safe alias that makes all void* arguments accept Xobj but not Xobj arguments to accept void* you can use `Typedef` like you linked. However using this language built-in feature is much simpler and cheaper in terms of resource usage and compile time + always results in the fastest code: (there is no conversions at all) ``` enum Xobj : void*; ``` This allows explicit conversion in both ways using cast, but only allows implicit conversion from Xobj to void*, not from void* to Xobj: ``` void* x = someValue; Xobj y = cast(Xobj)x; // ok x = y; // ok y = x; // error (need explicit cast) ```
Re: Derived type
On Tuesday, 30 March 2021 at 13:28:55 UTC, novice3 wrote: This messages dont help me understand, which type should i use. What i should change? Or Typedef template should be changes? From the docs: "Unlike the alias feature, Typedef ensures the two types are not considered as equals. Parameters:" https://dlang.org/phobos/std_typecons.html#Typedef Any Typedef alternatives? If you want your new type to be interchangeable with another, the straightforward way is just to use an alias. Buf if you need a more concrete type, you can use alias this in a struct: import std.stdio; struct MyType { void* wrapped; alias wrapped this; } void doSomething(void* t) { writeln(*(cast(int*)t)); } void main() { int i = 20; MyType mt = MyType(); doSomething(mt); }
Derived type
Hello. When i adapt C code, i see new type creation: typedef void* Xobj; Or code like this: struct _Xobj; typedef struct _Xobj *Xobj; I want create derived type in D, found std.typecons.Typedef template, and write: alias Xobj = Typedef!(void*, (void*).init); But compiler use long type name in error messages, like this: Error: function test6.foo(Typedef!(void*, null, null) obj) is not callable using argument types (void*) cannot pass argument bad of type void* to parameter Typedef!(void*, null, null) obj This messages dont help me understand, which type should i use. What i should change? Or Typedef template should be changes? Any Typedef alternatives?
Re: Any way to override base type with dervived in derived type
On 5/25/18 4:02 PM, IntegratedDimensions wrote: So, I upgraded everything, tried to add the setter and get an compile time access violation: override @property T t(T v) { _t = v; return v; } Changing T v to TT v gives the violation override @property T t(TT v) { _t = v; return v; } Parameters work the opposite way as return values. That is, you can't override a base class's function that accepts a base type with one that accepts a derived type. This is because you must be able to call the virtual function with the base type, and this would not work. So what is technically possible is to call an overridden function with a base type (i.e. override a function that accepts a TT with one that accepts a T), but I don't know if D allows this, and obviously it doesn't help with your use case. object.Error@(0): Access Violation 0x004850C8 0x00485C96 0x0043E22A 0x0047FB50 0x0046109A 0x0052401A 0x77D0B605 in LdrQueryProcessModuleInformation 0x77D11D02 in RtlQueryProcessLockInformation 0x77D11705 in RtlQueryProcessDebugInformation 0x77CA47DF in RtlAllocateHeap Hm... this is a runtime stack trace. And a crappy one at that (very little info at the top of the stack). If you are getting this at compile time, then it's the compiler having an issue, which is automatically a bug (compiler should never throw an error). If you have a reduced test case, I'd recommend filing an issue, and tagging it with ICE. But it needs to be reproducible. -Steve
Re: Any way to override base type with dervived in derived type
On Saturday, 26 May 2018 at 01:11:39 UTC, crimaniak wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). ... 1) Your architecture is wrong, I recommend to rethink it. Prove it genius! I recommend you rethink your absolutes without having a clue. Go back to SO, they need more Nazi's. 2) You still can deal with it using template mixins https://dlang.org/spec/template-mixin.html I've already said templates do not work. Time to rethink your answers, they are useless and you are not an authority, quick acting like one.
Re: Any way to override base type with dervived in derived type
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). ... 1) Your architecture is wrong, I recommend to rethink it. 2) You still can deal with it using template mixins https://dlang.org/spec/template-mixin.html
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 10:45:23 UTC, Steven Schveighoffer wrote: On 5/24/18 4:24 PM, IntegratedDimensions wrote: What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } It should work, you are allowed covariant overloads. However, private functions are not virtual, you need to make them at least protected. -Steve So, I upgraded everything, tried to add the setter and get an compile time access violation: override @property T t(T v) { _t = v; return v; } Changing T v to TT v gives the violation override @property T t(TT v) { _t = v; return v; } object.Error@(0): Access Violation 0x004850C8 0x00485C96 0x0043E22A 0x0047FB50 0x0046109A 0x0052401A 0x77D0B605 in LdrQueryProcessModuleInformation 0x77D11D02 in RtlQueryProcessLockInformation 0x77D11705 in RtlQueryProcessDebugInformation 0x77CA47DF in RtlAllocateHeap While my specific use case is far more complex in design, the original essentially boils down to the dpaste I gave. Probably won't spent any time on it since I do not need the setter in this case(can use the field directly). But a bug is probably related to the code that fixed the "original bug" and possibly windows. What I do know is that 2.75 did not produce this access violation and it was the same code(I just uncommented out the setter). The original dpaste code that did pass, I though, doesn't seem to pass now. I thought it was working for 2.80 and so I changed it to 2.69 and it failed but I might have made a mistake or the page lagged. Either way, maybe you have a clue for future reference.
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 10:45:23 UTC, Steven Schveighoffer wrote: On 5/24/18 4:24 PM, IntegratedDimensions wrote: What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } It should work, you are allowed covariant overloads. However, private functions are not virtual, you need to make them at least protected. -Steve Wow, I didn't expect that! Thanks, exactly what I needed. Unfortunately property setters seem to be broken. https://dpaste.dzfl.pl/24ce8c7e0681 Seems this is a bug though that has been fix as it only happens on certain the older compilers. I had to downgrade because in the latest I get a lot of link errors ;/
Re: Any way to override base type with dervived in derived type
On 5/24/18 4:24 PM, IntegratedDimensions wrote: What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } It should work, you are allowed covariant overloads. However, private functions are not virtual, you need to make them at least protected. -Steve
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 01:42:48 UTC, Basile B. wrote: On Friday, 25 May 2018 at 01:17:45 UTC, IntegratedDimensions wrote: On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote: On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions wrote: On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D. You must put a template parameter in the interface and specialize the class that implements the interface. ``` module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } ``` but obviously this won't work if you want to derive C1 or C2... or if there 100 fields. This isn't a proper solution. The whole issue is not outside of C but inside Hypothetically class C : A { @property TT : T t() { return _t; } // t can be used directly as TT rather than
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 01:17:45 UTC, IntegratedDimensions wrote: On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote: On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions wrote: On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D. You must put a template parameter in the interface and specialize the class that implements the interface. ``` module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } ``` but obviously this won't work if you want to derive C1 or C2... or if there 100 fields. This isn't a proper solution. The whole issue is not outside of C but inside Hypothetically class C : A { @property TT : T t() { return _t; } // t can be used directly as TT rather than having to do (cast(TT)t) everywhere t is used. } would solve
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote: On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions wrote: On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D. You must put a template parameter in the interface and specialize the class that implements the interface. ``` module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } ``` but obviously this won't work if you want to derive C1 or C2... or if there 100 fields. This isn't a proper solution. The whole issue is not outside of C but inside Hypothetically class C : A { @property TT : T t() { return _t; } // t can be used directly as TT rather than having to do (cast(TT)t) everywhere t is used. } would solve the problem and it would scale. The way it would work is that inside
Re: Any way to override base type with dervived in derived type
On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions wrote: On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D. You must put a template parameter in the interface and specialize the class that implements the interface. ``` module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } module runnable; class T{} class TT : T{} interface I(N) { @property N t(); } abstract class A(N) : I!N { N _t; @property N t() { return _t; } } class C1 : A!T{} class C2 : A!TT{} void main(string[] args) { import std.traits; static assert(is(ReturnType!(C1.t) == T)); static assert(is(ReturnType!(C2.t) == TT)); } ``` but obviously this won't work if you want to derive C1 or C2...
Re: Any way to override base type with dervived in derived type
On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote: On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? It really should be obvious that A was meant to derive from I. This is just standard oop. Simply leaving off : I should not be a deal breaker because it would not change the whole problem from black to white or vice versa. T is a member to be included. You can only derive from one class. C can't derive from both A and T and even if it did, it would mean something else. https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... This is not a composition pattern. This is a parallel inherentence pattern. TT : T = T || | vv v C : A : I TT is used with C and T with I. When C changes to C', TT : T changes to TT' : T All functions that use TT in C are forced to use it as if it were of type T rather than TT which requires a bunch of casts. This is generally a violation of type logic. There is nothing in that prevents t from being something like TTT which has no direct relation to TT. But the programming logic of the code enforces t to be of type TT in C *always*. So I don't know why I would have to use casting all the time. It would be nice if there where a simple logical way to enforce a design pattern in the type system knowing that it is enforced at runtime. This makes cleaner code, nothing else. But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´ No, I am trying to keep parallel derived types consistently connected. If A is derived from B and C from D and B uses D then A uses C. Consistency cannot be guaranteed by the type system at compile time because A is typed to use C, I want to restrict it further to D.
Re: Any way to override base type with dervived in derived type
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions wrote: class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) As as a side note: I can hardly follow this, as you don't show, where you use the interface I. However, especially if TT was refactored in such a way, that is a set difference of T and not T, why you choose to derive from T instead of to contain T? https://en.wikipedia.org/wiki/Composition_over_inheritance http://wiki.c2.com/?CompositionInsteadOfInheritance Well, can imagine useful cases though... But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename? Maybe, you are looking for Curiously Recurring Template Pattern? ´´´ interface I(P) { @property P t(); } abstract class T(P) : I!P { P _p; @property P t() { return _p; } } class TT : T!TT { } void main() { auto tt = new TT(); static assert(is(typeof(tt.t) == TT)); } ´´´
Any way to override base type with dervived in derived type
class T; class TT : T; interface I { @property T t(); } abstract class A { T _t; @property T t() { return _t; } } class C : A { // Stuff below uses t as TT but compiler, of course, treats t as T ... } The issue is that I programmed the class C with a variable that directly was based off TT, I later subderived T from TT and exposed it in I. (TT was refactored in to T and not T) But all the code in C assumes t is of type TT but now due to the interface it looks like a T, even though internally it is actually a TT. What I'd like to do is class C : A { private override @property TT t() { return cast(TT)(_t); } // null check if necessary // Stuff below uses t which is now a TT ... } or whatever. This is simply so I don't have to rename or cast all my uses of t in C to type TT. I'm pretty much guaranteed that in C, t will be type TT due to the design(C goes with TT like bread with butter). So, it would be nice if somehow I could inform the type system that in C, t is always of type TT and so treat it as such rather than forcing me to explicitly cast for every use. Again, I could rename things to avoid the same name usage but in this case it is not necessary because of the design. Is there any semantics that can get me around having to rename?
Re: Access derived type in baseclass static function template
On Wednesday, 2 August 2017 at 15:38:12 UTC, Steven Schveighoffer wrote: On 8/2/17 11:06 AM, Timoses wrote: On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote: However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter. I guess the `this` is really misleading it being a static method. I suppose https://issues.dlang.org/buglist.cgi?bug_severity=enhancement_status=NEW_status=ASSIGNED_status=REOPENED=D_format=report-table_axis_field=bug_severity would be the place for an enhancement request? Possibly related: https://issues.dlang.org/show_bug.cgi?id=14191 Yes, that's exactly it. Note that typeof(this) has special meaning for static methods: class C { static typeof(this) foo() { return new typeof(this); } } So there is precedence for the meaning of `this` in a static context. -Steve Oh, just now get it after creating the issue ^^. Makes sense. I kind of connected the "this" to existing instances because the DMD compiler often complains about something like "need this for..." when calling something from a static method that... well... needs "this" or instantiation.. E.g.: class A { static void a() { b(); } void b(); } will throw Error: need 'this' for 'b' of type 'void()'
Re: Access derived type in baseclass static function template
On Wednesday, 2 August 2017 at 12:07:46 UTC, Timoses wrote: Hey, wondering whether it's possible to access the derived type from a function template in the base class or interface. [...] Created an enhancement issue: https://issues.dlang.org/show_bug.cgi?id=17714
Re: Access derived type in baseclass static function template
On 8/2/17 11:06 AM, Timoses wrote: On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote: However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter. I guess the `this` is really misleading it being a static method. I suppose https://issues.dlang.org/buglist.cgi?bug_severity=enhancement_status=NEW_status=ASSIGNED_status=REOPENED=D_format=report-table_axis_field=bug_severity would be the place for an enhancement request? Possibly related: https://issues.dlang.org/show_bug.cgi?id=14191 Yes, that's exactly it. Note that typeof(this) has special meaning for static methods: class C { static typeof(this) foo() { return new typeof(this); } } So there is precedence for the meaning of `this` in a static context. -Steve
Re: Access derived type in baseclass static function template
Thanks Arafel, the alias workaround might just be a nice way to put it. On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote: What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. I'm not looking to overwrite the static method (which would refer to virtual, right?). The solution I had previously was: interface I { static void test(T)() { writeln(T.stringof); } } class B : I { alias type = int; static void test() { I.test!type(); } } void main() { B.test(); } However, this requires to add the base type as in I.test!type(); otherwise (only test!type();) it complains about Error: template instance test!type test is not a template declaration, it is a function I was hoping there was a way to simply define it in the base class/interface without producing redundant code in each derived class. Arafel's solution gets very close! On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote: However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter. I guess the `this` is really misleading it being a static method. I suppose https://issues.dlang.org/buglist.cgi?bug_severity=enhancement_status=NEW_status=ASSIGNED_status=REOPENED=D_format=report-table_axis_field=bug_severity would be the place for an enhancement request? Possibly related: https://issues.dlang.org/show_bug.cgi?id=14191 On Wednesday, 2 August 2017 at 14:23:26 UTC, Arafel wrote: What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. Well, there are interesting things to do: https://dpaste.dzfl.pl/ed826ae21473 I don't know if that's what one would call "virtual static", but I'd say it comes close... Nifty, but still doesn't allow knowing the derived type B in the foo method of A, does it?
Re: Access derived type in baseclass static function template
What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. Well, there are interesting things to do: https://dpaste.dzfl.pl/ed826ae21473 I don't know if that's what one would call "virtual static", but I'd say it comes close...
Re: Access derived type in baseclass static function template
On 8/2/17 9:11 AM, Timoses wrote: On Wednesday, 2 August 2017 at 12:49:12 UTC, Steven Schveighoffer wrote: Thanks for the reply! Not sure I understand correctly, though. interface I {} class A : I {} void test(T)(T t) if(is(T: I)) { writeln(T.type.stringof); } void main() { A.test; } throws: Error: no property 'test' for type 'app.A' which it of course does... test(A) makes no sense either. I need to call it statically and want to know the derived class type in the base class (or interface) function template. Is there a trick in your answer? : P Sorry, I didn't read your original post thoroughly, you need an instance to make this work properly. A a; a.test; // should work What you are looking for is virtual static methods, and D doesn't have those. I don't know if there's a way to make it work with existing features. However, your original code has potential as an enhancement request, as the type is known at compile-time and could certainly be resolved to pass in as the `this` template parameter. -Steve
Re: Access derived type in baseclass static function template
On 08/02/2017 02:07 PM, Timoses wrote: Hey, wondering whether it's possible to access the derived type from a function template in the base class or interface. this T does not seem to be working, I guess because it's a static function and this does not exists?! [...] Any way I could accomplish this? Well, it's a clumsy workaround, but the only thing missing seems to be the "this T" automatic deduction. I was recently hit by something similar: the "this" parameter deduction only works for instance methods. It was not totally clear if it was a bug or a feature... The documentation [1] is however quite clear: TemplateThisParameters are used in member function templates to pick up the type of the this reference. So, static functions doesn't seem to be covered. You can, however, make it explicit: ``` B.test!B(); C.test!C(); ``` And then even alias it to prevent accidental mismatches: ``` import std.stdio; interface I { static void test(this T)() { writeln(T.type.stringof); } } abstract class A { static void test(this T)() { writeln(T.type.stringof); } } class B : A { alias type = uint; } class C : I { alias type = int; } void main() { test!B(); test!C(); } alias test(T) = T.test!T; ``` [1]: http://dlang.org/spec/template.html#TemplateThisParameter
Re: Access derived type in baseclass static function template
On Wednesday, 2 August 2017 at 12:49:12 UTC, Steven Schveighoffer wrote: On 8/2/17 8:07 AM, Timoses wrote: Hey, wondering whether it's possible to access the derived type from a function template in the base class or interface. this T does not seem to be working, I guess because it's a static function and this does not exists?! Yep. Any way I could accomplish this? Move test outside the interface: void test(C)(C c) if(is(C : I)) { writeln(C.type.stringof); } Though, at that point, you don't need I. I'm assuming you have a more complex real-world example. -Steve Thanks for the reply! Not sure I understand correctly, though. interface I {} class A : I {} void test(T)(T t) if(is(T: I)) { writeln(T.type.stringof); } void main() { A.test; } throws: Error: no property 'test' for type 'app.A' which it of course does... test(A) makes no sense either. I need to call it statically and want to know the derived class type in the base class (or interface) function template. Is there a trick in your answer? : P
Re: Access derived type in baseclass static function template
On 8/2/17 8:07 AM, Timoses wrote: Hey, wondering whether it's possible to access the derived type from a function template in the base class or interface. this T does not seem to be working, I guess because it's a static function and this does not exists?! Yep. Any way I could accomplish this? Move test outside the interface: void test(C)(C c) if(is(C : I)) { writeln(C.type.stringof); } Though, at that point, you don't need I. I'm assuming you have a more complex real-world example. -Steve
Access derived type in baseclass static function template
Hey, wondering whether it's possible to access the derived type from a function template in the base class or interface. this T does not seem to be working, I guess because it's a static function and this does not exists?! interface I { static void test(this T)() { writeln(T.type.stringof); } } abstract class A { static void test(this T)() { writeln(T.type.stringof); } } class B : A { alias type = uint; } class C : I { alias type = int; } void main() { B.test(); C.test(); } Throws: Error: template app.A.test cannot deduce function from argument types !()(), candidates are: app.A.test(this T)() Error: template app.I.test cannot deduce function from argument types !()(), candidates are: app.I.test(this T)() Any way I could accomplish this?
Re: Getting most derived type of object that implements interface
Ahh I see, thanks guys.
Re: Getting most derived type of object that implements interface
On 7/25/16 5:54 AM, Kagamin wrote: Cast it to Object: FooInterface a = new BarImplementsInterface(); FooBaseClass b = new BarDerivedClass(); Object o = cast(Object)a; writefln("a class: %s", a.classinfo.name); writefln("b class: %s", b.classinfo.name); writefln("o class: %s", o.classinfo.name); Yes, for the unrelated reason that COM objects may not be D objects, interfaces that can only possibly be D Objects don't implicitly cast to Object. -Steve
Re: Getting most derived type of object that implements interface
yep, cast it. without the cast, compiler assuming that it knows the type in runtime, and is using well-known classinfo address instead of really looking into instance for that.
Re: Getting most derived type of object that implements interface
Cast it to Object: FooInterface a = new BarImplementsInterface(); FooBaseClass b = new BarDerivedClass(); Object o = cast(Object)a; writefln("a class: %s", a.classinfo.name); writefln("b class: %s", b.classinfo.name); writefln("o class: %s", o.classinfo.name);
Getting most derived type of object that implements interface
I'm having trouble getting the full name of an object of a class that implements an interface, using typeid() or .classinfo, the behavior seems to be different from that of a class that simply derives other classes. interface FooInterface {} class BarImplementsInterface : FooInterface {} class FooBaseClass {} class BarDerivedClass : FooBaseClass {} void main() { FooInterface a = new BarImplementsInterface(); FooBaseClass b = new BarDerivedClass(); writefln("a class: %s", a.classinfo.name); writefln("b class: %s", b.classinfo.name); } Output: a class: test.FooInterface b class: test.BarDerivedClass I expected "a class: test.BarImplementsInterface" as the result output.. Am I expecting the wrong behavior? Is there a preferred way to do this?
Re: Cannot implicitly convert derived type
On Sunday, 23 February 2014 at 01:37:08 UTC, Steven Schveighoffer wrote: On Sat, 22 Feb 2014 15:17:37 -0500, Frustrated c1514...@drdrb.com wrote: It is legal exactly because I will always guarantee that the proper button will be used. Static typing says it's not legal. D does not do dynamic type checking upon calling virtual functions. It is not logically legal as mentioned several times... no one needs to mention that. But it is legal within the context of the code. I'll never use a RogueButton so why force me to code for the chance I might? You may not be the only one using WindowsGui. You can't guarantee other code won't do it. In any case, the compiler cannot possibly know your intentions. Basically, the point is, the compiler could enforce the above but make the code more readable. e.g., I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } This solution is not as efficient as the one I outlined. If you have a WindowsGui object, no need to accept iButton when you require WindowsButton. One allows me to program in a natural way while the other makes me jump through hoops which litters the code with a bunch of casts and checks which are only there in the odd event that I assign the wrong type(which, I'm not going to do on purpose). Sorry, if you want a dynamically typed language, use one. D is not that. Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could absolutely guarantee that I won't pass them then there should be no problem(no asserts). Since I can't guarantee it I have to litter my code with checks? The compiler could do this for me. You can't guarantee it. That is the point. The compiler could do the checks for you, but D is not dynamically typed. The best you can do is encapsulate the type checking code as a mixin. -Steve It has nothing to do with being dynamically typed. We can't solve this problem until you get your head out of the gutter(the gutter being how D does things already. Can't make progress on something if you ever look beyond what it can do). This has to do with simply adding checks to enforce the type. I can guarantee it, but like you said, I can't guarantee what others do. Hence the check. The fact is, I presented two versions of the code. One represents the other. It is a representational problem, nothing more, nothing less. Please understand that from now on. e.g., a switch statement is just a representational form of if statements to simplify. I'll I'm talking about is adding a switch statement. (if you take that literal and can't see how it relates to the original problem then you are completely missing the point of the whole discussion) I did think it might be possible to use CT reflection to generate all the type checking automatically but this might be difficult and would have to generate a new class. It seems like the only way to get at this problem in D.
Re: Cannot implicitly convert derived type
On Saturday, 22 February 2014 at 20:17:37 UTC, Frustrated wrote: I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } Why does your WindowsGui violate the iGui contract?
Re: Cannot implicitly convert derived type
On Sunday, 23 February 2014 at 20:41:30 UTC, Jesse Phillips wrote: On Saturday, 22 February 2014 at 20:17:37 UTC, Frustrated wrote: I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } Why does your WindowsGui violate the iGui contract? It doesn't. It simply that one can't specify dependencies in D if (iGui is WindowsGui) then iButton is WindowsButton; It's not very hard logic but people are not even trying. I am attempting to make a mixin to solve the problem. The mixin will simply overload all methods in the derived class(WindowsGui) and when WindowsButton is used it will create an overload using iButton(to satisfy the interface) with the check to make sure the iButton is a WindowsButton. It will give me what I want except I have to create the mixin and then insert it in all the classes. (In theory though it should not add any overhead is used where it is not suppose to) But unfortunately when I try to find all members that use WindowsButton(or whatever) to be able to create the new overload, I get error due to the inner foreach. foreach (am; __traits(derivedMembers, B)) foreach (m; [__traits(getOverloads, B, am)]) { // check if method contains an parameter of type WindowsButton, then create identical method definition that uses iButton instead. Put a check in the method and call this method using a cast. This essentially overrides the virtual method satisfying the interface but passes the work to the user defined method. } What the above code will do, when working, is create the verbose code you quoted from the first case: @property WindowsButton button(WindowsButton b) { } The ***mixin*** turns **ADDS** this @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; button(b); // Call the user defined function here(hopefully) }
Re: Cannot implicitly convert derived type
On Sunday, 23 February 2014 at 21:06:03 UTC, Frustrated wrote: Why does your WindowsGui violate the iGui contract? It doesn't. It simply that one can't specify dependencies in D if (iGui is WindowsGui) then iButton is WindowsButton; It's not very hard logic but people are not even trying. I understand what you intend your code to do, but that is still breaking the contract which you setup. iGui takes an iButton because you defined it that way, to only handle specific types of iButton is a breach of contract. The language lets you break contracts, but it should not help you do so.
Re: Cannot implicitly convert derived type
On Sunday, 23 February 2014 at 23:14:24 UTC, Jesse Phillips wrote: On Sunday, 23 February 2014 at 21:06:03 UTC, Frustrated wrote: Why does your WindowsGui violate the iGui contract? It doesn't. It simply that one can't specify dependencies in D if (iGui is WindowsGui) then iButton is WindowsButton; It's not very hard logic but people are not even trying. I understand what you intend your code to do, but that is still breaking the contract which you setup. iGui takes an iButton because you defined it that way, to only handle specific types of iButton is a breach of contract. The language lets you break contracts, but it should not help you do so. Nope. It has nothing to do with the contract. You are totally missing the point. It is all about reducing typing a bunch of extra shit. Don't know why you can't see that. In any case once I get the mixin in finish it will do what I want and be good enough. IF the damn language had the ability to specify dependencies then it wouldn't be a problem. Just because you insist on using D's current model as the only model you will always be right... I hope that makes you happy. In the mean time I'll be moving on to writing cleaner code...
Re: Cannot implicitly convert derived type
On Sunday, 23 February 2014 at 23:23:07 UTC, Frustrated wrote: Nope. It has nothing to do with the contract. You are totally missing the point. iGui has a function which takes any iButton. That is a defined contract of iGui, your denial does not change that.
Re: Cannot implicitly convert derived type
On Monday, 24 February 2014 at 00:09:55 UTC, Jesse Phillips wrote: On Sunday, 23 February 2014 at 23:23:07 UTC, Frustrated wrote: Nope. It has nothing to do with the contract. You are totally missing the point. iGui has a function which takes any iButton. That is a defined contract of iGui, your denial does not change that. Let me put this another way. I started with the question of why you need to break the contract you define. In other words, What is the problem you are trying to solve. But instead you insisted the it must be solved this way instead of giving details on what the problem actually is. D already provides a way to say that WindowsGui only takes WindowsButtons, you did so in your original code, just don't extend iGui since that isn't the contract you fulfill.
Re: Cannot implicitly convert derived type
On Sun, 23 Feb 2014 08:26:10 -0500, Frustrated c1514...@drdrb.com wrote: It has nothing to do with being dynamically typed. We can't solve this problem until you get your head out of the gutter(the gutter being how D does things already. Can't make progress on something if you ever look beyond what it can do). You have a nasty habit of assuming people do not know as much as you. Bottom line, I get what you are asking, always have. It could be done, but D won't do it for you, nor will it be modified to do that. The costs of additional runtime type checks are far too great to implicitly add them. Use mixin generation, and be done with it. -Steve
Re: Cannot implicitly convert derived type
On Saturday, 22 February 2014 at 01:03:22 UTC, Steven Schveighoffer wrote: On Fri, 21 Feb 2014 17:54:06 -0500, Frustrated c1514...@drdrb.com wrote: interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? What you are trying to do is not legal. e.g.: class RogueButton : iButton { } iGui gui = new WindowsGui; gui.button = new RogueButton; Note that setting gui.button to any iButton is legal, but the derived type REQUIRES a WindowsButton. This would have to be rejected at runtime, because the compile-time type is implicitly convertible. There are two types of variance that are logical, contravariance and covariance. covariance allows you to *return* a more derived type than the base. In other words, this would be legal (assume same iButton/WindowsButton structure): interface iGui { @property iButton button(); } class WindowsGui : iGui { @property WindowsButton button() {...}; } This works, because whenever you return a WindowsButton, you ALSO are returning an iButton. In fact, D supports this. The opposite is contravariance, and that's used on *input* parameters. In this case, the derived method can accept a base of the parameter that the base class defines: interface iGui { void button(WindowsButton); // please humor me, I know you don't want to do this :) } class WindowsGui : iGui { void button(iButton); } This is logically sound, because the actual implementation only requires an iButton. Therefore, passing a WindowsButton into the iGui interface still satisfies that requirement. However, D does NOT support contravariance. 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. This is actually the correct mechanism if you want to use polymorphism. However, in some cases, a templated system may be more advantageous than an interface system. One other possibility is to use overloading -- i.e.: class WindowsGui { @property WindowsButton button(WindowsButton b) { return _button = b;} @property WindowsButton button(iButton b) { if(auto wb = cast(WindowsButton)b) button = wb; else throw new ButtonException; } } This is not really an attractive solution, but it could be easily generated as a mixed-in solution. -Steve It is legal exactly because I will always guarantee that the proper button will be used. It is not logically legal as mentioned several times... no one needs to mention that. But it is legal within the context of the code. I'll never use a RogueButton so why force me to code for the chance I might? Again, WindowsGui only uses WindowsButton which is a iButton type. So why force me to always use iButton and cast it to WindowsButton? Why can't I relax the condition to use the base type? The only reason it is illegal is because I could use a RogueButton, BUT I WON'T! If I do, then it is an error. Basically, the point is, the compiler could enforce the above but make the code more readable. e.g., I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } One is very clean, the other is not. If by chance I use the wrong button(a Rogue button) then it results in an error(hopefully user controlled). One allows me to program in a natural way while the other makes me jump through hoops which litters the code with a bunch of casts and checks which are only there in the odd event that I assign the wrong type(which, I'm not going to do on purpose). Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could absolutely guarantee that I won't pass them then there should be no problem(no asserts). Since I can't guarantee it I have to litter my code with checks? The compiler could do this for me.
Re: Cannot implicitly convert derived type
On Saturday, 22 February 2014 at 05:20:25 UTC, Eric Suen wrote: Generic? I don't see how this would help. I'd have to specify every concrete type in the creation of the object which might be significant. I can't use a generic virtual method so that doesn't help either. It would be nice to have something like T foo(T : iButton)(T button); Which then I override with WindowsButton foo(WindowsButton button) { } Since WindowsButton is derived from iButton. The compiler would have to insert a type check to make sure when I called the first one(from the interface) that it was a windows button that was passed(since any iButton could be passed) when using the WindowsGui. The main point of all this is simply efficiency. I have to liter the code with checks and casts when it is entirely possible to get the compiler to automate it all. By doing so one can program the concrete class in a much more natural way.
Re: Cannot implicitly convert derived type
On Sat, 22 Feb 2014 15:17:37 -0500, Frustrated c1514...@drdrb.com wrote: It is legal exactly because I will always guarantee that the proper button will be used. Static typing says it's not legal. D does not do dynamic type checking upon calling virtual functions. It is not logically legal as mentioned several times... no one needs to mention that. But it is legal within the context of the code. I'll never use a RogueButton so why force me to code for the chance I might? You may not be the only one using WindowsGui. You can't guarantee other code won't do it. In any case, the compiler cannot possibly know your intentions. Basically, the point is, the compiler could enforce the above but make the code more readable. e.g., I do this: @property WindowsButton button(WindowsButton b) { } The compiler turns this into @property WindowsButton button(iButton _b) { if (is(_b : WindowsButton)) assert(0, Rogue button used); auto b = cast(WindowsButton)_b; } This solution is not as efficient as the one I outlined. If you have a WindowsGui object, no need to accept iButton when you require WindowsButton. One allows me to program in a natural way while the other makes me jump through hoops which litters the code with a bunch of casts and checks which are only there in the odd event that I assign the wrong type(which, I'm not going to do on purpose). Sorry, if you want a dynamically typed language, use one. D is not that. Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could absolutely guarantee that I won't pass them then there should be no problem(no asserts). Since I can't guarantee it I have to litter my code with checks? The compiler could do this for me. You can't guarantee it. That is the point. The compiler could do the checks for you, but D is not dynamically typed. The best you can do is encapsulate the type checking code as a mixin. -Steve
Re: Cannot implicitly convert derived type
On 02/22/2014 12:17 PM, Frustrated wrote: Again, the whole point of why it is illegal because you can pass a RogueButton... BUT I DON'T INTEND TO PASS THEM! Thinking that way, many rules of a statically type-checked language like D would be unnecessary. ;) WindowsGui only uses WindowsButton which is a iButton type. WindowsGui is totally free to use any type it wants. However, it cannot both claim to implement an interface without actually obeying its requirements. Why can't I relax the condition to use the base type? The users of iGui don't even know what a WindowsButton is: interface iGui { @property iButton button(ref iButton button); } Imagine the following that I write: void foo(WindowsGui gui, iButton b) { gui.button(b); } Is the call legal or not? How would I know and why should I care? I have a WindowsGui, which happens to be an iGui and I have an iButton. According to the contract of the interface I should be able to call it without fear of type problems. Even, I can create my own iButton and pass it to that WindowsGui: gui.button(new MyButton()); I should be able to do all of that just because WindowsGui promises to be an iGui. Getting back to what I said above: WindowsGui is totally free to use any type it wants. That's why both Steven and I made it take its button as a constructor parameter. Then, you also mentioned a setter. That's fine too. As long as WindowsGui allows me to give it an iButton when I call button(), it is all fine. Ali
Re: Cannot implicitly convert derived type
interface iButton { } class WindowsButton : iButton { } interface iGui(T) { @property T button(ref T button); } class WindowsGui : iGui!(WindowsButton) { @property WindowsButton button(ref WindowsButton button) { return button; } } Frustrated c1514...@drdrb.com On Saturday, 22 February 2014 at 05:20:25 UTC, Eric Suen wrote: Generic? I don't see how this would help. I'd have to specify every concrete type in the creation of the object which might be significant. I can't use a generic virtual method so that doesn't help either. It would be nice to have something like T foo(T : iButton)(T button); Which then I override with WindowsButton foo(WindowsButton button) { } Since WindowsButton is derived from iButton. The compiler would have to insert a type check to make sure when I called the first one(from the interface) that it was a windows button that was passed(since any iButton could be passed) when using the WindowsGui. The main point of all this is simply efficiency. I have to liter the code with checks and casts when it is entirely possible to get the compiler to automate it all. By doing so one can program the concrete class in a much more natural way.
Cannot implicitly convert derived type
interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? Error: class main.WindowsGui interface function 'iButton button(ref iButton button) @property' is not implemented Or by using the commented line: Error: cannot implicitly convert expression (button) of type main.iButton to main.WindowsButton 1. In the first case I override a property using a more derived type. This should work but doesn't. Seems D doens't support covariance properly? 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. Basically, because of the covariance issue I end up having to use a lot of casts. Hopefully theres some simple trick that won't pollute the code to make this work. I guess I could use a templated property with a generic type that is derivable from iButton to make it work? In some sense I can understand the error. If I'm using iGui then I have the option to use any button(since it is generic) but if iGui is a WindowsGui I'm not allowing this. The issue is, that I will have some type of dependency restrictions on the types. e.g., iGui g = new WindowsGui; g.button = new LinuxButton; // ok but not ok!! (should result in an error in some way) Obviously I can cast and check the type and do all that. Just feels like the wrong way to go about it because it requires a lot of casting and polluting the code with checks that in general, should be unnecessary. Again: In the WindowsGui I want to use WindowsButton, not iButton because WindowsGui will never need any other type of button. iButton is too general to use in WindowsGui. (it would be cool if one could do something like class WindowsGui : iGui iButton = WindowsButton // constrains iButton to always be a WindowsButton. Checks/casts are automatically added by compiler when necessary { // use WindowsButton here with proper covariance relations and checks/casts } Anyways, hopefully there is some single trick to get what I'm asking?
Re: Cannot implicitly convert derived type
On 02/21/2014 02:54 PM, Frustrated wrote: interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? Error: class main.WindowsGui interface function 'iButton button(ref iButton button) @property' is not implemented Or by using the commented line: Error: cannot implicitly convert expression (button) of type main.iButton to main.WindowsButton 1. In the first case I override a property using a more derived type. This should work but doesn't. Seems D doens't support covariance properly? 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. Basically, because of the covariance issue I end up having to use a lot of casts. Hopefully theres some simple trick that won't pollute the code to make this work. I guess I could use a templated property with a generic type that is derivable from iButton to make it work? In some sense I can understand the error. If I'm using iGui then I have the option to use any button(since it is generic) but if iGui is a WindowsGui I'm not allowing this. The issue is, that I will have some type of dependency restrictions on the types. e.g., iGui g = new WindowsGui; g.button = new LinuxButton; // ok but not ok!! (should result in an error in some way) Obviously I can cast and check the type and do all that. Just feels like the wrong way to go about it because it requires a lot of casting and polluting the code with checks that in general, should be unnecessary. Again: In the WindowsGui I want to use WindowsButton, not iButton because WindowsGui will never need any other type of button. iButton is too general to use in WindowsGui. (it would be cool if one could do something like class WindowsGui : iGui iButton = WindowsButton // constrains iButton to always be a WindowsButton. Checks/casts are automatically added by compiler when necessary { // use WindowsButton here with proper covariance relations and checks/casts } Anyways, hopefully there is some single trick to get what I'm asking? It should not work because the derived type is requiring more than the interface. iGui requires that the parameter to button() is iButton: @property iButton button(ref iButton button); However, WindowsGui is bringing an extra requirement by asking a more specific iButton: @property WindowsButton button(ref WindowsButton button) Note that there is no problem with the return type because this time the derived type is still returning an iButton because WindowsButton is an iButton. I don't know whether this works for you but I made the actual button a constructor parameter: interface iGui { @property iButton button(); } class WindowsGui : iGui { WindowsButton _button; // The constructor gets the button this(WindowsButton button) { this._button = button; } @property WindowsButton button() { return _button; } } interface iButton { } class WindowsButton : iButton { } void main() { auto w = new WindowsGui(new WindowsButton()); w.button; } Ali
Re: Cannot implicitly convert derived type
On Friday, 21 February 2014 at 23:19:19 UTC, Ali Çehreli wrote: On 02/21/2014 02:54 PM, Frustrated wrote: interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? Error: class main.WindowsGui interface function 'iButton button(ref iButton button) @property' is not implemented Or by using the commented line: Error: cannot implicitly convert expression (button) of type main.iButton to main.WindowsButton 1. In the first case I override a property using a more derived type. This should work but doesn't. Seems D doens't support covariance properly? 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. Basically, because of the covariance issue I end up having to use a lot of casts. Hopefully theres some simple trick that won't pollute the code to make this work. I guess I could use a templated property with a generic type that is derivable from iButton to make it work? In some sense I can understand the error. If I'm using iGui then I have the option to use any button(since it is generic) but if iGui is a WindowsGui I'm not allowing this. The issue is, that I will have some type of dependency restrictions on the types. e.g., iGui g = new WindowsGui; g.button = new LinuxButton; // ok but not ok!! (should result in an error in some way) Obviously I can cast and check the type and do all that. Just feels like the wrong way to go about it because it requires a lot of casting and polluting the code with checks that in general, should be unnecessary. Again: In the WindowsGui I want to use WindowsButton, not iButton because WindowsGui will never need any other type of button. iButton is too general to use in WindowsGui. (it would be cool if one could do something like class WindowsGui : iGui iButton = WindowsButton // constrains iButton to always be a WindowsButton. Checks/casts are automatically added by compiler when necessary { // use WindowsButton here with proper covariance relations and checks/casts } Anyways, hopefully there is some single trick to get what I'm asking? It should not work because the derived type is requiring more than the interface. iGui requires that the parameter to button() is iButton: @property iButton button(ref iButton button); However, WindowsGui is bringing an extra requirement by asking a more specific iButton: @property WindowsButton button(ref WindowsButton button) Note that there is no problem with the return type because this time the derived type is still returning an iButton because WindowsButton is an iButton. I don't know whether this works for you but I made the actual button a constructor parameter: interface iGui { @property iButton button(); } class WindowsGui : iGui { WindowsButton _button; // The constructor gets the button this(WindowsButton button) { this._button = button; } @property WindowsButton button() { return _button; } } interface iButton { } class WindowsButton : iButton { } void main() { auto w = new WindowsGui(new WindowsButton()); w.button; } Ali But what about a setter? Using DI isn't the way to go here. The point that in the windows class, it will only ever use a windows button. This is fine, but because I'm using iGui(programming to interfaces), it causes a problem inside the windows class, which it shouldn't. e.g., if I only had one gui and used one class, then there would never be a problem. Also, it is not a problem of construct, I already have a solution by casting. But casting hides the fact that windowsgui is meant to use only a windows button... which is obvious in the design. Again iGui uses an iButton WindowsGui uses a WindowsButton But when iGui is an actual WindowsGui, it forces WindowsGui to be more generic than it is meant to be. The key piece of information here is that I will only ever use WindowsButtons with WindowsGui... this fact is not general and the reason the compiler throws the error BUT it is always the case in my code(except in errors). I need to inform the compiler that it is always the case and then I can do what I want.
Re: Cannot implicitly convert derived type
On Fri, 21 Feb 2014 17:54:06 -0500, Frustrated c1514...@drdrb.com wrote: interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? What you are trying to do is not legal. e.g.: class RogueButton : iButton { } iGui gui = new WindowsGui; gui.button = new RogueButton; Note that setting gui.button to any iButton is legal, but the derived type REQUIRES a WindowsButton. This would have to be rejected at runtime, because the compile-time type is implicitly convertible. There are two types of variance that are logical, contravariance and covariance. covariance allows you to *return* a more derived type than the base. In other words, this would be legal (assume same iButton/WindowsButton structure): interface iGui { @property iButton button(); } class WindowsGui : iGui { @property WindowsButton button() {...}; } This works, because whenever you return a WindowsButton, you ALSO are returning an iButton. In fact, D supports this. The opposite is contravariance, and that's used on *input* parameters. In this case, the derived method can accept a base of the parameter that the base class defines: interface iGui { void button(WindowsButton); // please humor me, I know you don't want to do this :) } class WindowsGui : iGui { void button(iButton); } This is logically sound, because the actual implementation only requires an iButton. Therefore, passing a WindowsButton into the iGui interface still satisfies that requirement. However, D does NOT support contravariance. 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. This is actually the correct mechanism if you want to use polymorphism. However, in some cases, a templated system may be more advantageous than an interface system. One other possibility is to use overloading -- i.e.: class WindowsGui { @property WindowsButton button(WindowsButton b) { return _button = b;} @property WindowsButton button(iButton b) { if(auto wb = cast(WindowsButton)b) button = wb; else throw new ButtonException; } } This is not really an attractive solution, but it could be easily generated as a mixed-in solution. -Steve
Re: Cannot implicitly convert derived type
Generic? Frustrated c1514...@drdrb.com ... interface iGui { @property iButton button(ref iButton button); } class WindowsGui : iGui { WindowsButton _button; @property WindowsButton button(ref WindowsButton button) //@property iButton button(ref iButton button) { _button = button; return button; } } interface iButton { } class WindowsButton : iButton { } Should this not work? Error: class main.WindowsGui interface function 'iButton button(ref iButton button) @property' is not implemented Or by using the commented line: Error: cannot implicitly convert expression (button) of type main.iButton to main.WindowsButton 1. In the first case I override a property using a more derived type. This should work but doesn't. Seems D doens't support covariance properly? 2. In the second case, I can cast to make everything work. This seems wrong. Hence goto 1. WindowsGui is designed to only work with WindowsButton, say, and I should never have to use iButton in the WindowsGui class unless, maybe, I want to support non-windows buttons in the WindowsGui for some reason. Basically, because of the covariance issue I end up having to use a lot of casts. Hopefully theres some simple trick that won't pollute the code to make this work. I guess I could use a templated property with a generic type that is derivable from iButton to make it work? In some sense I can understand the error. If I'm using iGui then I have the option to use any button(since it is generic) but if iGui is a WindowsGui I'm not allowing this. The issue is, that I will have some type of dependency restrictions on the types. e.g., iGui g = new WindowsGui; g.button = new LinuxButton; // ok but not ok!! (should result in an error in some way) Obviously I can cast and check the type and do all that. Just feels like the wrong way to go about it because it requires a lot of casting and polluting the code with checks that in general, should be unnecessary. Again: In the WindowsGui I want to use WindowsButton, not iButton because WindowsGui will never need any other type of button. iButton is too general to use in WindowsGui. (it would be cool if one could do something like class WindowsGui : iGui iButton = WindowsButton // constrains iButton to always be a WindowsButton. Checks/casts are automatically added by compiler when necessary { // use WindowsButton here with proper covariance relations and checks/casts } Anyways, hopefully there is some single trick to get what I'm asking?
Re: Tools for building a dynamic derived type? I need a push in the right direction.
On Wednesday, 21 August 2013 at 03:37:46 UTC, Kapps wrote: On Tuesday, 20 August 2013 at 18:55:44 UTC, Gary Willoughby wrote: I've been researching ways to accomplish creating a template that creates a special kind of derived type and i think i need a push in the right direction. Take this simple class: class Person { private string _name; private int _age; this(string name, int age) { this._name = name; this._age = age; } public string getName() { return this._name; } public int getAge() { return this._age; } } I want to create a mock of this class which would mean achieving the following: 1). Extend the class 2). Override all public methods to do nothing (or look for enabled methods) 3). Provide a way of dynamically enabling methods with new return values Extending the class is pretty easy and adding methods dynamically looks to be solved (TDPL 12.11.1) but it's the override all public methods to do something different which is beating me. I know it will probably involve mixins and dealing with tuples somewhere along the line but documentation is lacking everywhere i look. std.traits gives me information about a type but using that information is where i need the documentation. e.g. i know the traits methods return tuples but how do you work with these tuples? how to Iterate through them? I seem to always get stuck when trying to iterate through tuples and generate compiler errors. I've taken a look at the std.typecons source especially BlackHole and WhiteHole templates but i get lost. They are almost doing what i want but for abstract methods. The general usage is probably going to be something like this: class Mock(T) : T { // Implementation } auto cat = Mock!Cat(Ginger); // constructors supported. auto person = Mock!Person(); person.addMethod(getName, delegate(){ return Foo; }); person.addMethod(getAge, delegate(){ return 10; }); Any help will be greatly appreciated. AutoImplement (http://dlang.org/phobos/std_typecons.html#.AutoImplement) from std.typecons should do what you want. Instead of implementing only abstract methods, you could make it implement all non-final methods by changing the 'what' template parameter to simply return true (final methods are skipped regardless). Then you could change the 'how' template parameter to return ReturnType!parent.init unless an argument is set in an AA. I can't say I've ever tried this though, so I'm not sure how well it would work in reality. https://github.com/QAston/DMocks-revived may interest you as well. Thanks that gave me a lot to work with! :)
Re: Tools for building a dynamic derived type? I need a push in the right direction.
On 2013-08-20 20:55, Gary Willoughby wrote: The general usage is probably going to be something like this: class Mock(T) : T { // Implementation } auto cat = Mock!Cat(Ginger); // constructors supported. auto person = Mock!Person(); person.addMethod(getName, delegate(){ return Foo; }); person.addMethod(getAge, delegate(){ return 10; }); Any help will be greatly appreciated. I'm not exactly sure how you want it to work, but this is an idea: Create and store an instance of T in Mock. Implement opDispatch in Mock and forward an methods added by addMethod to the delegate. If no delegate exists for that method forward to the instance of T instead. http://dlang.org/operatoroverloading.html#Dispatch -- /Jacob Carlborg
Tools for building a dynamic derived type? I need a push in the right direction.
I've been researching ways to accomplish creating a template that creates a special kind of derived type and i think i need a push in the right direction. Take this simple class: class Person { private string _name; private int _age; this(string name, int age) { this._name = name; this._age = age; } public string getName() { return this._name; } public int getAge() { return this._age; } } I want to create a mock of this class which would mean achieving the following: 1). Extend the class 2). Override all public methods to do nothing (or look for enabled methods) 3). Provide a way of dynamically enabling methods with new return values Extending the class is pretty easy and adding methods dynamically looks to be solved (TDPL 12.11.1) but it's the override all public methods to do something different which is beating me. I know it will probably involve mixins and dealing with tuples somewhere along the line but documentation is lacking everywhere i look. std.traits gives me information about a type but using that information is where i need the documentation. e.g. i know the traits methods return tuples but how do you work with these tuples? how to Iterate through them? I seem to always get stuck when trying to iterate through tuples and generate compiler errors. I've taken a look at the std.typecons source especially BlackHole and WhiteHole templates but i get lost. They are almost doing what i want but for abstract methods. The general usage is probably going to be something like this: class Mock(T) : T { // Implementation } auto cat = Mock!Cat(Ginger); // constructors supported. auto person = Mock!Person(); person.addMethod(getName, delegate(){ return Foo; }); person.addMethod(getAge, delegate(){ return 10; }); Any help will be greatly appreciated.
Re: Tools for building a dynamic derived type? I need a push in the right direction.
On Tuesday, 20 August 2013 at 18:55:44 UTC, Gary Willoughby wrote: I've been researching ways to accomplish creating a template that creates a special kind of derived type and i think i need a push in the right direction. Take this simple class: class Person { private string _name; private int _age; this(string name, int age) { this._name = name; this._age = age; } public string getName() { return this._name; } public int getAge() { return this._age; } } I want to create a mock of this class which would mean achieving the following: 1). Extend the class 2). Override all public methods to do nothing (or look for enabled methods) 3). Provide a way of dynamically enabling methods with new return values Extending the class is pretty easy and adding methods dynamically looks to be solved (TDPL 12.11.1) but it's the override all public methods to do something different which is beating me. I know it will probably involve mixins and dealing with tuples somewhere along the line but documentation is lacking everywhere i look. std.traits gives me information about a type but using that information is where i need the documentation. e.g. i know the traits methods return tuples but how do you work with these tuples? how to Iterate through them? I seem to always get stuck when trying to iterate through tuples and generate compiler errors. I've taken a look at the std.typecons source especially BlackHole and WhiteHole templates but i get lost. They are almost doing what i want but for abstract methods. The general usage is probably going to be something like this: class Mock(T) : T { // Implementation } auto cat = Mock!Cat(Ginger); // constructors supported. auto person = Mock!Person(); person.addMethod(getName, delegate(){ return Foo; }); person.addMethod(getAge, delegate(){ return 10; }); Any help will be greatly appreciated. AutoImplement (http://dlang.org/phobos/std_typecons.html#.AutoImplement) from std.typecons should do what you want. Instead of implementing only abstract methods, you could make it implement all non-final methods by changing the 'what' template parameter to simply return true (final methods are skipped regardless). Then you could change the 'how' template parameter to return ReturnType!parent.init unless an argument is set in an AA. I can't say I've ever tried this though, so I'm not sure how well it would work in reality. https://github.com/QAston/DMocks-revived may interest you as well.