Topic: Proposal: two real uses for the "auto" keyword


Author: "Andrei Alexandrescu" <andrewalex@Hotmail.com>
Date: Mon, 2 Apr 2001 11:54:38 CST
Raw View
"Marco Manfredini" <marco@technoboredom.net> wrote in message
news:Xns90705A5C9D09Cmarcotechnobore@technoboredom.net...
> const auto & tmp = (a+b)/(c-d);

What about creating static variables without knowing their type.


Andrei


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "David Abrahams" <abrahams@mediaone.net>
Date: Mon, 2 Apr 2001 11:55:47 CST
Raw View
"Vladimir Prus" <ghost@cs.msu.su> wrote in message
news:aji1a9.kp.ln@158.250.10.247...
>
> David Abrahams wrote:
>
> >I propose that the "auto"
> >keyword be available to declare variables whose type is deduced from the
> >type of the expression with which they are initialized:
>
> >auto tmp = (a+b)/(c-d);
>
> First of all, I'd like to note that there's yet another use of  'auto'
the
> original post hasn't mentioned:
>
>         template<class T1, class T2>
>         auto foo(const T1& t1, const T2& t2)
>         {
>                 return t1 + t2;
>         }

I note firstly that my original proposal has a weakness: it is not really
appropriate for inferred type declarations at namespace scope, since the
'auto' has an existing meaning as a storage class.

That said, I don't like the proposal above too much because 'auto' might
conflict with the storage class of the return value in this case, and you
can't declare a function's storage class to be auto (see the original post).
On the other hand, since 'auto' is really optional, it might make sense to
expand the places where it is legal.

Your proposal also has another, more important problem: the interface of the
function is tied to the implementation more strongly than:

template <class T1, class T2>
typeof(T1() + T2()) foo()(const T1& t1, const T2& t2);

The compiler should be able to deduce the return type of a function template
from its declaration alone. On the other hand, the above requires T1 and T2
to be default-constructible, which is an undesired constraint. I'm not sure
what the best solution for this case might be. Maybe the compiler should be
allowed to use names from the argument list in typeof() expressions for the
return type:

template <class T1, class T2>
typeof(t1+t2) foo()(const T1& t1, const T2& t2);

> Such feature would greatly facilitate writing lambda libraries and their
> use. Actulually, I'd like to see lambda keyword in the language tomorrow,
> but that been impossible, auto is simple to implement and usefull addition
> for now.
>
> Second, it seems to me that 'auto' is little misleading. Better name would
> be 'infered', according to functional programming terms.

Well, yes, that's part of my argument against it in this case - it doesn't
indicate storage class. All the same, adding new keywords is problematic
because it breaks existing code.

-Dave



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 2 Apr 2001 11:57:46 CST
Raw View
In article <aji1a9.kp.ln@158.250.10.247>, Vladimir Prus
<ghost@cs.msu.su> writes
>Second, it seems to me that 'auto' is little misleading. Better name would
>be 'infered', according to functional programming terms.

But we have to be very careful about introducing new keywords. However
at a recent BSI C++ Standards Panel meeting (held in an Oxford hostelry,
which may be significant) we realised that we have a whole raft of
potential keywords that will not possibly break existing code. Consider:

#include <algorithm>
using namespace std;
~using std::sort;

Do I even need to explain what such code would do? :)

And think how useful a ~using directive would be to undo the damage
caused by an idiot programmer who has used using directives
inappropriately.



--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Ney Andr de Mello Zunino" <zunino@ias.unu.edu>
Date: Tue, 3 Apr 2001 13:54:43 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:4ZvL68C9O6x6Ew$F@ntlworld.com...
>
> #include <algorithm>
> using namespace std;
> ~using std::sort;
>
> Do I even need to explain what such code would do? :)

Hey, that looks nice and useful! I really like the idea. And I would even
take the opportunity to suggest a very simple change in the grammar of the
language to allow using declarations to be given a list of symbols, instead
of a single one. This, of course, would also apply to ~using.

// The way we must do now:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

// How it could be:
#include <iostream>
using std::cin, std::cout, std::endl;

// Same for ~using:
#include <algorithm>
~using std::sort, std::slice;

This is something I have wished for long and Mr. Francis' post just reminded
me of that.

Best regards,

Ney Andr    de Mello Zunino.

"Take of the fruit,
    But guard the seed..."




