C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Some remarks to N1849 (2nd trial)

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Daniel Krügler
Guest





PostPosted: Thu Sep 15, 2005 6:30 am    Post subject: Some remarks to N1849 (2nd trial) Reply with quote



{
Introductory comment: This is my 2nd trial to post this contribution.
The previous one was rejected, because the moderator argued, that it was
truncated, but the rejection mail did not show up any truncation and
such the posting is provided below (The only thing I changed where to
replace the single dot in the MyConcept definition by 3 dots).

**This note might be removed by the followup moderator**
}


Hello,

At first I want to emphasize, that I really liked the clearness and
thoroughness of the paper presented on:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1849.pdf

It doesn't evade any details of the proposals problems because it
explicitely mentions them. So although the following points seem
numerous on the first sight, they are mostly harmless (I hope):

1) Class analoga:
- Is it possible to define an object/instance of a concept or model? E.g.

template<typename T>
concept MyConcept {
..
};

MyConcept<int> c;

Assumption: No, it makes no sense, because concepts and models are pure
compile type entities which do have leave runtime traces.

2) I refer again to my most recent posting, where it was answered, that
reuse of typeid has been removed, and that the construction "!typename"
allows disabling of concept checking.

My personally feeling is, that I liked the previous syntax more than new
one. The reason are:

- The change of meaning of typename is more indirect and silent in
combination with concepts, because one has to recognize that there
exists a where clause (positionally quite late) to explain the suddenly
occuring names (injected typenames from concepts). Reusing "typeid"
seems better to me and visually at the right position. It also has the
convenient side effect, that the word "typeid" fits quite well (at least
to me Wink)

- The meaning of "!typename" really seems counterintuitive! My first
impression was: "It is not a type - so what is it?"

Was there somewhat more behind the decision other than: "It seems better
now"? (OK, I see at least one reason, and that is the usage of
simplified template-parameter syntax combined with concept checking
disablement)

3) A second reference to my previous posting: Doug Gregor explained
quite well the difference between loose matching of actual signatures
and the need of exact matching of pseudo signatures. Now the heretical
question: If I write a more specialized concept (i.e. a model), what
says the compiler, if I do the following:

// Original concept, as before:
template<typename Iter>
concept RandomAccessIterator : BidirectionalIterator<Iter>
{
typename difference type; // associated type requirement
difference type operator-(Iter const&, Iter const&); // operation
requirement
};

// Specialized model template, but **differing** from its original:
template<typename T>
concept RandomAccessIterator<const T*>
{
typedef ptrdiff t difference type;
ptrdiff t operator-(const T* x, const T* y) { return x-y; } // Note: No
const& in sight!
};

Is the compiler required to point to the wrong signature of operator-()
in the model for pointers?

4) It is probably a simple question, but one which needs an answer:
which relative positions of a "where" clause and an "inline" keyword are
allowed? Consider

template <typename T>
where {..}
inline void foo(T) {

---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Douglas Gregor
Guest





PostPosted: Fri Sep 16, 2005 3:29 am    Post subject: Re: Some remarks to N1849 (2nd trial) Reply with quote




Daniel Krügler wrote:
Quote:
At first I want to emphasize, that I really liked the clearness and
thoroughness of the paper presented on:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1849.pdf

It doesn't evade any details of the proposals problems because it
explicitely mentions them.

Thanks!

Quote:
So although the following points seem
numerous on the first sight, they are mostly harmless (I hope):

1) Class analoga:
- Is it possible to define an object/instance of a concept or model? E.g.

template<typename T
concept MyConcept {
.
};

MyConcept
Assumption: No, it makes no sense, because concepts and models are pure
compile type entities which do have leave runtime traces.

Your assumption is absolutely correct.

Quote:
2) I refer again to my most recent posting, where it was answered, that
reuse of typeid has been removed, and that the construction "!typename"
allows disabling of concept checking.

My personally feeling is, that I liked the previous syntax more than new
one. The reason are:

Let's see if we can sway your opinion :)

Quote:
- The change of meaning of typename is more indirect and silent in
combination with concepts, because one has to recognize that there
exists a where clause (positionally quite late) to explain the suddenly
occuring names (injected typenames from concepts). Reusing "typeid"
seems better to me and visually at the right position. It also has the
convenient side effect, that the word "typeid" fits quite well (at least
to me Wink)

That was our original rationale. However, while implementing and
testing ConceptGCC we found that the typeid/typename distinction
was too confusing. First, it means that there are now three ways to
declare a template type parameter (typename, class, typeid), two of
which are equivalent but very different from the third. Second, by
using a different keyword here it forced us to explain the difference
between non-dependent (or opaque) template parameters and normal,
dependent template parameters early on in the presentation of generic
programming. But in reality, most users will use one or the other
exclusively: they'll be writing completely type-safe templates or
they'll
be writing C++03 templates, but mixing the two will more likely be
reserved for migrating existing code to type-safe templates.

