In the hopes of soliciting constructive feedback, if anyone has the
time or the interest to play with a patched up Clang that implements
enhanced auto deduction & abbreviated template syntax from the
concepts ts, here it is:
https://github.com/faisalv/clang/tree/enhanced-auto-c%2B%2B1z .
// C++14: Create a lambda object with a template member operator()
auto f = [](auto x, auto y) { return x + y; };
// C++1z: Create a template function directly
auto f(auto x, auto y) { return x + y; }
1) Enhanced-Auto Deduction:
pair<auto...> f() { return make_pair([] { }, [] { }); }
vector<auto> v = vector<int>();
vector<auto> v = vector<int>();
auto v = vector<int>();
template<class T> using identity1 = T;
identity1<auto> id1 = 42;
template<class T> struct identity2 { using type = T; };
identity2<auto>::type id2 = 42;
template<class T> struct int3 { using type = int; };
int3<auto>::type id3 = 42;
template<class> using int4 = int;
int4<auto> id4 = 42;
vector<auto> vec = { 1, 2, 3 }; // creates a vector of int
2) Abbreviated Template Syntax:
void f(auto) <=> template<class T> void f(T);
A few, perhaps not so obvious or interesting, technicalities:
a) The equivalence of templates when it comes to trailing return
types in function pointer parameters is based on the order of the
'auto' that signifies a placeholder, not just the appearance of an
auto in the declaration-specifier of a parameter:
template<class R, class P> void f( R(P) ); // #1
template<class P, class R> void f( R(P) ); // #2 (order of
templ-params flipped)
template<class R, class P> void f( auto (P)->R); // equivalent to
#1, not abbreviated.
int one(int (*f)(int)) { return f(42); } // C++03
int two(auto (*f)(int) -> int) { return f(42); } // C++11
int three(auto (*f)(int)) { return f(42); } // never
int four(auto (*f)(int) -> auto) { return f(42); } // never
int five(int (*f)(auto)) { return f(42); } // never
int six(int f(int)) { return f(42); } // C++03 (takes a function pointer)
int seven(int f(auto)) { return f(42); } // never
auto bone = [](int (*f)(int)) { return f(42); }; // C++11
auto btwo = [](auto (*f)(int) -> int) { return f(42); }; // never
auto bthree = [](auto (*f)(int)) { return f(42); }; // C++14
auto bfour = [](auto (*f)(int) -> auto) { return f(42); }; // never
auto bfive = [](int (*f)(auto)) { return f(42); }; // never
auto bsix = [](int f(int)) { return f(42); }; // C++11 (takes a function pointer)
auto bseven = [](int f(auto)) { return f(42); }; // never
void f(auto(auto)); // equivalent to #1
auto f(auto ga(auto)) { return ga("hello world"); }
auto g(auto xa) { puts(xa); }
int main() { f(g); }
auto f(auto *ga) { return ga("hello world"); }
b) variadic auto
Once an ellipsis is seen as part of the declarator, all contained
auto placeholders get transformed into parameter packs.
void f(auto (*...)(auto) -> std::tuple<auto, std::pair<auto, auto>...>);
Note there are 4 deducible template parameter packs above.
template<class... A, class... B, class... C, class... D>
void f1(std::tuple<A, std::pair<B,C>...> (*...args)(D));
void f2(std::tuple<auto, std::pair<auto,auto>...> (*...args)(auto));
c) multi abbreviated template declarations
void f(auto), g(auto);
are allowed - the above declares two function templates.
auto foo = 42; // foo is definitely an int
void bar(auto baz = 42); // baz is NOT an int; it's of some deduced type.
// The initializer 42 is coerced to that type if necessary.
template<class X, class Y=int> auto one(X x, Y y=1) { return x+y; }; // legal C++14
template<class X, class Y> auto two(X x, Y y=1) { return x+y; }; // invalid, and rightly so
auto three = [](auto x, auto y=1) { return x+y; }; // invalid, but I claim it has an obvious meaning that should be standardized
auto four(auto x, auto y=1) { return x+y; }; // invalid?? with your patch, but I claim it has an obvious meaning
int main() { one(1); two(2); three(3); four(4); }
I generally agree with the above statement - but there are some who> I don't see the use-case for this feature. Why would I write
>
> vector<auto> v = vector<int>();
>
> when it's less typing and less noise to just write
>
> auto v = vector<int>();
>
have argued that it can improve readability - and I see their point
too.
I don't see the use-case for this feature. Why would I write
vector<auto> v = vector<int>();when it's less typing and less noise to just write
auto v = vector<int>();
vector<int> v;
array_view<auto> av = v; //deduces to array_view<int>
On Tuesday, March 3, 2015 at 6:39:49 PM UTC-8, faisalv wrote:In the hopes of soliciting constructive feedback, if anyone has the
time or the interest to play with a patched up Clang that implements
enhanced auto deduction & abbreviated template syntax from the
concepts ts, here it is:
https://github.com/faisalv/clang/tree/enhanced-auto-c%2B%2B1z .That's very very cool — at least the "abbreviated template syntax" half! ;)
On 4 March 2015 at 17:59, Geoffrey Romer wrote:
> Interesting; my reaction is precisely the opposite- I find enhanced auto
> deduction very appealing (for reasons that others on this thread have
> elaborated), but am actively uninterested in the abbreviated template
> syntax. It seems to me to offer only a modest improvement in brevity, and
> pays for it with a very substantial reduction in readability. That
> compromise may be appropriate for lambdas, because brevity is particularly
> important inside a single expression, but it seems far less justifiable in
> the case of ordinary functions. Functions are not under the kinds of space
> constraints that lambdas are, and function signatures (unlike lambda
> signatures) often act as abstraction boundaries, so it's particularly
> important for them to convey useful information to the reader.
This conveys useful information:
template<typename ForwardIterator>
ForwardIterator next(ForwardIterator);
but that's still true if it's rewritten like this:
ForwardIterator next(ForwardIterator);
This doesn't convey any useful information:
template<typename T>
void frob(T);
so in terms of describing the interface it's no different when written
like this:
void frob(auto);
This doesn't convey any useful information:
template<typename T>
void frob(T);I don't agree; it tells me that frob is a generic operation that works with roughly any type T.
so in terms of describing the interface it's no different when written
like this:
void frob(auto);This is different because now I don't know anything about the requirements or semantics of the parameter type.
On 5 March 2015 at 11:11, 'Geoffrey Romer' via ISO C++ Standard - Future Proposals <std-pr...@isocpp.org> wrote:This doesn't convey any useful information:
template<typename T>
void frob(T);I don't agree; it tells me that frob is a generic operation that works with roughly any type T.But what does that mean? Sure, I can copy/move it (since it was passed by value), but any other constraints will be dictated by the body of frob.
so in terms of describing the interface it's no different when written
like this:
void frob(auto);This is different because now I don't know anything about the requirements or semantics of the parameter type.I'm just not seeing how that is any different (other than the incredibly minor of having to call decltype on its parameter to get its type).Do you have an example function body that works with frob(T) but doesn't work with frob(auto) (or vice versa) for a specific concrete type? I'm really trying to understand the difference you see between these two forms.
I've personally never minded the template boilerplate, but I guess I'm weird that way.
void frob(auto t)
{
// if I want to use 'T' here, I need to do a decltype(t) to get at it
}
I... just... ugh.
I'm fine with type deduction patterns like std::vector<auto> = ...; That's just a generalization of type deduction in static contexts.
My issue is with, well, any syntax that declares a template without having to type either the word "template" or the use of "<>" brackets. Templates are a fundamentally different kind of construct, and we have specific syntax for doing so. By removing that syntax, it becomes way too easy to not notice that you've declared a template.
To paraphrase Stroustrup, it’s not about functional programming and object-oriented programming and generic programming… “it’s all just programming.”
> Templates are a fundamentally different kind of construct
Why? Every full specialization of a function template is just a function.
> My issue is with, well, any syntax that declares a template without having to type either the word "template" or the use of "<>" brackets.
That ship has sailed:
auto plus = [](auto x, auto y) { return x+y; }
which even already decays to an ordinary pointer to function, etc.
Clarifying Q: Are we mainly arguing about whether to require the three characters =, [, and ] ?
Not only has the ship sailed, but I for one like the direction it’s sailing. I see no reason why functions should be forced to spell “template” and “<>”. What value does it add? It’s “just programming.” In fact, if we didn’t have backward compatibility issues with unnamed parameters and such, I’d personally probably be fine with just “auto plus(x,y){x+y}” as an equivalent function definition. That still doesn’t lose any information.
Gratuitous syntax is often unnecessary and usually harmful. Saying
template<class T, class U>
auto(T x, U y) -> decltype(x+y) { return x+y; }
does not appear to me to contain any more information than
auto plus(auto x, auto y) { return x+y; }
does it? Requiring the verbose syntax is gratuitous, if the verbose syntax does not add information, does not serve to disambiguate anything, and does not highlight a dangerous operation or anything else I can see that deserves to have attention called to it.
There’s a disturbing (to me and at least some others) trend in C++ these days: People seem to be very prone to wanting “more syntax” lately. It’s rather Vasa-like, if only lexically. Let me channel certain influential committee members and say: ‘People these days are always asking for more syntax! There’s no proposal they’ve seen that they couldn’t make uglier with more syntax!’
Important note: The point here is NOT terseness for terseness’ sake. I am not arguing that terser is somehow better, that terseness is virtuous in itself. Too many people glorify languages because they’re terser; fewer characters alone doesn’t make code clearer. Rather, my point is to avoid gratuitous verbosity. At the other end of the pendulum, too many people glorify verbose syntax because they think _that_ is somehow inherently clearer; usually it isn’t. So I am arguing that neither is verbosity virtuous in itself.
Herb
To paraphrase Stroustrup, it’s not about functional programming and object-oriented programming and generic programming… “it’s all just programming.”
> Templates are a fundamentally different kind of construct
Why? Every full specialization of a function template is just a function.
> My issue is with, well, any syntax that declares a template without having to type either the word "template" or the use of "<>" brackets.
That ship has sailed:
auto plus = [](auto x, auto y) { return x+y; }
which even already decays to an ordinary pointer to function, etc.
Clarifying Q: Are we mainly arguing about whether to require the three characters =, [, and ] ?
Not only has the ship sailed, but I for one like the direction it’s sailing. I see no reason why functions should be forced to spell “template” and “<>”. What value does it add? It’s “just programming.” In fact, if we didn’t have backward compatibility issues with unnamed parameters and such, I’d personally probably be fine with just “auto plus(x,y){x+y}” as an equivalent function definition. That still doesn’t lose any information.
Gratuitous syntax is often unnecessary and usually harmful. Saying
template<class T, class U>
auto(T x, U y) -> decltype(x+y) { return x+y; }
does not appear to me to contain any more information than
auto plus(auto x, auto y) { return x+y; }
does it?
Requiring the verbose syntax is gratuitous, if the verbose syntax does not add information, does not serve to disambiguate anything, and does not highlight a dangerous operation or anything else I can see that deserves to have attention called to it.
There’s a disturbing (to me and at least some others) trend in C++ these days: People seem to be very prone to wanting “more syntax” lately. It’s rather Vasa-like, if only lexically. Let me channel certain influential committee members and say: ‘People these days are always asking for more syntax! There’s no proposal they’ve seen that they couldn’t make uglier with more syntax!’
Important note: The point here is NOT terseness for terseness’ sake. I am not arguing that terser is somehow better, that terseness is virtuous in itself. Too many people glorify languages because they’re terser; fewer characters alone doesn’t make code clearer. Rather, my point is to avoid gratuitous verbosity. At the other end of the pendulum, too many people glorify verbose syntax because they think _that_ is somehow inherently clearer; usually it isn’t. So I am arguing that neither is verbosity virtuous in itself.
Incidentally, this is one thing I love about the concepts TS: it lets us form a much stronger argument about the merits here based on actual user experience.
>> Herb
>>
>>
>>
>>
>>
>> From: Nicol Bolas [mailto:jmck...@gmail.com]
>> Sent: Thursday, March 5, 2015 3:19 PM
>> To: std-dis...@isocpp.org
>> Cc: std-pr...@isocpp.org; c++st...@accu.org; fai...@gmail.com
>> Subject: [c++std-core-27204] Re: An implementation of enhanced auto deduction and abbreviated template syntax using Clang
>>
>>
>>
>> I... just... ugh.
>>
>> I'm fine with type deduction patterns like std::vector<auto> = ...; That's just a generalization of type deduction in static contexts.
>>
>> My issue is with, well, any syntax that declares a template without having to type either the word "template" or the use of "<>" brackets. Templates are a fundamentally different kind of construct, and we have specific syntax for doing so. By removing that syntax, it becomes way too easy to not notice that you've declared a template.
>>
>> The last thing we should want is for people to accidentally make something a template.
>>
>> I accept this with lambdas, because the main point of lambdas is that they're a short-cut. Furthermore, they have a syntax that's fundamentally different from regular functions. But for a regular function? No.
>>
>> Basically, if I see this:
>>
>> X func_name(...);
>>
>> I expect that &func_name ought to return a pointer. For it to do something else, like being a compiler error, would be surprising.
>
>
template<class Sequence, class UnaryFunction>
void for_each(Sequence& seq, UnaryFunction f) { for(auto&& x : seq) f(x); }
void for_each(auto& sequence, auto unary_op) { for(auto&& x : sequence) unary_op(x); }
template<typename Function, typename Value>
auto f(Function fn, Value v) { return fn(v); }
auto f(auto fn, auto val) { return fn(val); }
On 5 March 2015 at 16:24, Herb Sutter <hsu...@microsoft.com> wrote:
Gratuitous syntax is often unnecessary and usually harmful. Saying
template<class T, class U>
auto(T x, U y) -> decltype(x+y) { return x+y; }
does not appear to me to contain any more information than
auto plus(auto x, auto y) { return x+y; }
does it?
To me, yes, it does. It says:* I deliberately want to allow the parameters to have different types
* I deliberately want to allow the return type to differ from those types
* I want a substitution failure if x + y is not valid (your rewrite is possibly incorrect due to this)
* I want to "perfectly return" x + y rather than always returning by value (your rewrite is possibly incorrect due to this)
* It's OK for this apparent function definition to be in a header file despite not including the 'inline' keyword
* It's *not* OK to move this definition out of the header file.
* I deliberately want to allow the parameters to have different types
* I deliberately want to allow the return type to differ from those types
* I want a substitution failure if x + y is not valid (your rewrite is possibly incorrect due to this)
* I want to "perfectly return" x + y rather than always returning by value (your rewrite is possibly incorrect due to this)
* It's OK for this apparent function definition to be in a header file despite not including the 'inline' keyword
* It's *not* OK to move this definition out of the header file.
* And the big one: it says "this is a template". No need to go scanning the declaration for "auto" (or for concept names, not that you can identify them by sight). It's right there at the start.
It's somewhat less clear to me how this loss of readability balances against the possibility of improved readability from a shorter declaration.
Out of curiosity, why is next's template-ness a critical fact?
I've been writing a fair amount of C lately (and sadly). Many of the
functions I use turn out to be macros. I don't consider that to be a
critical fact. And when I'm writing C++, I generally don't care that
something I call is a template, only that there's an overload that
matches the arguments I call it with.
I've heard this argument before. I've yet to hear a good answer.
To paraphrase Stroustrup, it’s not about functional programming and object-oriented programming and generic programming… “it’s all just programming.”
> Templates are a fundamentally different kind of construct
Why? Every full specialization of a function template is just a function.
//header
RetType func_name(Type1 arg1, ...);
//source
RetType func_name(Type1 arg1, ...)
{
//implementation
}
//header
template<typename T>
RetType func_name_template(T arg1, ...)
{
//implementation
}
//source doesn't exist.
//header
RetType func_name_concept(ConceptName arg1, ...);
//source
RetType func_name_concept(ConceptName arg1, ...)
{
//implementation
}
> My issue is with, well, any syntax that declares a template without having to type either the word "template" or the use of "<>" brackets.
That ship has sailed:
auto plus = [](auto x, auto y) { return x+y; }
which even already decays to an ordinary pointer to function, etc.
Clarifying Q: Are we mainly arguing about whether to require the three characters =, [, and ] ?
Not only has the ship sailed, but I for one like the direction it’s sailing. I see no reason why functions should be forced to spell “template” and “<>”. What value does it add? It’s “just programming.” In fact, if we didn’t have backward compatibility issues with unnamed parameters and such, I’d personally probably be fine with just “auto plus(x,y){x+y}” as an equivalent function definition. That still doesn’t lose any information.
Gratuitous syntax is often unnecessary and usually harmful. Saying
template<class T, class U>
auto(T x, U y) -> decltype(x+y) { return x+y; }
does not appear to me to contain any more information than
auto plus(auto x, auto y) { return x+y; }
does it?
Requiring the verbose syntax is gratuitous, if the verbose syntax does not add information, does not serve to disambiguate anything, and does not highlight a dangerous operation or anything else I can see that deserves to have attention called to it.
There’s a disturbing (to me and at least some others) trend in C++ these days: People seem to be very prone to wanting “more syntax” lately. It’s rather Vasa-like, if only lexically. Let me channel certain influential committee members and say: ‘People these days are always asking for more syntax! There’s no proposal they’ve seen that they couldn’t make uglier with more syntax!’
Important note: The point here is NOT terseness for terseness’ sake. I am not arguing that terser is somehow better, that terseness is virtuous in itself. Too many people glorify languages because they’re terser; fewer characters alone doesn’t make code clearer. Rather, my point is to avoid gratuitous verbosity. At the other end of the pendulum, too many people glorify verbose syntax because they think _that_ is somehow inherently clearer; usually it isn’t. So I am arguing that neither is verbosity virtuous in itself.
Herb
On 6 March 2015 at 17:21, Nicol Bolas wrote:
> Explain to me, the novice C++ programmer, why this thing which doesn't look
> like a template suddenly became a template. Explain to me why I have to
> implement it in a header, even though it looks exactly like every other
> non-template function declaration/definition.
>
> To the novice C++ programmer, it isn't "all just programming." Whether
> something is a template matters.
Ah, the "won't somebody think of the children" argument.
The answer to why it suddenly became a template is that its parameter
is a concept, not a type. A concept is a family of types. I don't see
why that should be much harder to teach than "a function template is a
family of functions" and "a class template is a family of types".
> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.
Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:
auto f() { … };
This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
Herb
PS – Since you mention “novices” writing templates, in my experience (and to my surprise) I’ve found that not only novices but also intermediate developers (like 5-7 year veterans) don’t write templates very much. [I expect this to change with concepts, for the good.] I discovered this by chance when I had a class exercise that included writing a very simple template, and as I walked through the class during the exercise I was surprised that most of the groups asked about the syntax for writing a template – a dead giveaway that they didn’t write templates very often, yet these were pretty experienced developers who used C++ every day, but just never needed to write templates much in their normal code. To validate that this wasn’t just an outlier group, I’ve watched that exercise in a number of classes over several years and found a similar result – the majority of even reasonably experienced C++ programmers asked about the syntax for how to write a template.
> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:auto f() { … };This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
That's not the case he's talking about. He's talking about this one:void f(T);I don't see how "people will learn" to tell whether that's a template, because there just fundamentally isn't enough information there to answer that question, and in real code the necessary information might be anywhere in the transitive #include graph.
auto plus = [](auto x, auto y) { return x+y; }
which even already decays to an ordinary pointer to function, etc.
That doesn't decay into a function pointer. It can't; the operator() is a template.
using fn = int (*)(int, int);
fn f = plus;
std::cout << f(2, 3) << std::endl;
From: Bjarne Stroustrup
Sent: Friday, March 6, 2015 1:14 PM
Reply To: c++st...@accu.org
Subject: [c++std-core-27227] Re: An implementation of enhanced auto deduction and abbreviated template syntax using Clang
|
struct X{int x;auto y;};
(Again, I'm not actually against 'auto means template function'; I just bring up counter arguments to be comfortable that we explored the design space and that we have a path of consistency going forward)
If all we need is auto, then is the next step:
struct X{int x;auto y;};
X is obviously a template
> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.
Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:
auto f() { … };
This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
Herb
PS – Since you mention “novices” writing templates, in my experience (and to my surprise) I’ve found that not only novices but also intermediate developers (like 5-7 year veterans) don’t write templates very much. [I expect this to change with concepts, for the good.] I discovered this by chance when I had a class exercise that included writing a very simple template, and as I walked through the class during the exercise I was surprised that most of the groups asked about the syntax for writing a template – a dead giveaway that they didn’t write templates very often, yet these were pretty experienced developers who used C++ every day, but just never needed to write templates much in their normal code. To validate that this wasn’t just an outlier group, I’ve watched that exercise in a number of classes over several years and found a similar result – the majority of even reasonably experienced C++ programmers asked about the syntax for how to write a template.
std::pair p{x, std::ref(y)}; // std::pair<X, Y&>
Reminds me of people complaining that they don't know which type Foo is in
void f(Foo);
and therefore they don't know what arguments it insists.
That can indeed be a real problem, but not one that I loose sleep over.
On Fri, Mar 6, 2015 at 10:27 AM, Herb Sutter <hsu...@microsoft.com> wrote:> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.
Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:
auto f() { … };
This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
Herb
PS – Since you mention “novices” writing templates, in my experience (and to my surprise) I’ve found that not only novices but also intermediate developers (like 5-7 year veterans) don’t write templates very much. [I expect this to change with concepts, for the good.] I discovered this by chance when I had a class exercise that included writing a very simple template, and as I walked through the class during the exercise I was surprised that most of the groups asked about the syntax for writing a template – a dead giveaway that they didn’t write templates very often, yet these were pretty experienced developers who used C++ every day, but just never needed to write templates much in their normal code. To validate that this wasn’t just an outlier group, I’ve watched that exercise in a number of classes over several years and found a similar result – the majority of even reasonably experienced C++ programmers asked about the syntax for how to write a template.
This very much matches my experience- as far as I can tell, the vast majority of C++ code is non-template code. But why is that surprising, and why do you expect concepts to change it?
This surprised me so I asked John offline what he meant, and I think we’re not in disagreement. You can’t call those unless there are (also) definitions.
What I said is correct: If auto (or a concept name) is used in the return type or parameter type, the definition must be available “in a header.” And this is already true for auto return types.
I did not mean to imply that you couldn’t also have a forward declaration too (which you can have for function templates but not for auto returns), but it still must be accompanied by a definition which was the point under discussion, namely that the definition still has to be available in the header.
Note that I’m excluding the “extern template” case, which is a special case and about controlling where instantiations occur (or limiting them) rather than about writing the generally usable function template itself… so IMO extern templates aren’t applicable to this question.
Herb
“if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
On Friday, March 6, 2015 at 2:27:23 PM UTC-5, Geoffrey Romer wrote:On Fri, Mar 6, 2015 at 10:27 AM, Herb Sutter <hsu...@microsoft.com> wrote:> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.
Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:
auto f() { … };
This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
Herb
PS – Since you mention “novices” writing templates, in my experience (and to my surprise) I’ve found that not only novices but also intermediate developers (like 5-7 year veterans) don’t write templates very much. [I expect this to change with concepts, for the good.] I discovered this by chance when I had a class exercise that included writing a very simple template, and as I walked through the class during the exercise I was surprised that most of the groups asked about the syntax for writing a template – a dead giveaway that they didn’t write templates very often, yet these were pretty experienced developers who used C++ every day, but just never needed to write templates much in their normal code. To validate that this wasn’t just an outlier group, I’ve watched that exercise in a number of classes over several years and found a similar result – the majority of even reasonably experienced C++ programmers asked about the syntax for how to write a template.
This very much matches my experience- as far as I can tell, the vast majority of C++ code is non-template code. But why is that surprising, and why do you expect concepts to change it?
That's my experience as well. However, I can also say that concepts is not what would get me to write more templates, as concepts (as it is currently proposed) only makes using templates easier (by declaring up-front what the requirements are). It doesn't make implementing a function easier (by checking each point of use to see if it is a required behavior).
Sorry for confusion, I was trying to word it generally to cover both auto returns (which we have already, so we already have a case where we require a definition without a keyword like “template” or “inline”) and the proposed auto parameter (only the latter makes a template).
The observation was that both the current and proposes uses of “auto” in the declaration would equally require a definition to be available in the header, and that simply saying that is a teachable rule.
Thanks,
On Fri, Mar 6, 2015 at 12:11 PM, Nicol Bolas <jmck...@gmail.com> wrote:
On Friday, March 6, 2015 at 2:27:23 PM UTC-5, Geoffrey Romer wrote:On Fri, Mar 6, 2015 at 10:27 AM, Herb Sutter <hsu...@microsoft.com> wrote:> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.
Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:
auto f() { … };
This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
Herb
PS – Since you mention “novices” writing templates, in my experience (and to my surprise) I’ve found that not only novices but also intermediate developers (like 5-7 year veterans) don’t write templates very much. [I expect this to change with concepts, for the good.] I discovered this by chance when I had a class exercise that included writing a very simple template, and as I walked through the class during the exercise I was surprised that most of the groups asked about the syntax for writing a template – a dead giveaway that they didn’t write templates very often, yet these were pretty experienced developers who used C++ every day, but just never needed to write templates much in their normal code. To validate that this wasn’t just an outlier group, I’ve watched that exercise in a number of classes over several years and found a similar result – the majority of even reasonably experienced C++ programmers asked about the syntax for how to write a template.
This very much matches my experience- as far as I can tell, the vast majority of C++ code is non-template code. But why is that surprising, and why do you expect concepts to change it?
That's my experience as well. However, I can also say that concepts is not what would get me to write more templates, as concepts (as it is currently proposed) only makes using templates easier (by declaring up-front what the requirements are). It doesn't make implementing a function easier (by checking each point of use to see if it is a required behavior).Interesting; my impression was the other way around, that concepts make it easier to write templates, but not really easier to use them. The main functional advantage that I see with concepts is that they let you control the overload set much more easily (and much more readably), and that helps template authors, not template users. I see your point about declaring the requirements up-front, but decent template libraries already do that in the documentation; I'm not sure that formalizing those requirements in code will really help users much.
On Friday, March 6, 2015 at 4:25:51 PM UTC-5, Geoffrey Romer wrote:On Fri, Mar 6, 2015 at 12:11 PM, Nicol Bolas <jmck...@gmail.com> wrote:
On Friday, March 6, 2015 at 2:27:23 PM UTC-5, Geoffrey Romer wrote:On Fri, Mar 6, 2015 at 10:27 AM, Herb Sutter <hsu...@microsoft.com> wrote:> To the novice C++ programmer, it isn't "all just programming." Whether something is a template matters.
Why? Only because of where you put the definition, and that’s (a) teachable and (b) not new because the same issue exists already with:
auto f() { … };
This is not a template, but must appear in a header. This is amazingly similar – and easy to teach as “if the declaration mentions ‘auto’ or a concept name, the compiler needs the definition, either to deduce something or to inline the body into the caller.” Right?
Herb
PS – Since you mention “novices” writing templates, in my experience (and to my surprise) I’ve found that not only novices but also intermediate developers (like 5-7 year veterans) don’t write templates very much. [I expect this to change with concepts, for the good.] I discovered this by chance when I had a class exercise that included writing a very simple template, and as I walked through the class during the exercise I was surprised that most of the groups asked about the syntax for writing a template – a dead giveaway that they didn’t write templates very often, yet these were pretty experienced developers who used C++ every day, but just never needed to write templates much in their normal code. To validate that this wasn’t just an outlier group, I’ve watched that exercise in a number of classes over several years and found a similar result – the majority of even reasonably experienced C++ programmers asked about the syntax for how to write a template.
This very much matches my experience- as far as I can tell, the vast majority of C++ code is non-template code. But why is that surprising, and why do you expect concepts to change it?
That's my experience as well. However, I can also say that concepts is not what would get me to write more templates, as concepts (as it is currently proposed) only makes using templates easier (by declaring up-front what the requirements are). It doesn't make implementing a function easier (by checking each point of use to see if it is a required behavior).Interesting; my impression was the other way around, that concepts make it easier to write templates, but not really easier to use them. The main functional advantage that I see with concepts is that they let you control the overload set much more easily (and much more readably), and that helps template authors, not template users. I see your point about declaring the requirements up-front, but decent template libraries already do that in the documentation; I'm not sure that formalizing those requirements in code will really help users much.
You assume that users actually read that documentation. Or remember it when they read it.
If someone gives you an abstract base class to implement, the requirements are listed right there, in the language. You have to derive from that class; derive from the wrong one, and you'll get a compiler error somewhere. You have to override all pure-virtual methods; type the method name wrong, and you get a compiler error somewhere (either due to the class still being abstract or because you used "override" and there was no base class function). And so forth.
If I give a non-moveable type to std::vector<T>, it will give me some kind of compiler error. What kind? God only knows, but more likely than not, it will be long, obtuse, and generally indecipherable if you've never seen it before. This is because the compilation failure happens somewhere in the instantiation of std::vector<T> when it tries to actually use your type in a way that it can't be used. So the compiler will point to the guts of std::vector<T>'s implementation, rather than at your code where the actual mistake was made.
If I give a non-moveable type to std::vector<MoveConstructable>, it will give me a much cleaner error message. With a semi-decent compiler, it'll point you right to the line where you instantiated your std::vector and say "Hey, your type T isn't MoveConstructable, because it doesn't have a move constructor." At the very least, I won't get a giant spew of template stuff.
Concepts are great at telling me what I did wrong when I misuse a template. Which means I will feel much more confident that, if it compiled, I'm using the template correctly.
If all we need is auto, then is the next step:
struct X{int x;auto y;};
X is obviously a template?So is Y:
struct Y{int x;ForwardIterator y;};
?
(Again, I'm not actually against 'auto means template function'; I just bring up counter arguments to be comfortable that we explored the design space and that we have a path of consistency going forward)
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.--
---
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
From: David Rodríguez Ibeas
Sent: Saturday, March 7, 2015 4:21 PM
Reply To: c++st...@accu.org
Subject: [c++std-core-27261] Re: [std-discussion] Re: Re: An implementation of enhanced auto deduction and abbreviated template syntax using Clang
|