---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Vladimir Prus <ghost@cs.msu.su>
Date: Tue, 3 Apr 2001 15:47:36 GMT
Raw View
David Abrahams wrote:

>> First of all, I'd like to note that there's yet another use of  'auto'
> the
>> original post hasn't mentioned:
>>
>>         template<class T1, class T2>
>>         auto foo(const T1& t1, const T2& t2)
>>         {
>>                 return t1 + t2;
>>         }

> Your proposal also has another, more important problem: the interface of
> the function is tied to the implementation more strongly than:
>
> template <class T1, class T2>
> typeof(T1() + T2()) foo()(const T1& t1, const T2& t2);
>
> The compiler should be able to deduce the return type of a function
> template from its declaration alone.

This is not exactly what I propose. 'inferred' should be allowed as return
type *only* if body is given. Really, this requires some change to the
language semantics.

        template<class T>
        struct S {
                int f1() {}
                infered f2() { .... }
                template<class T2>
                something<T2> f3() { ... }
        };
Here f2 is not a member template, but the declaration can be fully known
only when f2 is instantinated, and not when S is instantinated, as is the
case with f1. But I don't see any better way.
(BTW another proposed syntax,
        template<typename T> T f2() {}
more clearly indicates semantics,  but it is too verbose for me)

>> Second, it seems to me that 'auto' is little misleading. Better name
>> would be 'infered', according to functional programming terms.
>
> Well, yes, that's part of my argument against it in this case - it doesn't
> indicate storage class. All the same, adding new keywords is problematic
> because it breaks existing code.

Is there any choice? Lambda libraries now try to provide construct
*parallel* to those present in language. Of course they have wierd look,
not powerfull enough and don't always work. I think that adding a keyword
or two might be better.

--
Regards,
Vladimir

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Wed, 4 Apr 2001 14:53:41 CST
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message news:4ZvL68C9O6x6Ew$F@ntlworld.com...

> #include <algorithm>
> using namespace std;
> ~using std::sort;
>
> Do I even need to explain what such code would do? :)

Will that apply to all sorts of nemes? Like in the situation:

{
    Object x;
// ... set up x;
    const typeof(x) & x_ = x;
    ~using x;  // hides x
}
?

Paul

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Mark Blewett <mblewett@nildram.co.uk>
Date: Wed, 28 Mar 2001 15:33:16 CST
Raw View
On Sun, 25 Mar 2001 17:28:51 GMT, marco@technoboredom.net (Marco
Manfredini) wrote:

>"David Abrahams" <abrahams@mediaone.net> wrote in
><052201c0b4ab$603e8050$0500a8c0@dragonsys.com>:
>
>>The overloading of keywords in C++ is often cited as a nasty problem
>>(c.f. "static", which means a half-dozen different things in
>>different contexts). An even nastier problem is that we can't add
>>any new keywords without breaking user code, which makes future
>>language extensions difficult. There is, however, at least one
>>keyword hanging around which is underloaded**: "auto".
>[snip]
>
>I like proposed usage #2 most!! Finally I can write:
>
>vector<int> v;
>for (auto i=v.begin(); i!=v.end(); i++) { ... ]
>
>But I have a different suggestion for #2, that would involve an overload
>of the template keyword.
>
>Take the example above. I'd suggest that one can write:
>vector<int> v;
>for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
>
>This usage of template instructs the compiler to deduce T as the type of
>v.begin() and use T as the type to declare i.

Sorry I disagree with both suggestions.

For example (a generic version of the above);

StartT start =...;
EndT end = ...;
for (template<typename T> T i=start; i!=end; i++) { ... }

What if start and end are different types? What should T be? StartT?
EndT? Another compatible type? Too complex for a compiler and/or user
to determine IMHO.

Rather than

for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }

how about

for (v::iterator i=v.begin(); i!=v.end(); i++) { ... }

>In other words, using
>template in a variable declaration works quite the way as 'template' in
>a template function declaration. The nice thing is, that T is now a
>typename which is valid for the scope of the declaration, which means,
>that I can do things like these:
>
>int k;
>// declares int i and vector<int> vi;
>template<typename T> T i=k, vector<T> vi;
>
>// declares vector<int> &k and int x;
>template<typename K> vector<K> &k=vi, K x;
>
>// declares vector<int>::iterator it and int r
>template<typename X> X it=k.begin(), iterator_traits<X>::value_type &r;

