Re: template interface and delegates
On Tuesday, 1 April 2014 at 19:55:05 UTC, Steven Schveighoffer wrote: On Tue, 01 Apr 2014 15:47:42 -0400, anonymous n...@trash-mail.com wrote: Is this bug allready reported? or can somebody who has a deeper insight to this report it? I don't know. I think you should report it. If it's already reported, someone will close it as a duplicate -Steve I filed it. https://d.puremagic.com/issues/show_bug.cgi?id=12508 Kenji Hara
Re: template interface and delegates
Is this bug allready reported? or can somebody who has a deeper insight to this report it? On Tuesday, 1 April 2014 at 05:51:46 UTC, anonymous wrote: Ok, thought i did something wrong or got some wrong idea how it should work.
Re: template interface and delegates
On Tue, 01 Apr 2014 15:47:42 -0400, anonymous n...@trash-mail.com wrote: Is this bug allready reported? or can somebody who has a deeper insight to this report it? I don't know. I think you should report it. If it's already reported, someone will close it as a duplicate -Steve
Re: template interface and delegates
On Mon, 31 Mar 2014 18:58:30 +, anonymous wrote: Hi, I'm new to D and played a bit with templates and delegates. Now i discovered some behaviore that i don't understand. Can somebody explain me why i get two different outputs? import std.stdio; interface A(T){ bool GetBool(); T getT(); } class C:A!(double){ override bool GetBool(){ return false; } override double getT(){ return 1; } } void mwriteln(T)( A!T delegate() dg){ writeln(dg().getT()); } void main() { auto c = new C(); writeln(c.getT()); mwriteln!double({return new C();}); } Looks like a bug. Here's a cleaned-up test case: --- interface A(T) { T getT(); } class C : A!double { double getT(){ return 1; } } void mwriteln(T)(A!T delegate() dg) { import std.stdio; auto a = dg(); writeln(Checkpoint 1); assert(a !is null); writeln(a); writeln(Checkpoint 2); } void main() { import std.traits; static assert(isImplicitlyConvertible!(C, A!double)); mwriteln!double({return new C();}); } --- Backtrace: --- Program received signal SIGSEGV, Segmentation fault. #0 0x0042ac8c in _d_interface_cast () #1 0x00427ec6 in std.format.__T11formatValueTS3std5stdio4File17LockingTextWriterTC4test8__T1ATdZ1ATaZ.formatValue () () #2 0x00427e23 in std.format.__T13formatGenericTS3std5stdio4File17LockingTextWriterTC4test8__T1ATdZ1ATaZ.formatGeneric () () #3 0x00427d29 in std.format.__T14formattedWriteTS3std5stdio4File17LockingTextWriterTaTC4test8__T1ATdZ1AZ.formattedWrite () () #4 0x00427871 in std.stdio.File.__T5writeTC4test8__T1ATdZ1ATaZ.write() () #5 0x004277d5 in std.stdio.__T7writelnTC4test8__T1ATdZ1AZ.writeln () () #6 0x0042771f in test.__T8mwritelnTdZ.mwriteln() () #7 0x004276a9 in D main () #8 0x0042b61c in rt.dmain2._d_run_main() () #9 0x0042b576 in rt.dmain2._d_run_main() () #10 0x0042b5dc in rt.dmain2._d_run_main() () #11 0x0042b576 in rt.dmain2._d_run_main() () #12 0x0042b4f7 in _d_run_main () #13 0x00429c5f in main () ---
Re: template interface and delegates
On Mon, 31 Mar 2014 14:58:30 -0400, anonymous n...@trash-mail.com wrote: Hi, I'm new to D and played a bit with templates and delegates. Now i discovered some behaviore that i don't understand. Can somebody explain me why i get two different outputs? import std.stdio; interface A(T){ bool GetBool(); T getT(); } class C:A!(double){ override bool GetBool(){ return false; } override double getT(){ return 1; } } void mwriteln(T)( A!T delegate() dg){ writeln(dg().getT()); } void main() { auto c = new C(); writeln(c.getT()); mwriteln!double({return new C();}); } This is definitely a bug. Reduced case: import std.stdio; interface A{ void foo(); } class C:A{ override void foo(){ writeln(here); } } void x( A delegate() dg){ dg().foo(); } void main() { A c = new C; c.foo(); // prints here x({A a = new C; return a;}); // prints here x({return new C;}); // does not print } This is really an issue with delegate return type inferrence not working properly. -Steve
Re: template interface and delegates
Ok, thought i did something wrong or got some wrong idea how it should work.
Re: Template Interface
On 12/06/2012 18:56, Nathan M. Swan wrote: When writing a generic function which takes an unknown type, the signature is written like so: void fun(L)(L l) if (isList!L); While writing a generic interface is written like so: template isList(L) { enum bool isList = is(typeof( (inout int _dummy=0) The above line seems unnecessary as we have {no_argument_lambda;} syntax - or is there a special reason why? { L l; if (l.nil) {} auto e = l.car; l = l.cdr; )); } BTW I think Walter said we could have enum template syntax, which would improve the above a little: enum bool isList(L) = is(typeof(... This doesn't seem very intuitive to me. OOP languages handle this with interfaces, but in D for things like ranges we often use structs, making it incompatible with the current interface. A possible enhancement is to allow structs to implement interfaces (but this has a runtime cost, unlike using templates). I'm suggesting something like a template interface, which is compatible with all types, and serves as a placeholder for any type for which the body compiles: [snip] void fun(List!string l); Maybe: void fun(L:IList)(L l); template interface IList(E) { template interface List(E) : List { List!E l; E e = l.car; } It makes writing generic code much cleaner. I'm not quite sure what the ': List' part means - is it just to declare that the List struct is used below? Maybe it would be better for the template interface body to contain method signatures/members rather than code? I think it might be an interesting idea, but it would probably need to be significantly better than the current way with constraints to get adopted by D. Nick
Re: Template Interface
On Wednesday, 13 June 2012 at 13:34:25 UTC, Nick Treleaven wrote: On 12/06/2012 18:56, Nathan M. Swan wrote: When writing a generic function which takes an unknown type, the signature is written like so: void fun(L)(L l) if (isList!L); While writing a generic interface is written like so: template isList(L) { enum bool isList = is(typeof( (inout int _dummy=0) The above line seems unnecessary as we have {no_argument_lambda;} syntax - or is there a special reason why? I'm not sure, I just found it throughout std.range { L l; if (l.nil) {} auto e = l.car; l = l.cdr; )); } BTW I think Walter said we could have enum template syntax, which would improve the above a little: enum bool isList(L) = is(typeof(... This doesn't seem very intuitive to me. OOP languages handle this with interfaces, but in D for things like ranges we often use structs, making it incompatible with the current interface. A possible enhancement is to allow structs to implement interfaces (but this has a runtime cost, unlike using templates). I'm suggesting something like a template interface, which is compatible with all types, and serves as a placeholder for any type for which the body compiles: [snip] void fun(List!string l); Maybe: void fun(L:IList)(L l); template interface IList(E) { template interface List(E) : List { List!E l; E e = l.car; } It makes writing generic code much cleaner. I'm not quite sure what the ': List' part means - is it just to declare that the List struct is used below? That List!E inherits from list. I'm not sure this is necessary or not. Maybe it would be better for the template interface body to contain method signatures/members rather than code? I considered that, but somethings aren't just methods. A range's empty could be enum empty = false, bool empty, or @property bool empty. The whole point of the range interface is syntactic similarity, though the semantics might be different. I think it might be an interesting idea, but it would probably need to be significantly better than the current way with constraints to get adopted by D. Nick Yea, this isn't a specific proposal, just an idea put out there. NMS
Re: Template Interface
On Tuesday, 12 June 2012 at 17:56:26 UTC, Nathan M. Swan wrote: When writing a generic function which takes an unknown type, the signature is written like so: void fun(L)(L l) if (isList!L); While writing a generic interface is written like so: template isList(L) { enum bool isList = is(typeof( (inout int _dummy=0) { L l; if (l.nil) {} auto e = l.car; l = l.cdr; )); } This doesn't seem very intuitive to me. OOP languages handle this with interfaces, but in D for things like ranges we often use structs, making it incompatible with the current interface. I'm suggesting something like a template interface, which is compatible with all types, and serves as a placeholder for any type for which the body compiles: What you're looking for were also proposed for C++; they were called concepts void fun(List l); template interface List { List l; if (l.nil) {} auto e = l.car; l = l.cdr; } It might be have parameters: void fun(List!string l); template interface List(E) : List { List!E l; E e = l.car; } It makes writing generic code much cleaner. Thoughts? NMS
Re: Template Interface
On 2012-06-13 15:34, Nick Treleaven wrote: Maybe it would be better for the template interface body to contain method signatures/members rather than code? I would prefer that. I think it might be an interesting idea, but it would probably need to be significantly better than the current way with constraints to get adopted by D. In general I like the idea. -- /Jacob Carlborg