Newsgroups: comp.lang.c++,comp.lang.smalltalk,comp.object
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!hookup!usc!howland.reston.ans.net!pipex!uknet!comlab.ox.ac.uk!sable.ox.ac.uk!lady0065
From: lady0065@sable.ox.ac.uk (David Hopwood)
Subject: Templates (was Re: C++ Productivity)
Message-ID: <1995Feb15.024720.516@inca.comlab.ox.ac.uk>
Followup-To: comp.lang.c++,comp.object
Sender: david.hopwood@lmh.oxford.ac.uk
Organization: Oxford University, England
References: <jim.fleming.84.00133AB6@bytes.com> <19950127.093932.289762.NETNEWS@UICVM.UIC.EDU> <DJOHNSON.95Jan28152443@arnold.ucsd.e <19950209.161709.472183.NETNEWS@uicvm.uic.edu>
Date: Wed, 15 Feb 95 02:47:20 GMT
Lines: 120
Xref: glinda.oz.cs.cmu.edu comp.lang.c++:112841 comp.lang.smalltalk:20854 comp.object:26760

[comp.lang.smalltalk removed from follow-ups]

In article <19950209.161709.472183.NETNEWS@uicvm.uic.edu>,
David Hanley <dhanley@matisse.eecs.uic.edu> wrote:

>David Chase (chase@michaelcenterline.com) wrote:

[...]
>: Templates, though better than macros, are still a crock
>: as implemented in C++.
>
>That's an opinion.  As stated it's merely an unjustified
>attack.
>
>: They should probably be
>: parameterized in the style of (I think) ML functors.
>
>Again, an opinion.

What's wrong with opinions? Anyway, David Chase mentions some of the problems
below, so it's hardly 'an unjustified attack'.

>:    (provides explicit, checked documentation of how
>:    a template is supposed to behave, for starters,
>:    and earlier detection of bugs.)
>
>And also not allow templates to be as flexible as they are
>now in C++.

I'd like to see an example of something that can be done using templates,
but not in an OO language that implements Milner polymorphism (assuming
you've used one, that is).

Here are the main problems with templates:

1. Code bloat

   The stock reply to this is that it's mainly a problem with current
   compiler implementations. OTOH since it doesn't occur in similar
   languages with genericity (Ada9X, Eiffel), it's hard not to lay some of
   the blame on the C++ language itself.

   (The main cause is that C++ relies on knowing the positions and types of
   instance variables statically, which means recompiling the template for each
   combination of type parameters that changes these. The problem isn't
   going to go away easily).

2. Can't separately compile a template definition and its instantiation.

   Since you need to recompile the template in order to use it, you can't
   put it in a separately compiled module, and also, you can't dynamically
   link template code with its users (this completely rules out discovering
   new types at run-time, if that wasn't already ruled out in C++).

3. Can't leave type variables abstract when inheriting from a template.

   For example:

   type Foo {T}
       method1: T

   type Bar {T}
       method1: T
       method2: T

   Clearly, Bar {T} is a subtype of Foo {T}. It doesn't matter what T is;
   the type checker shouldn't need to know. But C++ won't let you inherit
   from Foo <T>, so you can't model this kind of relationship
   (at least, not without hacking around with (void *)s and casts).

   This isn't just a theoretical curiosity (see point 4 below for a
   concrete example). I frequently see problems posted in this group
   that could be solved fairly easily using this technique.

4. No support for constrained genericity

   Very often you want a constraint on a type variable, because you need to
   know some things about it, even though you don't know its exact type.

   For example, what is the type of a bag implemented as an ordered list?
   I'd like to be able to write:

   type Comparable-to {T}
       lt (other: T): Boolean
           post Result => not eq (other)
       eq (other: T): Boolean
           post Result => not lt (other)

   type OrderedList {T _< Comparable-to {T}}
       subtypes Bag {T}

   In C++, there are two problems:
   - I cannot inherit from Bag <T> (see point 3), and
   - I cannot express the fact that the elements must all be comparable to
     each other.

   I could use:

       class Comparable
           { public: virtual bool lt (Comparable) = 0; ... };

       class OrderedList: Bag <Comparable>
           ...

   but then I can only extract Comparables from the list; I can't get at their
   real (more specific) type.
   If I use:

       template <class T>
       class OrderedList <T>: Bag <??>
           ...

   then in the implementation of OrderedList or its subclasses, I will have
   to use the methods lt and eq on objects of an arbitrary type T. In
   practice that means I have to use a cast, and I gain very little type
   safety over the equivalent class in an untyped language.


David Hopwood
david.hopwood@lmh.oxford.ac.uk