I can't see the value in the above apart from adding more complexity
to the language. Could you give examples on how the above are used,
and not just declared. Do you gain anything?

>
>'auto' could then be useful as a identifier placeholder for
>interference:
>
>int inarray[10];
>/* If I want to decompose the type of inarray, I'd need to declare an
>identifier here, which is needed to build the expressions tree on which
>the deduction takes place. 'auto' plays the role of an "anonymous"
>identifier, which isn't really declared. */
>template<typename Type,int Size> Type auto[Size]=intarray;

Think of it from a design pov. Why is inarray 10 elements? Why are
they ints? IMHO you should build complex types from basic types, not
the other way around.

>/* The deduction introduces "Type" as int and Size as a const integer
>expression which is valued 10. */
>double p[Size]; /* declare an array of the same size of inarray. This
>looks much better than 'double p[sizeof(inarray)/sizeof(int)]'  */
>vector<Type> t; /* a vector<int> */
>
>Comments? Suggestions?

I'm not conviced.

Regards
Mark

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Vladimir Prus <ghost@cs.msu.su>
Date: Fri, 30 Mar 2001 19:57:09 GMT
Raw View
David Abrahams wrote:

>I propose that the "auto"
>keyword be available to declare variables whose type is deduced from the
>type of the expression with which they are initialized:

>auto tmp = (a+b)/(c-d);

First of all, I'd like to note that there's yet another use of  'auto'  the
original post hasn't mentioned:

        template<class T1, class T2>
        auto foo(const T1& t1, const T2& t2)
        {
                return t1 + t2;
        }

Such feature would greatly facilitate writing lambda libraries and their
use. Actulually, I'd like to see lambda keyword in the language tomorrow,
but that been impossible, auto is simple to implement and usefull addition
for now.

Second, it seems to me that 'auto' is little misleading. Better name would
be 'infered', according to functional programming terms.

Mark Blewett wrote:

>
> Sorry I disagree with both suggestions.
>
> For example (a generic version of the above);
>
> StartT start =...;
> EndT end = ...;
> for (template<typename T> T i=start; i!=end; i++) { ... }
>
> What if start and end are different types? What should T be? StartT?
> EndT? Another compatible type? Too complex for a compiler and/or user
> to determine IMHO.

Not at all!  Precise semantic for auto/infered can be similar to that
already given in post by Marco Manfredini:

1) auto/infered can only appear in definition of variable with initializer
or in function definition, at position where type name is allowed by the
grammar.

        ... infered ... var = e;
is equvivalent to
        ... typeof(e) ... var = e;
Such semantic means that 'infered' is *nothing but syntax sugar*, but a
very good one.

2) for functions returning expressions e1, en, it should hold that
        typeof(e1) == ... == typeof(en)
and infered will be the same at typeof(e1)

Compiler can apply those rules very easily.

> how about
> for (v::iterator i=v.begin(); i!=v.end(); i++) { ... }

That's just the same as
        for (typeof(v)::iterator .....)
so this is another syntax sugar. Don't know whether we need it.


--
Regards,
Vladimir

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: pedwards@dmapub.dma.org (Phil Edwards)
Date: Mon, 26 Mar 2001 03:58:39 GMT
Raw View
David Abrahams <abrahams@mediaone.net> wrote:
> Proposed usage #1
[...]
> Right now, it is a
> syntax error to write:
>
>    auto deque<string> coll3(istream_iterator<string>(cin), // 3
>                             istream_iterator<string>());
>
> because "auto" is an illegal storage class for a function declaration. I
> propose that #3 become a legal synonym for #2. It's much easier, IMO, to
> understand how it works in disambiguating the declaration.

I sincerely hope that this proposal makes its way into the language.
It solves a real problem.  Adding a "redundant" pair of parenthesis is,
frankly, embarassing.  As this construction idiom becomes more and more
common, C++ will look more and more like these issues weren't thought all
the way through.

For what it's worth, the last time I had to explain this particular ambiguity
to a group of students, a group of them told me that they had tried on their
own initiative to resolve the ambiguity by adding "auto" to their code in
exactly this manner, because "it seemed like the obvious thing to do."  !!


Luck++;
Phil

