www.digitalmars.com         C & C++   DMDScript  

D - suggestion for template equivalent

reply Chris Friesen <cfriesen nortelnetworks.com> writes:
I remember the generic types in Eiffel as being very convenient.  Perhaps you
could do something equivalent?

An example would be a stack.  A simplistic example would be something like

class Stack : T
{
   int push(T item);
   T pop();
   T[] storage;
   int arrayIndex;
}

Then you could use it as

int main()
{
   Stack:int myStack;
   myStack.push(5);
   int a = myStack.pop
}


To get a bit fancier, you could have some constraints on what the generic type
is

class BinaryTree : T->Sortable
{
  insert(T item);
  ...
}


Then we would have a base virtual Sortable class that has virtual routines that
define what it is to be sortable.  Those routines would then be accessable
within
the BinaryTree methods.

Of course, this really only comes into its own if you can have multiple
inheritance
so that you can inherit from Sortable as well as whatever your real parent is.

Chris

-- 
Chris Friesen                    | MailStop: 043/33/F10  
Nortel Networks                  | work: (613) 765-0557
3500 Carling Avenue              | fax:  (613) 765-2986
Nepean, ON K2H 8E9 Canada        | email: cfriesen nortelnetworks.com
Aug 16 2001
next sibling parent reply "Walter" <walter digitalmars.com> writes:
That's a great idea. But I want to try to make it work without needing
multiple inheritance!

"Chris Friesen" <cfriesen nortelnetworks.com> wrote in message
news:3B7C1DB9.F5C04019 nortelnetworks.com...
 I remember the generic types in Eiffel as being very convenient.  Perhaps

 An example would be a stack.  A simplistic example would be something like

 class Stack : T
 {
    int push(T item);
    T pop();
    T[] storage;
    int arrayIndex;
 }

 Then you could use it as

 int main()
 {
    Stack:int myStack;
    myStack.push(5);
    int a = myStack.pop
 }


 To get a bit fancier, you could have some constraints on what the generic

 class BinaryTree : T->Sortable
 {
   insert(T item);
   ...
 }


 Then we would have a base virtual Sortable class that has virtual routines

 define what it is to be sortable.  Those routines would then be accessable

 the BinaryTree methods.

 Of course, this really only comes into its own if you can have multiple

 so that you can inherit from Sortable as well as whatever your real parent

 Chris

 --
 Chris Friesen                    | MailStop: 043/33/F10
 Nortel Networks                  | work: (613) 765-0557
 3500 Carling Avenue              | fax:  (613) 765-2986
 Nepean, ON K2H 8E9 Canada        | email: cfriesen nortelnetworks.com

Aug 16 2001
next sibling parent reply Michael Lindner <mikell optonline.net> writes:
Walter wrote:
 
 That's a great idea. But I want to try to make it work without needing
 multiple inheritance!

Agreed. Have you looked at functional programming languages at all? There are some nice typing systems that do "template-y" things much better than templates. Consider the pseudocode: min(a, b) { if (a <= b) { return a; } return b; } If the actual parameters passed to min() are of types that can be compared using <=, why should the developer have to specify what the types are; the compiler can infer them. In fact, there was a nice article mentioned on /. a few months ago about such things - of course I can't find it now.
Aug 16 2001
parent reply Chris Friesen <chris_friesen sympatico.ca> writes:
Michael Lindner wrote:

 min(a, b)
 {
         if (a <= b) {
                 return a;
         }
         return b;
 }
 
 If the actual parameters passed to min() are of types that can be
 compared using <=, why should the developer have to specify what the
 types are; the compiler can infer them.

This would definately be cool. The compiler would have to check at runtime that all the operations used in a given function are supported by anything that calls that function. This may be time-consuming. Also, some thought must be given on how to make this work with pre-compiled code libraries. You'd almost have to compile libraries to some intermediate form and then do the final specialization later. Chris
Aug 16 2001
next sibling parent Christophe de Dinechin <descubes earthlink.net> writes:
As I indicated in a different thread, a good model used in the LX programming
language is to have real generic types, which make declarations that use them
generic in turn. In addition, you can also put validation on said generic types.

    generic type ordered
    {
        // Validation code for the generic type
        ordered A, B;
        bool C = A <= B;
    }
    ordered min(ordered A; ordered B) {
        if (A <= B) { return A; } else { return B; }
    }

The LX syntax for this is basically the same thing without the brackets and
parentheses :-)


Christophe


Chris Friesen wrote:

 Michael Lindner wrote:

 min(a, b)
 {
         if (a <= b) {
                 return a;
         }
         return b;
 }

 If the actual parameters passed to min() are of types that can be
 compared using <=, why should the developer have to specify what the
 types are; the compiler can infer them.

