Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
June 12, 2012 Template Interface | ||||
---|---|---|---|---|
| ||||
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: 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 |
June 13, 2012 Re: Template Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nathan M. Swan | 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 |
June 13, 2012 Re: Template Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | 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 |
June 13, 2012 Re: Template Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nathan M. Swan | 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 |
June 13, 2012 Re: Template Interface | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | 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 |
Copyright © 1999-2021 by the D Language Foundation