Finally, and most importantly, "typeid" was just too easy to forget.
While coding ConceptGCC, we of course were writing test cases, mini
STLs, etc; on many occasions I added where clauses to an existing
template, ran it through the compiler, and chuckled with glee when it
worked... only to realize later that I'd forgotten to change the
"typename" parameters to "typeid". Actually, it was worse than that:
even when writing new function templates, I kept writing "typename"
and not "typeid". If the authors/implementors of the proposal can't
use it properly, there is a serious usability problem.

With this new rule, that the presence of any constraints implies that
all template parameters are non-dependent *unless* they are marked
with '!', the aforementioned problem does not occur. Better yet, it
requires more knowledge to write a less-safe template, and less
knowledge doesn't hurt you. Now, you don't really need to
understand what "dependent" means to write a type-safe template.
When we used "typeid" for non-dependent template parameters,
users had to understand "dependent" before writing their template.

Quote:
- The meaning of "!typename" really seems counterintuitive! My first
impression was: "It is not a type - so what is it?"

Just to be picky, the '!' actually precedes the parameter name, e.g.,

template<typename !Dangerous> ...

We don't read the '!' as "not", but as "unsafe". There are other
languages
out there that use '!' to mean "unsafe", and we picked up the
convention.
Granted, we don't much care about the syntax here, so long as it takes
extra work to turn off type checking. Someone else suggested to us
privately that we just provide a bult-in concept "std::Unsafe" that
could
be used in a where clause like so:

template<typename Dangerous> where { std::Unsafe<Dangerous> }

Quote:
3) A second reference to my previous posting: Doug Gregor explained
quite well the difference between loose matching of actual signatures
and the need of exact matching of pseudo signatures. Now the heretical
question: If I write a more specialized concept (i.e. a model), what
says the compiler, if I do the following:

// Original concept, as before:
template<typename Iter
concept RandomAccessIterator : BidirectionalIterator {
typename difference type; // associated type requirement
difference type operator-(Iter const&, Iter const&); // operation
requirement
};

// Specialized model template, but **differing** from its original:
template concept RandomAccessIterator {
typedef ptrdiff t difference type;
ptrdiff t operator-(const T* x, const T* y) { return x-y; } // Note: No
const& in sight!
};

Is the compiler required to point to the wrong signature of operator-()
in the model for pointers?

Well, to be picky, the model should have an empty where clause
to turn on type checking for the model template:

template concept RandomAccessIterator<const T*>
{
// ...
};

With this change, the program is ill-formed and the compiler shall emit
a
diagnostic stating that the operator-() given does not satisfy any
requirement in the model. The "real" operator- signature will have been
implicitly generated.

If we hadn't added the "where{}", the same error would be detected when
the model is instantiated, e.g., RandomAccessIterator<const int*>;

Quote:
4) It is probably a simple question, but one which needs an answer:
which relative positions of a "where" clause and an "inline" keyword are
allowed? Consider