--
pedwards at disaster dot jaj dot com  |  pme at sources dot redhat dot com
devphil at several other less interesting addresses in various dot domains
The gods do not protect fools.  Fools are protected by more capable fools.

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: gt5163b@prism.gatech.edu (Brian McNamara!)
Date: Mon, 26 Mar 2001 06:31:13 GMT
Raw View
I think this is an outstanding proposal.  Thus I'll do my best to play
devil's advocate and attempt to find problems with it.

"David Abrahams" <abrahams@mediaone.net> once said:
>serve to disambiguate it as an expression-statement. Right now, it is a
>syntax error to write:
>
>
>   auto deque<string> coll3(istream_iterator<string>(cin), // 3
>                            istream_iterator<string>());
>
>because "auto" is an illegal storage class for a function declaration. I
>propose that #3 become a legal synonym for #2. It's much easier, IMO, to
>understand how it works in disambiguating the declaration.

Does this work (not do anything "bad") for declaring function pointers,
and/or references too?  (I think it does, but declaring pointers to
functions, and declaring functions that return pointers to array fo
functions and horrible things like that... it's all beyond my general
understanding.  So my real question is something like "can you rewrite
the grammar to ensure this is possible without causing new
ambiguities?"  I think yes, but it would strengthen the proposal much
to do so.)

(As an aside, I am curious why function declarations are even allowed
inside functions.)

>In the world of high-performance numeric computation, the use of Expression
>Templates
>(http://www.extreme.indiana.edu/~tveldhui/papers/Expression-Templates/exprtm
>pl.html) allows us to obtain the highest performance from matrix expressions
>written in natural mathematical notation. Expression Templates work by
>delaying expression evaluation and allowing the numerics library to examine
>the structure of the computation at compile time, applying optimizations.
>The ability to use natural mathematical notation makes for simple code and
>easier maintenance, but a detail of the C++ type system prevents us from
>fully realizing that goal.
>
>Expression templates generate complicated types which encapsulate the
>expression's parse tree. An example from the paper referenced above:
>
>the expression "(a+b)/(c-d)" is of type
>DVExpr<DVBinExprOp<DVExpr< DVBinExprOp<DVec::iterT, DVec::iterT, DApAdd>>,
>DVExpr<DVBinExprOp< DVec::iterT, DVec::iterT, DApSubtract>>, DApDivide>>
>
>It is a common rule that for readable and maintainable code, complicated
>expressions should be broken up into smaller ones, but with expression
>templates this is obviously impractical, because we would have to declare
>variables to hold intermediate results. If (a+b)/(c-d) were part of a larger
>expression that we wanted to evaluate separately, we'd have to declare an
>intermediate variable of the type shown above.

Note also that expression-templates are not the only place this crops
up.  In the FC++ library, "direct functoids" which are created via
currying and composition also exhibit this same problem all the time.
Also, I have experienced this problem when using the View Template
Library.  So, to any other readers: don't think that this is a solution
that "only helps the expression-template people".  This is a common
problem that arises in a number of disparate domains (which have only
"templates" in common).  And the problems apply to client/user code--
not just to implementation code that's hidden inside these libraries.

>I propose that the "auto"
>keyword be available to declare variables whose type is deduced from the
>type of the expression with which they are initialized:
>
>auto tmp = (a+b)/(c-d);
>
>Allowing this usage would neatly solve the problem described above, and
>would make a neat companion to the proposed typeof() keyword.

Terrific.  My hunch is that all of us waiting on the typeof() keyword
(and there are a fair number of us) were about to add

   #define DECLARE(var,value)    ; typeof(value) var = value;

or some similar horror to try to deal with this.  Your idea is a much
better way to deal with this.


But as promised, I must try to break it.  So,

First: are you sure this doesn't conflict with the first proposal (the
deque example)?  I think it's ok.  However...

Second: Instead of and/or in addition to
   auto tmp = (a+b)/(c-d);
should
   auto tmp( (a+b)/(c+d) );
be allowed too?  This allows for "explicit" constructors, too.  It might
be a shame if "magic 'auto' typing" only worked for types with implicit
copy constructors.

Third: Is there a way to add cv-qualifiers or reference-ness?  In other
words, can I do something like
   auto const& tmp = (a+b)/(c-d);
This would also be nice, as well as potentially more practical for some
of the intended uses.  (There aren't any "implicit int"s left in the
language trying to get in the way, are there?)

Fourth: If either "Second" or "Third" or both look ok, do the
combinations of the new proposals create any new ambiguity?  (In other
words, if my added suggestions pass, "First" must be revisited.)


