From: Joel Eidsath on
Dave Abrahams wrote:
>> But there is not much functional difference between templates, as
>> implemented now, and functions in more OO languages that work on the
>> base object for all types.
>
>Yes, there is. Covariant argument types (the kind you need in order
>to do int + int and complex + complex with the same '+' operation --
>or swap, for that matter) can't be implemented using traditional OO
>without compromising static type safety. Among other things.

That surprises me to find out. I haven't really used any fully OO
languages beyond tinkering. I didn't realize things were quite that
bad.

>> Stroustrup's and Dos Reis' paper for the standard committee is
>> available here:
>> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1782.pdf
>
>I hope you're aware that there's a competing concepts proposal:
>http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1849.pdf

I wasn't aware of it. I've been making my way through the proposals,
but in a fairly haphazard manner.

To be honest, the reason I posted what I thought of the Stroustrup
paper was because I haven't been able to find much good discussion of
the details of concepts, despite how important they are. So I thought
I'd drum some up. I also hoped to provoke some posters into curing my
various points of ignorance. So thanks for the link, I'll be reading
it right away.

>> Concepts allow two sorts of errors to be picked up by the compiler:
>> 1) Concept violations in the arguments passed to a template at point
>> of call.
>> 2) Concept violations inside the template itself.
>>
>> I am somewhat wary about this. Catching 1 should be the main
>> justification of concepts. In effect, it is the template designer
>> saying to the user of the template "your types must possess these
>> properties, or they won't work as template arguments." Catching 2,
>> however, is saying "so long as your types possess these properties,
>> they will work as template arguments." The problem with 2 is that it
>> won't always be true.
>
>What do you mean?

You specify Assignable<T, U> to keep the user of a template from doing
something stupid like passing your template a U that can't be assigned
to T. This would be a violation of 1.

A violation of 2 would be where you try to write T = U in your template
code, but can't because you haven't specified Assignable<T,U>. I think
that enforcing 2 may fool some people into thinking that all concept
templates are truly generic. More importantly, because of 2, I can't
make existing template code more safe for code users by just adding a
single concept to stop the user from doing something stupid. I have to
add every concept that the template code uses.

>I hope you're aware that the competing concepts proposal supports
>that, and it has been implemented:
>http://www.osl.iu.edu/~dgregor/ConceptGCC/
>
>You can download that compiler and use it today.

Again, thanks.

>> Section 3 describes how to create concepts. I dislike that there are
>> no provisions for negative concepts. For example, I might like to have
>> something like "Not_Assignable" for use in creating slow careful
>> algorithms rather than the fast awesome algorithms I might create with
>> "Assignable".
>
>You don't need that. If you create two overloads, only one of which
>requires Assignable, it will be chosen in preference to the other
>one. You can put the slow implementation in the overload that doesn't
>require Assignable.

I realize that it can be done, it just won't be quite as clear or
pretty.

And it can get uglier. Say I have a property Is_Inherited_From_ClassX.
(This is what I was getting at with the dynamic_cast stuff. It looks
like a useful property to me, I'll be able to specify it somehow,
right?) I have a couple of other properties R and S. I have
algorithms for 1) R&&~Is_Inherited_From_ClassX, 2)
S&&~Is_Inherited_From_ClassX, 3) R&&S&&~Is_Inherited_From_ClassX, 4)
Is_Inherited_From_ClassX.

But because I can't specify ~Is_Inherited_From_ClassX, I have to write
7 algorithms instead:
1)R
2)S
3)Is_Inherited_From_ClassX
4)R&&S
5)R&&Is_Inherited_From_ClassX
6)S&&Is_Inherited_From_ClassX
7)R&&S&&Is_Inherited_From_ClassX

Yeah, some of those will be copy and pastes, but there are more
required as more properties get involved. It boosts compilation time,
and so on and so forth. So not having '~' is less clear, potentially
requires more work, and may slow compilation. What are the reasons put
forward against having it?

>> Another feature that is missing is some sort of user concept
>> specification.
>
>I don't know what that means.

Say I want to write some template code for classes with a binary
function. I'd like to specify a concept
"this_binary_function_never_returns_zero." For any class to be used by
the template, the class designer would specifically have to associate
"this_binary_function_never_returns_zero" with the class somehow. The
class author might subvert it by lying, but I still think that you
would avoid errors and create more maintainable code with that option.
To do this now, I'd use traits.

>What you're referring to sounds a lot more like it should be called
>"runtime semantic guarantees" than "user concept specification."

Yes, that sounds like a much better term.

>> There is another thing missing from concepts that limit their utility.
>> I don't see how to implement it, however:
>
>> Hopefully everyone learned about induction proofs in high school. For
>> induction to work, you need to prove that "P true for x" implies "P
>> true for x + 1" and also a specific instance of P. (Usually P of 1 or
>> 0.) I see concepts as equivalent to the first general condition of
>> induction, but not the second. It would be nice to have some
>> constraints on class T initialized with 0, for instance.
>
>Again, these are runtime semantic guarantees.
>
>> Sometimes this will be possible to know at compile-time, sometimes
>> not.
>
>How could it ever be known at compile time?

