🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

7 total messages Started by Roman Lechtchinsky Tue, 16 Apr 1996 22:30
Better template syntax?
#4067
Author: Roman Lechtchinsky
Date: Tue, 16 Apr 1996 22:30
36 lines
2135 bytes
Hi, 

sorry for being curious but I'm only human... My question is: when declaring 
templates, why isn't it required to declare what one expects of the 
template's parameters? Let's create a template function:

template<class T> bool equal( const T& t1, const T& t2 )
{
  return t1==t2;
}

Now, personally I would prefer to write something like:

template<class T { bool operator==( const T& t ) const; }> ...

This would make both the development and the use of templates much easier ( 
to me, at least ). No need for writing lots of comments explaining what 
interface T should provide; no need for reading the source code of "equal" if 
it is part of a third-party library with poor interface documentation; no 
need to worry about implicit conversions - sounds like a lot of advantages. 
Then again, I imagine that this approach would make templates more efficient 
and easier to implement.
Now, what I'd like to know is if something like this has been considered and 
rejected ( and why ) and what other people think about it ( would this be 
really easier to use in practice; do you consider it more elegant than the 
current approach ). Thanks in advance.

Bye

Roman
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Re: Better template syntax?
#4069
Author: Matt Austern
Date: Wed, 17 Apr 1996 08:47
63 lines
3487 bytes
In article <31741E6C.53CA@cs.tu-berlin.de> Roman Lechtchinsky
<wolfro@cs.tu-berlin.de> writes:

> sorry for being curious but I'm only human... My question is: when declaring
> templates, why isn't it required to declare what one expects of the 
> template's parameters? Let's create a template function:
> 
> template<class T> bool equal( const T& t1, const T& t2 )
> {
>   return t1==t2;
> }
> 
> Now, personally I would prefer to write something like:
> 
> template<class T { bool operator==( const T& t ) const; }> ...

Specifying something like this correctly turns out to be extremely
difficult: it's very hard to come up with syntax that neither
overspecifies nor underspecifies the constraints.  In this particular
case, for example: do you really care whether operator== takes a const
T&, as opposed to a T?  Does it matter that it returns bool, instead
of something (like int) that is freely convertable to bool?  Does it
matter whether this is T::operator==(T), or ::operator==(T,T), or any
of a dozen other minor variations?

More realistic cases are even harder to deal with.  Consider, for
example, the for_each algorithm from STL:
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f) {
    while (first != last) f(*first++);
    return f;
}

The constraints are as follows:
  There must be either a built-in operator!=, or a global operator!=,
    or a member function InputIterator::operator!=, such that applying
    operator!= to two InputIterators is well-defined and yields something
    that's convertable to bool.
  Operators ++ and * are defined such that *InputIterator++ yields an
    rvalue of some type.
  An object of type Function has an operator() that takes an argument
    of the type returned by *InputIterator++, or at least a type to
    which the return value of *InputIterator++ can be converted.
    The return value of operator() is unimportant.

Notice what's tricky here: the important constraints are relationships
between different types, some of which (like the return value of
InputIterator++, and the return value of *InputIterator++) aren't
named as template parameters.  This rapidly becomes a problem in 
formal specification.

This issue is something that has been thought about, and there's some
discussion of it in D&E.
-- 
Matt Austern
SGI: MTI Compilers Group
austern@isolde.mti.sgi.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Re: Better template syntax?
#4077
Author: Roman Lechtchinsky
Date: Wed, 17 Apr 1996 14:57
102 lines
5387 bytes
Matt Austern wrote:
> 
> In article <31741E6C.53CA@cs.tu-berlin.de> Roman Lechtchinsky
> <wolfro@cs.tu-berlin.de> writes:
> 
> > sorry for being curious but I'm only human... My question is: when declaring
> > templates, why isn't it required to declare what one expects of the
> > template's parameters? Let's create a template function:
> >
> > template<class T> bool equal( const T& t1, const T& t2 )
> > {
> >   return t1==t2;
> > }
> >
> > Now, personally I would prefer to write something like:
> >
> > template<class T { bool operator==( const T& t ) const; }> ...
> 
> Specifying something like this correctly turns out to be extremely
> difficult: it's very hard to come up with syntax that neither
> overspecifies nor underspecifies the constraints.  In this particular
> case, for example: do you really care whether operator== takes a const
> T&, as opposed to a T?  

Sure I do. If it takes a T the template needs access to the copy constructor. 
This is something one tends to forget about - the compiler wouldn't let you 
if you had to declare this fact.

> Does it matter that it returns bool, instead
> of something (like int) that is freely convertable to bool?  

