digitalmars.D - Templated interfaces
- James Dunne (104/104) Sep 12 2005 This proposition might be a bit long, but I think it's worth a serious l...
- Derek Parnell (9/14) Sep 12 2005 Seems sensible and a useful simplification. It gave me a sort of "oh yea...
- Ben Hinkle (2/20) Sep 12 2005 hmm. works for me in dmd.130 out of the box (well, supply a Remove body ...
- Derek Parnell (25/51) Sep 12 2005 Well how about that! It's not documented so I assumed it wasn't
- James Dunne (13/67) Sep 12 2005 I have successfully tested such code and it works. I just naturally
- Sean Kelly (5/9) Sep 12 2005 Yup. Templates in D are very consistent. The only thing I occasionally...
- Walter Bright (3/4) Sep 14 2005 Ouch!
- Walter Bright (9/13) Sep 14 2005 What's kinda neat about it is that the syntax is exactly what you expect...
- James Dunne (7/36) Sep 12 2005 No, but I think I might've. =P Feeling a bit sheepish now... I'll do
This proposition might be a bit long, but I think it's worth a serious look. PROPOSITION: In a world of templated and generic programming, why hasn't the concept of the Interface been given much attention? I often find myself wanting a templated container of elements, inheriting an interface of function names to call. Anyone who has attempted to write such a container in D could be considered a proposition to extend D's interface concept to allow for templating function parameter types and return value types. EXAMPLE CASE: I want an interface to define a set of functions for inherited classes to call, but don't want to force the container type in the interface function declarations. As far as I know, this is not possible with D, using interfaces at least. One must create an abstract base class for types of items to store in containers inheriting from the interface and define the interface's functions on that base class. Some code might help: /* A base object to store */ public abstract IBaseObject { } /* My base interface for collections which can store IBaseObjects */ public interface IBaseObjectCollection { public IBaseObject Add(IBaseObject x); public IBaseObject opIndex(int i); . . . } public class Collection1(ItemType : IBaseObject) : IBaseObjectCollection { ItemType[] list; public IBaseObject Add(IBaseObject x) { if (typeid(x) != typeid(ItemType)) throw new Exception("Wrong type!"); list ~= cast(ItemType)x; } public IBaseObject opIndex(int i) { return list[i]; } } public class Collection2(ItemType : IBaseObject) : IBaseObjectCollection { ItemType[] list; public IBaseObject Add(IBaseObject x) { if (typeid(x) != typeid(ItemType)) throw new Exception("Wrong type!"); list ~= cast(ItemType)x; // duplicated for sake of difference from Collection1 list ~= cast(ItemType)x; } public IBaseObject opIndex(int i) { return list[i]; } } FINDINGS/PROBLEMS ON/WITH EXAMPLE CASE: I have two classes inheriting from the IBaseObjectCollection interface, which means that the functions defined in the classes may only use the type IBaseObject, and not the ItemType object that the user actually wants to store. With the template parameter specialization, ItemType is guaranteed to be inheriting IBaseObject, but casting (both implicit and explicit) is needed. Also, the point of the templated collection is defeated as a strongly-typed collection. From the user's perspective, the collection is perceived to be able to store any object inheriting IBaseObject, but this is misleading because the collection uses a dynamic array of type ItemType internally. Finally, the templated collection may not store basic D types, like int, short, char[], etc. because they do not inherit from any class and cannot be made to be. (At least in the sense of inheriting the collection from an interface, as is the case) SOLUTION: What is really needed is *templated interfaces*. This will truly give interfaces the power they need to do their job right. The interface will be defined more loosely, sort of as a guaranteed naming convention that all inheriting classes must follow. Then, true strongly-typed collections can be defined and can in turn also be abstracted more. For a code demonstration of this templated interface: public interface ICollection(itemType) { public itemType Add(itemType x); public itemType Remove(int i); public itemType opIndex(int i); } public class IntegerCollection : ICollection!(int) { int[] list; public int Add(int x) { list ~= x; } public int Remove(int i) { ... } public int opIndex(int i) { return list[i]; } } Isn't that much simpler and cleaner? This can be a very powerful feature for tying together concept-related, but /not necessarily/ type-related, classes and for enforcing strong naming conventions and general design patterns. -- Regards, James Dunne
Sep 12 2005
On Mon, 12 Sep 2005 20:05:13 -0500, James Dunne wrote:This proposition might be a bit long, but I think it's worth a serious look. PROPOSITION:[snip]to extend D's interface concept to allow for templating function parameter types and return value types.Seems sensible and a useful simplification. It gave me a sort of "oh yeah, of course" reaction accompanied with a slap to one's forehead. -- Derek (skype: derek.j.parnell) Melbourne, Australia 13/09/2005 11:37:36 AM
Sep 12 2005
For a code demonstration of this templated interface: public interface ICollection(itemType) { public itemType Add(itemType x); public itemType Remove(int i); public itemType opIndex(int i); } public class IntegerCollection : ICollection!(int) { int[] list; public int Add(int x) { list ~= x; } public int Remove(int i) { ... } public int opIndex(int i) { return list[i]; } }hmm. works for me in dmd.130 out of the box (well, supply a Remove body and a main). Am I missing something?
Sep 12 2005
On Mon, 12 Sep 2005 21:44:41 -0400, Ben Hinkle wrote:Well how about that! It's not documented so I assumed it wasn't implemented. I also tried other undocumented templating ideas and discovered that you can do templated structs too. struct SS(Type) { Type[] list; void opCall(Type x, int y) { list.length = y; list[] = x; } } void main() { SS!(int) A; SS!(real) B; A(3, 10); B(3.1472L, 5); } -- Derek (skype: derek.j.parnell) Melbourne, Australia 13/09/2005 12:04:22 PMFor a code demonstration of this templated interface: public interface ICollection(itemType) { public itemType Add(itemType x); public itemType Remove(int i); public itemType opIndex(int i); } public class IntegerCollection : ICollection!(int) { int[] list; public int Add(int x) { list ~= x; } public int Remove(int i) { ... } public int opIndex(int i) { return list[i]; } }hmm. works for me in dmd.130 out of the box (well, supply a Remove body and a main). Am I missing something?
Sep 12 2005
Derek Parnell wrote:On Mon, 12 Sep 2005 21:44:41 -0400, Ben Hinkle wrote:I have successfully tested such code and it works. I just naturally assumed it wouldn't when I wrote up the proposal. For that, I am slightly embarassed. It seems there's some general templating shorthand defined for all aggregate types (classes, interfaces, structs). Any hey - wow! That was the quickest acceptance and implementation of a proposal I've ever seen!! =P This is awesome!! Why isn't this documented?? I'm so unbelievably happy right now. -- Regards, James DunneWell how about that! It's not documented so I assumed it wasn't implemented. I also tried other undocumented templating ideas and discovered that you can do templated structs too. struct SS(Type) { Type[] list; void opCall(Type x, int y) { list.length = y; list[] = x; } } void main() { SS!(int) A; SS!(real) B; A(3, 10); B(3.1472L, 5); }For a code demonstration of this templated interface: public interface ICollection(itemType) { public itemType Add(itemType x); public itemType Remove(int i); public itemType opIndex(int i); } public class IntegerCollection : ICollection!(int) { int[] list; public int Add(int x) { list ~= x; } public int Remove(int i) { ... } public int opIndex(int i) { return list[i]; } }hmm. works for me in dmd.130 out of the box (well, supply a Remove body and a main). Am I missing something?
Sep 12 2005
In article <dg5df7$b0q$1 digitaldaemon.com>, James Dunne says...It seems there's some general templating shorthand defined for all aggregate types (classes, interfaces, structs).Yup. Templates in D are very consistent. The only thing I occasionally miss is a shorthand for template functions.This is awesome!! Why isn't this documented?? I'm so unbelievably happy right now.The first rule of D is that you don't document D ;-) Sean
Sep 12 2005
"Sean Kelly" <sean f4.ca> wrote in message news:dg5koe$gdh$1 digitaldaemon.com...The first rule of D is that you don't document D ;-)Ouch!
Sep 14 2005
"James Dunne" <james.jdunne gmail.com> wrote in message news:dg5df7$b0q$1 digitaldaemon.com...Any hey - wow! That was the quickest acceptance and implementation of a proposal I've ever seen!! =PWhat's kinda neat about it is that the syntax is exactly what you expected it to be.This is awesome!! Why isn't this documented??Because writing documentation is not one of my favorite activities and I tend to avoid it <g>. I recently did a quick look at the Phobos documentation, and it stinks. The best solution I can think of is to proceed with writing Ddoc, which should cut the effort for documenting the library by half or more. This won't help with the language spec, though.I'm so unbelievably happy right now.
Sep 14 2005
Ben Hinkle wrote:No, but I think I might've. =P Feeling a bit sheepish now... I'll do some tests and check the front-end code to ensure this is really implemented yet undocumented. -- Regards, James DunneFor a code demonstration of this templated interface: public interface ICollection(itemType) { public itemType Add(itemType x); public itemType Remove(int i); public itemType opIndex(int i); } public class IntegerCollection : ICollection!(int) { int[] list; public int Add(int x) { list ~= x; } public int Remove(int i) { ... } public int opIndex(int i) { return list[i]; } }hmm. works for me in dmd.130 out of the box (well, supply a Remove body and a main). Am I missing something?
Sep 12 2005