If a class constructor doesn't make any function calls, then the
compiler could theoretically know a lot about C(0) for some class C.
It may know one or two things about a sufficiently simple empty
container. I can't imagine an easy way for compiler writers to
implement this sort of thing, but maybe there are smarter people than
me on this newsgroup who can. That's why I threw it out.

Joel Eidsath


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Roland Pibinger on
On 30 Sep 2005 21:59:51 -0400, "kanze" <kanze(a)gabi-soft.fr> wrote:

>The whole point of static type checking is that the
>compiler detects errors, rather than the run-time library. For
>run-time genericity, the requirement of a common base type (or
>something similar) is essential for static type checking.

Actually there is no 'type checking' involved with templates. If a
template instantiation compiles (produces syntactically correct C++)
it's ok, otherwise you see the notorious error messages. Templates are
untyped. The compiler checks syntax, not types.

Best regards,
Roland Pibinger

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gabriel Dos Reis on
rpbg123(a)yahoo.com (Roland Pibinger) writes:

| On 30 Sep 2005 21:59:51 -0400, "kanze" <kanze(a)gabi-soft.fr> wrote:
|
| >The whole point of static type checking is that the
| >compiler detects errors, rather than the run-time library. For
| >run-time genericity, the requirement of a common base type (or
| >something similar) is essential for static type checking.
|
| Actually there is no 'type checking' involved with templates.

I guess it depends on your definition of "type checking".

--
Gabriel Dos Reis
gdr(a)integrable-solutions.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Roland Pibinger wrote:
> On 30 Sep 2005 21:59:51 -0400, "kanze" <kanze(a)gabi-soft.fr> wrote:

>>The whole point of static type checking is that the compiler
>>detects errors, rather than the run-time library. For
>>run-time genericity, the requirement of a common base type (or
>>something similar) is essential for static type checking.

> Actually there is no 'type checking' involved with
> templates. If a template instantiation compiles (produces
> syntactically correct C++) it's ok, otherwise you see the
> notorious error messages. Templates are untyped. The compiler
> checks syntax, not types.

Templates are resolved at compile time. And the compiler very
definitly does type check the resulting instantiations. The
results are as fully type safe as any normal C++ code.

In this regard, the important point is, of course, that C++
templates are a meta-language; the compiler doesn't "compile"
the template itself, it compiles instantiations of the template.
Which means that some errors will not be detected until
instantiation, and that error messages refer to the
instantiation, and not to the template. But precisely because
they are a meta-language, they permit (amongst many other
things) expressing type constraints which could otherwise only
be expressed by means of extensive copy/paste, often with
additional editing of the pasted code.

I'm hardly what one could consider an expert with regards to
templates, and I'm fairly sceptical concerning the applicability
of the most advanced meta-programming techniques in commercial
code, where other programmers have to understand what you've
done. But I've also used <generic.h>, in pre-template days, and
I've used the Java Collections (which IMHO are globally better
designed than the STL). And given that experience, I can say
that templates are a better solution that pure macros or than
deriving everything from Object and depending on dynamic
downcasting. A much better solution.

--
James Kanze mailto: james.kanze(a)free.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre S?mard, 78210 St.-Cyr-l'?cole, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: kanze on
Gabriel Dos Reis wrote:
> rpbg123(a)yahoo.com (Roland Pibinger) writes:

> | On 30 Sep 2005 21:59:51 -0400, "kanze" <kanze(a)gabi-soft.fr> wrote:

> | >The whole point of static type checking is that the
> | >compiler detects errors, rather than the run-time library.
> | >For run-time genericity, the requirement of a common base
> | >type (or something similar) is essential for static type
> | >checking.

> | Actually there is no 'type checking' involved with templates.

> I guess it depends on your definition of "type checking".

Actually, I don't think that there is any definition for which
one could say that there is NO type checking. If I declare:

template < typename T > class X {} ;

and try to instantiation "X< 3 >", the compiler is going to
complain that the template parameter is of the wrong type -- it
is an int, where a typename is required.

The way I "interpret" templates is that they are a
meta-language, with dynamic type checking. The meta-program
gets "executed" at compile time, with the results that the
"dynamic type checking" of the meta-program occurs at compile
time. And of course, the meta-program generates "program" (the
instantiations), which is type checked exactly like any other
C++ code.

The only real problem, of course, is that the compiler error
messages refer to the code generated by the meta-program, which
doesn't necessarily make them particularly easy to understand.
(I'm exagerating a little, of course, when I say "the only real
problem". The interactions between the meta-program and the
rest aren't always that simple either -- implicit instantiation
with template type deduction and function overload resolution
come to mind.)

--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: C++/CLI limitations?
Next: SHA1