This would definately be cool. The compiler would have to check at runtime that all the operations used in a given function are supported by anything that calls that function. This may be time-consuming. Also, some thought must be given on how to make this work with pre-compiled code libraries. You'd almost have to compile libraries to some intermediate form and then do the final specialization later. Chris

Aug 16 2001
prev sibling parent Michael Lindner <mikell optonline.net> writes:
Chris Friesen wrote:
 
 Michael Lindner wrote:
 
 ...why should the developer have to specify what the
 types are; the compiler can infer them.

This would definately be cool. The compiler would have to check at runtime that all the operations used in a given function are supported by anything that calls that function. This may be time-consuming. Also, some thought must be given on how to make this work with pre-compiled code libraries. You'd almost have to compile libraries to some intermediate form and then do the final specialization later.

Actually, I was thinking of a more modest version in which the compiler could do the type determination at compile/link time or produce an error. As for libraries, yes, you do need an intermediate form in the case of generic code if the compiler is to specialize at link time. Note that this requires generic type names as mentioned by Christophe in his response. I simply left them out for brevity.
Aug 17 2001
prev sibling parent reply "Sheldon Simms" <sheldon semanticedge.com> writes:
Why do you need multiple inheritance? Why can't Sortable just
be an interface?

Im Artikel <9lhh1h$50n$1 digitaldaemon.com> schrieb "Walter"
<walter digitalmars.com>:

 That's a great idea. But I want to try to make it work without needing
 multiple inheritance!
 
 "Chris Friesen" <cfriesen nortelnetworks.com> wrote in message
 news:3B7C1DB9.F5C04019 nortelnetworks.com...
 I remember the generic types in Eiffel as being very convenient. 
 Perhaps

 An example would be a stack.  A simplistic example would be something
 like

 class Stack : T
 {
    int push(T item);
    T pop();
    T[] storage;
    int arrayIndex;
 }

 Then you could use it as

 int main()
 {
    Stack:int myStack;
    myStack.push(5);
    int a = myStack.pop
 }


 To get a bit fancier, you could have some constraints on what the
 generic

 class BinaryTree : T->Sortable
 {
   insert(T item);
   ...
 }


 Then we would have a base virtual Sortable class that has virtual
 routines

 define what it is to be sortable.  Those routines would then be
 accessable

 the BinaryTree methods.

 Of course, this really only comes into its own if you can have multiple

 so that you can inherit from Sortable as well as whatever your real
 parent

 Chris

 --
 Chris Friesen                    | MailStop: 043/33/F10 Nortel Networks
                  | work: (613) 765-0557 3500 Carling Avenue            
  | fax:  (613) 765-2986 Nepean, ON K2H 8E9 Canada        | email:
 cfriesen nortelnetworks.com


-- Sheldon Simms / sheldon semanticedge.com
Aug 17 2001
next sibling parent reply Chris Friesen <cfriesen nortelnetworks.com> writes:
Sheldon Simms wrote:
 
 Why do you need multiple inheritance? Why can't Sortable just
 be an interface?

I suppose it could. I was taking my example from Eiffel where multiple inheritance is easy and useful, but there's no reason why we need to make it identical. So the interface would describe the methods which must be present in a class but then you can add more, right? (Its been a while since I've used interfaces.) Chris -- Chris Friesen | MailStop: 043/33/F10 Nortel Networks | work: (613) 765-0557 3500 Carling Avenue | fax: (613) 765-2986 Nepean, ON K2H 8E9 Canada | email: cfriesen nortelnetworks.com
Aug 17 2001
parent "Sheldon Simms" <sheldon semanticedge.com> writes:
Im Artikel <3B7D16D0.29DCA80B nortelnetworks.com> schrieb "Chris Friesen"
<cfriesen nortelnetworks.com>:

 Sheldon Simms wrote:
 
 Why do you need multiple inheritance? Why can't Sortable just be an
 interface?

I suppose it could. I was taking my example from Eiffel where multiple inheritance is easy and useful, but there's no reason why we need to make it identical. So the interface would describe the methods which must be present in a class but then you can add more, right? (Its been a while since I've used interfaces.)

Yes. Personally I don't see why multiple inheritance should be disallowed (*), but I just wanted to point out that your example doesn't require it. (*) I do understand why multiple inheritance can be problematic but I think that only allowing inheritance trees (arbitrary DAGs not allowed) solves most, if not all, of the problems. Java has interfaces instead of multiple inheritance and it also has a lot of redundant "utility classes" that implement interfaces to make up for it. -- Sheldon Simms / sheldon semanticedge.com
Aug 17 2001
prev sibling parent Charles Hixson <charleshixsn earthlink.net> writes:
Sheldon Simms wrote:
 Why do you need multiple inheritance? Why can't Sortable just
 be an interface?
 
 ...
 