I thought my
   Error<compile_time_bool,"User defined conditional error message">
idea was good--but this one is even better!  If any compiler implementor
adds both this extension and my user-defined error messages idea, I will
be happy to purchase that compiler and quit using g++, even if I have to
pay out the nose.  I am dying for these features!

--
 Brian M. McNamara   lorgon@acm.org  :  I am a parsing fool!
   ** Reduce - Reuse - Recycle **    :  (Where's my medication? ;) )

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 26 Mar 2001 06:34:50 GMT
Raw View
In article <Xns906FC4EAFCB49marcotechnobore@technoboredom.net>, Marco
Manfredini <marco@technoboredom.net> writes
>But I have a different suggestion for #2, that would involve an overload
>of the template keyword.
>
>Take the example above. I'd suggest that one can write:
>vector<int> v;
>for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
>
>This usage of template instructs the compiler to deduce T as the type of
>v.begin() and use T as the type to declare i. In other words, using
>template in a variable declaration works quite the way as 'template' in
>a template function declaration.

uses of the 'template' keyword are already ugly enough as well as
dealing with one of the more complex areas of the language so I would
not advocate any more meanings for it, not now, not ever.


--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "David Abrahams" <abrahams@mediaone.net>
Date: Mon, 26 Mar 2001 06:36:55 GMT
Raw View
"Marco Manfredini" <marco@technoboredom.net> wrote in message
news:Xns906FC4EAFCB49marcotechnobore@technoboredom.net...
> I like proposed usage #2 most!! Finally I can write:
>
> vector<int> v;
> for (auto i=v.begin(); i!=v.end(); i++) { ... ]

Yes, it would simplify that code, too.

> But I have a different suggestion for #2, that would involve an overload
> of the template keyword.
>
> Take the example above. I'd suggest that one can write:
> vector<int> v;
> for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
>
> This usage of template instructs the compiler to deduce T as the type of
> v.begin() and use T as the type to declare i. In other words, using
> template in a variable declaration works quite the way as 'template' in
> a template function declaration. The nice thing is, that T is now a
> typename which is valid for the scope of the declaration, which means,
> that I can do things like these:
>
> int k;
> // declares int i and vector<int> vi;
> template<typename T> T i=k, vector<T> vi;
>
> // declares vector<int> &k and int x;
> template<typename K> vector<K> &k=vi, K x;
>
> // declares vector<int>::iterator it and int r
> template<typename X> X it=k.begin(), iterator_traits<X>::value_type &r;

People have been proposing the use of a typeof() operator for this purpose

int k;
// declares int i and vector<int> vi;
auto i=k, vector<typeof(i)> vi;

// declares vector<int> &k and int x;
typeof(vi) &k=vi;
vi::value_type x;

// declares vector<int>::iterator it and int r
auto it=k.begin(), iterator_traits<typeof(it)>::value_type &r;

I guess I prefer the use of auto with typeof in most cases. It seems much
simpler.

> 'auto' could then be useful as a identifier placeholder for
> interference:
>
> int inarray[10];
> /* If I want to decompose the type of inarray, I'd need to declare an
> identifier here, which is needed to build the expressions tree on which
> the deduction takes place. 'auto' plays the role of an "anonymous"
> identifier, which isn't really declared. */
> template<typename Type,int Size> Type auto[Size]=intarray;

Okay, now I really don't like the proposal. The fact that this doesn't
really initialize a variable, but instead produces a compile-time const int
really rubs me the wrong way.

> /* The deduction introduces "Type" as int and Size as a const integer
> expression which is valued 10. */
> double p[Size]; /* declare an array of the same size of inarray. This
> looks much better than 'double p[sizeof(inarray)/sizeof(int)]'  */
> vector<Type> t; /* a vector<int> */

This bit is a problem with a known, existing solution in the current C++
language.

-Dave



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 26 Mar 2001 14:03:09 GMT
Raw View
In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
<gt5163b@prism.gatech.edu> writes
>(As an aside, I am curious why function declarations are even allowed
>inside functions.)

Almost certainly for compatibility with C.


--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: marco@technoboredom.net (Marco Manfredini)
Date: Mon, 26 Mar 2001 16:45:03 GMT
Raw View
gt5163b@prism.gatech.edu (Brian McNamara!) wrote in
<99l3nf$7n0$1@news-int.gatech.edu>:


>Third: Is there a way to add cv-qualifiers or reference-ness?  In
>other words, can I do something like
>   auto const& tmp = (a+b)/(c-d);
>This would also be nice, as well as potentially more practical for
>some of the intended uses.  (There aren't any "implicit int"s left
>in the language trying to get in the way, are there?)

I think auto could be positioned as a placeholder for the right-hand
type. Such that:
{X}={Y};

can be rewritten as

{X/auto=typeof(Y)}=Y;

In that case cv would come up quite naturally, like:

const auto & tmp = (a+b)/(c-d);

Anything else looks more complicated, since whatever type I declare on
the lhs, it must be initializable with the rhs.

>
>I thought my
>   Error<compile_time_bool,"User defined conditional error message">
>idea was good--but this one is even better!  If any compiler
>implementor adds both this extension and my user-defined error
>messages idea, I will be happy to purchase that compiler and quit
>using g++, even if I have to pay out the nose.  I am dying for these
>features!
>

g++ already has typeof() and I think that auto can be hacked into it
easily (for someone who is into the source).

--
Marco

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Mon, 26 Mar 2001 19:18:29 GMT
Raw View
"Phil Edwards" <pedwards@dmapub.dma.org> wrote

> I sincerely hope that this proposal makes its way into the language.

Same hope here with addition "ASAP". And in company of typeof().

Paul


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Mon, 26 Mar 2001 23:44:29 GMT
Raw View
Francis Glassborow wrote:
>
> In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
> <gt5163b@prism.gatech.edu> writes
> >(As an aside, I am curious why function declarations are even allowed
> >inside functions.)
>
> Almost certainly for compatibility with C.

Would it be sensible to consider deprecating this feature,
or removing it altogether?  It seems to give no significant
benefit, and plenty of pain.

-- James Dennett

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Marco Manfredini <marco@technoboredom.net>
Date: Tue, 27 Mar 2001 00:06:05 GMT
Raw View
David Abrahams wrote:

> Okay, now I really don't like the proposal.

Francis Glassborow wrote:

> uses of the 'template' keyword are already ugly enough as well as
> dealing with one of the more complex areas of the language so I would
> not advocate any more meanings for it, not now, not ever.
>

Oh boy, good that I'm going on vacation on thursday - I feel like a loony
making stupid rants that everybody hates :-)