template <typename T
where {..}
inline void foo(T) {

The where-clause follows a template header or precedes a member
declaration. The relevant portions of the grammar (from page 21 of
N1849) are:

template-declaration:
export[opt] template < template-parameter-list > where-clause[opt]
declaration

member-declaration:
where-clause member-declaration

Doug


---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Daniel Krügler
Guest





PostPosted: Sat Sep 17, 2005 2:01 am    Post subject: Re: Some remarks to N1849 (2nd trial) Reply with quote



Hello Douglas Gregor,

At first I want to add that my posting was strongly truncated
through the moderation process, so I tried a second posting in
the main queue and not as answer to your contribution.

Douglas Gregor wrote:
Quote:
Daniel Krügler wrote:
Let's see if we can sway your opinion :)


[..]

Quote:

That was our original rationale. However, while implementing and
testing ConceptGCC we found that the typeid/typename distinction
was too confusing. First, it means that there are now three ways to
declare a template type parameter (typename, class, typeid), two of
which are equivalent but very different from the third. Second, by
using a different keyword here it forced us to explain the difference
between non-dependent (or opaque) template parameters and normal,
dependent template parameters early on in the presentation of generic
programming. But in reality, most users will use one or the other
exclusively: they'll be writing completely type-safe templates or
they'll
be writing C++03 templates, but mixing the two will more likely be
reserved for migrating existing code to type-safe templates.

Finally, and most importantly, "typeid" was just too easy to forget.
While coding ConceptGCC, we of course were writing test cases, mini
STLs, etc; on many occasions I added where clauses to an existing
template, ran it through the compiler, and chuckled with glee when it
worked... only to realize later that I'd forgotten to change the
"typename" parameters to "typeid". Actually, it was worse than that:
even when writing new function templates, I kept writing "typename"
and not "typeid". If the authors/implementors of the proposal can't
use it properly, there is a serious usability problem.

With this new rule, that the presence of any constraints implies that
all template parameters are non-dependent *unless* they are marked
with '!', the aforementioned problem does not occur. Better yet, it
requires more knowledge to write a less-safe template, and less
knowledge doesn't hurt you. Now, you don't really need to
understand what "dependent" means to write a type-safe template.
When we used "typeid" for non-dependent template parameters,
users had to understand "dependent" before writing their template.


- The meaning of "!typename" really seems counterintuitive! My first
impression was: "It is not a type - so what is it?"


Just to be picky, the '!' actually precedes the parameter name, e.g.,

Yes, you got me here ;-!!


Quote:
template<typename !Dangerous> ...

We don't read the '!' as "not", but as "unsafe". There are other
languages
out there that use '!' to mean "unsafe", and we picked up the
convention.
Granted, we don't much care about the syntax here, so long as it takes
extra work to turn off type checking. Someone else suggested to us
privately that we just provide a bult-in concept "std::Unsafe" that
could
be used in a where clause like so:

template<typename Dangerous> where { std::Unsafe<Dangerous> }


Yes, that is also I nice idea. But after reading your reasoning of the
proposed nameing and a long time reading bothe papers N1848 and N1849
I think I got used to the propsed syntax.



Quote:
3) A second reference to my previous posting: Doug Gregor explained
quite well the difference between loose matching of actual signatures
and the need of exact matching of pseudo signatures. Now the heretical
question: If I write a more specialized concept (i.e. a model), what
says the compiler, if I do the following:

// Original concept, as before:
template<typename Iter
concept RandomAccessIterator : BidirectionalIterator {
typename difference type; // associated type requirement
difference type operator-(Iter const&, Iter const&); // operation
requirement
};

// Specialized model template, but **differing** from its original:
template concept RandomAccessIterator {
typedef ptrdiff t difference type;
ptrdiff t operator-(const T* x, const T* y) { return x-y; } // Note: No
const& in sight!
};

Is the compiler required to point to the wrong signature of operator-()
in the model for pointers?


Well, to be picky, the model should have an empty where clause
to turn on type checking for the model template:

template concept RandomAccessIterator<const T*
{
// ...
};


while you are right concerning the proper way to write this model
template it was importand for me to understand what happens, if
programmers do make errors in writing models corresponding to concepts.


Quote:
With this change, the program is ill-formed and the compiler shall emit
a
diagnostic stating that the operator-() given does not satisfy any
requirement in the model. The "real" operator- signature will have been
implicitly generated.

If we hadn't added the "where{}", the same error would be detected when
the model is instantiated, e.g., RandomAccessIterator

OK, that are good news!


Quote:
4) It is probably a simple question, but one which needs an answer:
which relative positions of a "where" clause and an "inline" keyword are
allowed? Consider

template <typename T
where {..}
inline void foo(T) {


The where-clause follows a template header or precedes a member
declaration. The relevant portions of the grammar (from page 21 of
N1849) are:

template-declaration:
export[opt] template < template-parameter-list > where-clause[opt]
declaration

member-declaration:
where-clause member-declaration

Thank you for clarification. I have must have found this grammar later
than I wrote my question and forgot to remove it...

Greetings,

Daniel

---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Douglas Gregor
Guest





PostPosted: Sun Sep 18, 2005 4:22 am    Post subject: Re: Some remarks to N1849 (2nd trial) Reply with quote


Daniel Krügler wrote:
Quote:
// Original concept, as before:
template<typename Iter
concept RandomAccessIterator : BidirectionalIterator {
typename difference type; // associated type requirement
difference type operator-(Iter const&, Iter const&); // operation
requirement
};

// Specialized model template, but **differing** from its original:
template concept RandomAccessIterator {
typedef ptrdiff t difference type;
ptrdiff t operator-(const T* x, const T* y) { return x-y; } // Note: No
const& in sight!
};

For reference, our development version of ConceptGCC gives the
following error message when provided with your example:

model_check2.C:17: error: model operation 'ptrdiff_t operator-(const
T*, const T*)' does not match any concept requirement
model_check2.C:9: note: near match: 'typename
RandomAccessIterator const&, const T* const&)'

(The line numbers match up with the operator- in the model and concept,
respectively). Also, much to my surprise, the result is the same
regardless of whether we add an empty where-clause to the model
template, because model templates need to be completely consistent with
their concept even if they have dependent template parameters.

Doug


---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.