If you're going to define interfaces, may I suggest that they be ex post facto. I.e., an interface is a description of a set of calls and objects. Anything that possesses those calls and variables automatically implements the interface, whether it knows it or not. This would allow one to look at a bunch of existing code, abstract a commonality, and then just define a matching interface, which could then be called on all objects that match that code. I don't know how hard this would be, but it seems to me that it could be quite useful.
Aug 17 2001
prev sibling next sibling parent reply Christophe de Dinechin <descubes earthlink.net> writes:
Chris Friesen wrote:

 I remember the generic types in Eiffel as being very convenient.  Perhaps you
could do something equivalent?

Eiffel and Ada don't have implicit instantiation. That means that you can't implement the STL (or most generic libraries, like Blitz++) in Eiffel or Ada. According to the authors. Christophe
Aug 17 2001
next sibling parent reply Chris Friesen <cfriesen nortelnetworks.com> writes:
Christophe de Dinechin wrote:
 
 Chris Friesen wrote:
 
 I remember the generic types in Eiffel as being very convenient.  Perhaps you
could do something equivalent?

Eiffel and Ada don't have implicit instantiation. That means that you can't implement the STL (or most generic libraries, like Blitz++) in Eiffel or Ada. According to the authors.

I don't know enough about how the STL is coded to comment on that part of it, but I do remember it being much simpler to create generic objects in Eiffel than in C++. Stack, array, list, queue, binary tree, etc...all become extremely simple to code. Chris -- Chris Friesen | MailStop: 043/33/F10 Nortel Networks | work: (613) 765-0557 3500 Carling Avenue | fax: (613) 765-2986 Nepean, ON K2H 8E9 Canada | email: cfriesen nortelnetworks.com
Aug 17 2001
parent reply Christophe de Dinechin <descubes earthlink.net> writes:
The STL is mostly about algorithms, more even than about types. The fact that
the Eiffel syntax is superficially
easier than C++ (not difficult, template<> was one of the biggest mistake in
C++ history ;-) doesn't contradict the
fact that there are things you can't do in Eiffel.

E.g. in Eiffel, it's (almost?) impossible to create a "traits" class and
automatically deduce information about the
types you are being instantiated with.


Christophe

Chris Friesen wrote:

 Christophe de Dinechin wrote:
 Chris Friesen wrote:

 I remember the generic types in Eiffel as being very convenient.  Perhaps you
could do something equivalent?

Eiffel and Ada don't have implicit instantiation. That means that you can't implement the STL (or most generic libraries, like Blitz++) in Eiffel or Ada. According to the authors.

I don't know enough about how the STL is coded to comment on that part of it, but I do remember it being much simpler to create generic objects in Eiffel than in C++. Stack, array, list, queue, binary tree, etc...all become extremely simple to code. Chris -- Chris Friesen | MailStop: 043/33/F10 Nortel Networks | work: (613) 765-0557 3500 Carling Avenue | fax: (613) 765-2986 Nepean, ON K2H 8E9 Canada | email: cfriesen nortelnetworks.com

Aug 17 2001
parent "Walter" <walter digitalmars.com> writes:
Christophe de Dinechin wrote in message <3B7E0470.DB2EB31A earthlink.net>...
E.g. in Eiffel, it's (almost?) impossible to create a "traits" class and

types you are being instantiated with.

Like what?
Aug 25 2001
prev sibling parent "Walter" <walter digitalmars.com> writes:
I'm not sure implict instantiation is a good idea, even if it leads to code
bloat.

Christophe de Dinechin wrote in message <3B7D2E35.537552AB earthlink.net>...
Chris Friesen wrote:

 I remember the generic types in Eiffel as being very convenient.  Perhaps


Eiffel and Ada don't have implicit instantiation. That means that you can't

libraries, like Blitz++) in Eiffel or Ada. According to the authors.


Christophe

Aug 25 2001
prev sibling parent "Brent Schartung" <bschartung home.com> writes:
Two things--first, I agree that inheritting from multiple classes gets very
messy.  What if only one base class is allowed, but you can 'implement' as
many interfaces as desired?  Seems a little lop-sided, but it keeps us clear
of the common problems of MI, and allows a type to be i.e. Comparable and
Settable in one step.

Second, I wanted to contribute my 0.02USD on templates/GP.  I think they are
totally critical to have in a modern language, and I think the way C++ does
them is necissary, in that there should be named types.  Consider:

generic(class X, class Y)
class Map
{
    Y operator[] (X) { ... }
}

I'm not sure how you'd accomplish making an L-value out of i.e.
mymap[mykey].  Also, I know there are already assoc. arrays, but I think the
example is still a good one.

Oops, I brought in an overloaded operator!!  Oh well, I guess that reveals
my feelings about those as well.  c( :
This is a feature/ability I would certainly expect from any modern C-based
language.

 - Brent
Aug 17 2001