Just for the records, I felt it was a good idea, when I remembered from my
CS student & scheme days, that local variable declarations (and everything
else) can easily be transformed into nestes functions . Having this in my
lobe, I found function templates and declaration "templates" are the same
thing too -- and I really found it *beautiful*

--
Marco

And everything must be LAMBDA-CALCULUS when I'm back!! Listen!!!


---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 27 Mar 2001 07:03:28 CST
Raw View
In article <3ABF4E68.14646D4E@acm.org>, James Dennett <jdennett@acm.org>
writes
>Francis Glassborow wrote:
>>
>> In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
>> <gt5163b@prism.gatech.edu> writes
>> >(As an aside, I am curious why function declarations are even allowed
>> >inside functions.)
>>
>> Almost certainly for compatibility with C.
>
>Would it be sensible to consider deprecating this feature,
>or removing it altogether?  It seems to give no significant
>benefit, and plenty of pain.

I think the pain would still be there unless you want to deprecate
member function declarations in classes:)

--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Risto Lankinen" <rlankine@hotmail.com>
Date: Tue, 27 Mar 2001 12:49:48 CST
Raw View
Hi!

James Dennett <jdennett@acm.org> wrote in message
news:3ABF4E68.14646D4E@acm.org...
> Francis Glassborow wrote:
> >
> > In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
> > <gt5163b@prism.gatech.edu> writes
> > >(As an aside, I am curious why function declarations are even allowed
> > >inside functions.)
> >
> > Almost certainly for compatibility with C.
>
> Would it be sensible to consider deprecating this feature,
> or removing it altogether?  It seems to give no significant
> benefit, and plenty of pain.

The "benefit" is the ability to do overloaded function
selection in a local scope, by utilizing the name hiding
phenomenon.  For example, the program...

void f(int);
void f(bool);

void main()
{
  void f(bool);

  f(1);
  f(false);
}

... changes its behaviour when the declaration inside
the main()'s function block is removed.