It depends on what this something is and whether you really want it to be 
converted to bool or not ( in the case of operator== you almost certainly do; 
maybe it's a bad example ). No problem if it is really int. If it is a class 
which can be converted to bool or to int or even to a pointer then the 
programmer should at least know which conversions might occur. Usually 
templates are not documented that good.
As a matter of fact, my definition could accept an operator== with a 
different return type. When calling it the return value would be converted to 
bool prior to any other conversions which would give the programmer at least 
some control.

> Does it
> matter whether this is T::operator==(T), or ::operator==(T,T), or any
> of a dozen other minor variations?

Note that this problem occurs only with operators. Again, the two operators 
you mention have different semantics: the second one copies two objects 
whereas the first one copies only one. 

> 
> More realistic cases are even harder to deal with.  Consider, for
> example, the for_each algorithm from STL:
> template <class InputIterator, class Function>
> Function for_each(InputIterator first, InputIterator last, Function f) {
>     while (first != last) f(*first++);
>     return f;
> }
> 
> The constraints are as follows:
>   There must be either a built-in operator!=, or a global operator!=,
>     or a member function InputIterator::operator!=, such that applying
>     operator!= to two InputIterators is well-defined and yields something
>     that's convertable to bool.
>   Operators ++ and * are defined such that *InputIterator++ yields an
>     rvalue of some type.
>   An object of type Function has an operator() that takes an argument
>     of the type returned by *InputIterator++, or at least a type to
>     which the return value of *InputIterator++ can be converted.
>     The return value of operator() is unimportant.
> 
> Notice what's tricky here: the important constraints are relationships
> between different types, some of which (like the return value of
> InputIterator++, and the return value of *InputIterator++) aren't
> named as template parameters.  This rapidly becomes a problem in
> formal specification.

Yes, sure. I could try to design a class  which messes the whole thing up 
even though it provides everything the function needs. This rapidly becomes a 
problem in application development :-) Essentially, templates are macros. One 
can do a lot of things with macros. But should they be done? Maybe STL the 
design of STL would be clearer if everything had to be declared...

> 
> This issue is something that has been thought about, and there's some
> discussion of it in D&E.

Yes, there is ( I think so, at least; I don't remember who has my copy but 
its not me ). However, in many threads about templates I've read something 
like "now the semantics of templates are better understood". I'd like to hear 
what people think about them in the light of this new understanding.

Bye

Roman


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Re: Better template syntax?
#4081
Author: nicolas (n.) chapados
Date: Wed, 17 Apr 1996 14:57
39 lines
2311 bytes
Roman Lechtchinsky wrote:

> Now, personally I would prefer to write something like:
> 
> template<class T { bool operator==( const T& t ) const; }> ...
> 
> Now, what I'd like to know is if something like this has been considered and
> rejected ( and why ) and what other people think about it ( would this be
> really easier to use in practice; do you consider it more elegant than the
> current approach ). Thanks in advance.

Specification of requirements on template arguments in a form similar to
what
you suggest is discussed in Stroustrup's Design and Evolution of C++.
The
reasons leading to the rejection of similar proposals are discussed as
well
(although not to my satisfaction, since one of the stated reasons is
that 
requirements specification can be "emulated" in the language--this was
true
when Stroustrup wrote D&E but is not true any more.)

Note that your and similar approach make it easy to specify positive
requirements on arguments ("this type shall have this and that") but not
negative
requirements ("this type shall *not* have this and that").

---
Nicolas Chapados                          ----Standard Disclaimer---- 
chapados@nortel.ca                        Nortel Technology, formerly
BNR


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Re: Better template syntax?
#4084
Author: Nathan Myers <http://www.cantrip...
Date: Wed, 17 Apr 1996 17:41
55 lines
3160 bytes
Roman Lechtchinsky wrote:

> ... when declaring templates, why isn't it required to declare what 
> one expects of the template's parameters? 
> ... has [this] been considered and rejected ( and why ) ?

[This is from a paper by Koenig and Stroustrup, "Foundations for
Native C++ Styles" that appeared in Software Practice and Experience
vol. 25, December '95 (a Wiley pub.).  I encourage readers of this
newsgroup to look it up.] 