Cheers!

 - Risto -



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Tue, 27 Mar 2001 16:37:46 CST
Raw View
"James Dennett" <jdennett@acm.org> wrote in message
news:3ABF4E68.14646D4E@acm.org...
> Francis Glassborow wrote:
> >
> > In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
> > <gt5163b@prism.gatech.edu> writes
> > >(As an aside, I am curious why function declarations are even allowed
> > >inside functions.)
> >
> > Almost certainly for compatibility with C.
>
> Would it be sensible to consider deprecating this feature,
> or removing it altogether?  It seems to give no significant
> benefit, and plenty of pain.
>

I would like to see it extended to allow proper nested functions, and
(whilst I'm at it) for local classes to have linkage so they can be used
with templates.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Tue, 27 Mar 2001 17:08:44 CST
Raw View
Risto Lankinen wrote:
>
> Hi!
>
> James Dennett <jdennett@acm.org> wrote in message
> news:3ABF4E68.14646D4E@acm.org...
> > Francis Glassborow wrote:
> > >
> > > In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
> > > <gt5163b@prism.gatech.edu> writes
> > > >(As an aside, I am curious why function declarations are even allowed
> > > >inside functions.)
> > >
> > > Almost certainly for compatibility with C.
> >
> > Would it be sensible to consider deprecating this feature,
> > or removing it altogether?  It seems to give no significant
> > benefit, and plenty of pain.
>
> The "benefit" is the ability to do overloaded function
> selection in a local scope, by utilizing the name hiding
> phenomenon.

I'm glad you wrote "benefit" in quotation marks.  I'd love to
get rid of such ugly code at the same time as fixing a real
problem.

> For example, the program...
>
> void f(int);
> void f(bool);
>
> void main()
> {
>   void f(bool);
>
>   f(1);
>   f(false);
> }
>
> ... changes its behaviour when the declaration inside
> the main()'s function block is removed.

int main, blah blah blah.

-- James Dennett

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Tue, 27 Mar 2001 18:37:56 CST
Raw View
Francis Glassborow wrote:
>
> In article <3ABF4E68.14646D4E@acm.org>, James Dennett <jdennett@acm.org>
> writes
> >Francis Glassborow wrote:
> >>
> >> In article <99l3nf$7n0$1@news-int.gatech.edu>, Brian McNamara!
> >> <gt5163b@prism.gatech.edu> writes
> >> >(As an aside, I am curious why function declarations are even allowed
> >> >inside functions.)
> >>
> >> Almost certainly for compatibility with C.
> >
> >Would it be sensible to consider deprecating this feature,
> >or removing it altogether?  It seems to give no significant
> >benefit, and plenty of pain.
>
> I think the pain would still be there unless you want to deprecate
> member function declarations in classes:)

How so?  It's not legal to initialize non-static data members of
classes, so there's no chance of confusing an initialized data member
with a method declaration.  The only initializations we allow in
class definitions are for integral types, IIRC.  As far as I can
see, there's no possibility of the problematic ambiguity arising
inside a class definition.

If I'm wrong, I'm sure you (or another language lawyer ;) will
detail why.

-- James Dennett

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "David Abrahams" <abrahams@mediaone.net>
Date: Sun, 25 Mar 2001 04:55:52 GMT
Raw View
The overloading of keywords in C++ is often cited as a nasty problem (c.f.
"static", which means a half-dozen different things in different contexts).
An even nastier problem is that we can't add any new keywords without
breaking user code, which makes future language extensions difficult. There
is, however, at least one keyword hanging around which is underloaded**:
"auto".

auto is a syntactic relic from 'C' whose use is never neccessary. It can be
used as a storage class specifier (just like "static") to mean, informally,
"put this on the stack". Since variables are put on the stack by default in
all contexts where "auto" can be used, it is completely redundant to write
auto and everyone*** leaves it out. As long as we have "auto", however, I
think we ought to put it to work.

Proposed usage #1
=================

We've all probably been bitten by the rule that "if it looks like a function
declaration, it is a function declaration" (6.8 in the standard). This
example borrowed from Herb Sutter at http://www.gotw.ca/gotw/075.htm:

   deque<string> coll3(istream_iterator<string>(cin), // 1
                       istream_iterator<string>());

The standard approach to fixing the problem is to add an additional set of
parentheses around any of the function's arguments:

    deque<string> coll3((istream_iterator<string>(cin)), // 2
                        istream_iterator<string>());


Unfortunately, where to place the parentheses is hard to remember (around
one argument? around all arguments?), and it is thoroughly non-obvious why
the extra parentheses around the argument name (cin) in the first case don't
serve to disambiguate it as an expression-statement. Right now, it is a
syntax error to write:


   auto deque<string> coll3(istream_iterator<string>(cin), // 3
                            istream_iterator<string>());

because "auto" is an illegal storage class for a function declaration. I
propose that #3 become a legal synonym for #2. It's much easier, IMO, to
understand how it works in disambiguating the declaration.

Proposed usage #2
=================

In the world of high-performance numeric computation, the use of Expression
Templates
(http://www.extreme.indiana.edu/~tveldhui/papers/Expression-Templates/exprtm
pl.html) allows us to obtain the highest performance from matrix expressions
written in natural mathematical notation. Expression Templates work by
delaying expression evaluation and allowing the numerics library to examine
the structure of the computation at compile time, applying optimizations.
The ability to use natural mathematical notation makes for simple code and
easier maintenance, but a detail of the C++ type system prevents us from
fully realizing that goal.

Expression templates generate complicated types which encapsulate the
expression's parse tree. An example from the paper referenced above:

the expression "(a+b)/(c-d)" is of type
DVExpr<DVBinExprOp<DVExpr< DVBinExprOp<DVec::iterT, DVec::iterT, DApAdd>>,
DVExpr<DVBinExprOp< DVec::iterT, DVec::iterT, DApSubtract>>, DApDivide>>

It is a common rule that for readable and maintainable code, complicated
expressions should be broken up into smaller ones, but with expression
templates this is obviously impractical, because we would have to declare
variables to hold intermediate results. If (a+b)/(c-d) were part of a larger
expression that we wanted to evaluate separately, we'd have to declare an
intermediate variable of the type shown above. I propose that the "auto"
keyword be available to declare variables whose type is deduced from the
type of the expression with which they are initialized:

auto tmp = (a+b)/(c-d);

Allowing this usage would neatly solve the problem described above, and
would make a neat companion to the proposed typeof() keyword.

-Dave

** credit to Andy Sawyer for first applying the "underloaded" label to
"auto"
*** I have never seen a program outside of a book on the language that used
"auto"



---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: marco@technoboredom.net (Marco Manfredini)
Date: Sun, 25 Mar 2001 17:28:51 GMT
Raw View
"David Abrahams" <abrahams@mediaone.net> wrote in
<052201c0b4ab$603e8050$0500a8c0@dragonsys.com>:

>The overloading of keywords in C++ is often cited as a nasty problem
>(c.f. "static", which means a half-dozen different things in
>different contexts). An even nastier problem is that we can't add
>any new keywords without breaking user code, which makes future
>language extensions difficult. There is, however, at least one
>keyword hanging around which is underloaded**: "auto".
[snip]

I like proposed usage #2 most!! Finally I can write:

vector<int> v;
for (auto i=v.begin(); i!=v.end(); i++) { ... ]

But I have a different suggestion for #2, that would involve an overload
of the template keyword.

Take the example above. I'd suggest that one can write:
vector<int> v;
for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }

This usage of template instructs the compiler to deduce T as the type of
v.begin() and use T as the type to declare i. In other words, using
template in a variable declaration works quite the way as 'template' in
a template function declaration. The nice thing is, that T is now a
typename which is valid for the scope of the declaration, which means,
that I can do things like these:

int k;
// declares int i and vector<int> vi;
template<typename T> T i=k, vector<T> vi;

// declares vector<int> &k and int x;
template<typename K> vector<K> &k=vi, K x;

// declares vector<int>::iterator it and int r
template<typename X> X it=k.begin(), iterator_traits<X>::value_type &r;

'auto' could then be useful as a identifier placeholder for
interference:

int inarray[10];
/* If I want to decompose the type of inarray, I'd need to declare an
identifier here, which is needed to build the expressions tree on which
the deduction takes place. 'auto' plays the role of an "anonymous"
identifier, which isn't really declared. */
template<typename Type,int Size> Type auto[Size]=intarray;

/* The deduction introduces "Type" as int and Size as a const integer
expression which is valued 10. */
double p[Size]; /* declare an array of the same size of inarray. This
looks much better than 'double p[sizeof(inarray)/sizeof(int)]'  */
vector<Type> t; /* a vector<int> */

Comments? Suggestions?

--
Marco

---
[ 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.research.att.com/~austern/csc/faq.html                ]