[I hope my excerpting hasn't done too much damage.]

----------------

What does C++ offer no such facility?   There are three main reasons:

[1] Any such facility would have to take into account not only inheritance
  but also built-in types and operations on types not defined as members.
  ... Ordinary pointers meet the requirements for random-access iterators
  when they are used to point to elements of (built-in) arrays.  That means
  we would need some way of saying that for any type T, T* is a random-
  access iterator, ... [or] forego the ability to use ... [template] 
  functions on arrays. ...

[2] The facility would offer little additional safety, if any.  The main
  benefit would be that errors would be detected when a template function
  ... is called, rather than when code is generated for it... [this is]
  not enough to justify a whole new type-checking facility.

[3] Even if such a facility existed ... that would still not guarantee 
  safety. ... Specifying "the expected operations" can be messy and 
  constraining; specifying "the expected semantics" can be surprisingly 
  difficult. ...

In general, we know of no way of expressing constraints on template
parameters that wouldn't be either too cumbersome or too constraining.
...

-----------------

[In short, any such apparatus (in C++, at least) would be complicated,
over-restrictive, and would fail to do the job required of it.  Some 
incompatible successor to C++ might be designed with such an apparatus
in mind, but today that's a research topic.]

Nathan Myers
ncm@cantrip.org  http://www.cantrip.org/
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu 
]
Re: Better template syntax?
#4104
Author: Rob Stewart
Date: Thu, 18 Apr 1996 16:54
58 lines
3228 bytes
Roman Lechtchinsky wrote:
> 
> Hi,
> 
> sorry for being curious but I'm only human... My question is: when declaring
> templates, why isn't it required to declare what one expects of the
> template's parameters? Let's create a template function:
> 
> template<class T> bool equal( const T& t1, const T& t2 )
> {
>   return t1==t2;
> }
> 
> Now, personally I would prefer to write something like:
> 
> template<class T { bool operator==( const T& t ) const; }> ...
> 
> This would make both the development and the use of templates much easier (
> to me, at least ). No need for writing lots of comments explaining what
> interface T should provide; no need for reading the source code of "equal" if
> it is part of a third-party library with poor interface documentation; no
> need to worry about implicit conversions - sounds like a lot of advantages.
> Then again, I imagine that this approach would make templates more efficient
> and easier to implement.
> Now, what I'd like to know is if something like this has been considered and
> rejected ( and why ) and what other people think about it ( would this be
> really easier to use in practice; do you consider it more elegant than the
> current approach ). Thanks in advance.
> 

I can't answer whether this has been considered (or rejected), 
but I can see a problem with your proposal.  What if a template 
required ten, fifteen, twenty mfs in its parameterizing type?  
What if those mfs have many parameters?  The resulting list of 
mfs and parameters would become quite ungainly.

Perhaps you could declare a class with the exact interface you 
expect and provide that as a model for the parameterizing type?  
This still leaves issues like equivalence.  Are implicit 
conversion allowed in mfs of a parameterizing type in order to 
match the model?  At what point do you decide there is no match?

What about the template code?  What if it you misuse the 
parameterizing type relative to your model?  Is the model wrong 
or is your code wrong?

There's probably a lot more I haven't thought of yet.

-- 
Robert Stewart		| My opinions are usually my own.
Datalytics, Inc.	| stew@datalytics.com


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Re: Better template syntax?
#4106
Author: Roman Lechtchinsky
Date: Thu, 18 Apr 1996 21:35
74 lines
3537 bytes
Rob Stewart wrote:
> 
> Roman Lechtchinsky wrote:
> >
> > Hi,
> >
> > sorry for being curious but I'm only human... My question is: when declaring
> > templates, why isn't it required to declare what one expects of the
> > template's parameters? Let's create a template function:
> >
> > template<class T> bool equal( const T& t1, const T& t2 )
> > {
> >   return t1==t2;
> > }
> >
> > Now, personally I would prefer to write something like:
> >
> > template<class T { bool operator==( const T& t ) const; }> ...
> >[...]
> 
> I can't answer whether this has been considered (or rejected),

Yes, it has been. I forgot that D&E contains a ( rather short ) discussion on 
this topic. Probably I should have written: "Has there been an attempt to 
define this", a question still unanswered.

> but I can see a problem with your proposal.  What if a template
> required ten, fifteen, twenty mfs in its parameterizing type?
> What if those mfs have many parameters?  The resulting list of
> mfs and parameters would become quite ungainly.

Actually, when I define a template I usually describe what it expects from 
its parameters in a comment. This means I have to write this list anyway. Do 
other programmers do it?

 
> Perhaps you could declare a class with the exact interface you
> expect and provide that as a model for the parameterizing type?
> This still leaves issues like equivalence.  Are implicit
> conversion allowed in mfs of a parameterizing type in order to
> match the model?  At what point do you decide there is no match?

I'm currently trying to define how this can be handled. In general, I think 
the following would do: a function matches a function required by the 
template if
a) its return type can be implicitly converted to the required return type 
and
b) the types of its parameters can be implicitly converted to the types of 
the correspondenting required parameters.
I wonder if someone has already tried this and what the results are.

> 
> What about the template code?  What if it you misuse the
> parameterizing type relative to your model?  Is the model wrong
> or is your code wrong?
> 

I'm not sure what you mean here.

> There's probably a lot more I haven't thought of yet. 
Yes, definitely. However, there's probably a lot more that hasn't been 
thought of ( or that is being thought of a this very moment ;-) about 
templates as well.

Bye

Roman


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads