Topic: Language feature suggested to avoid typedefs.


Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/27
Raw View
Ian McCulloch <ipm105@rsphy1.anu.edu.au> wrote:

> [This message was originally sent last weekend - it looks like might ha=
ve
> gotten lost in the post ;- ]
>=20
> Valentin Bonnard wrote in message <382DD2A9.41C6@wanadoo.fr>...
> >Is it usable on function return types ?
>=20
>=20
> how about setting the return 'type' to be declare, eg
>=20
> declare foo()
> {
>    return something_very_obscure;
> }

Here is another one (we already saw that for most uses inline might be
required)

inline declare foo(int s) {
    switch (s)=20
    {
    case 1: return 0;
    case 2: return &foo;
    case 3: return 1;
    case 4: return 2L;
    case 5: return 3.0;
    case 6: return std::string("A class type");

    default: return "Very obscure indeed";
    }
}
If you agree that runtime resolution of the declare does not fit into
the static typing of C++, and returning a union isn't a real option
either, then what would be the results of:
    /*1*/ typeid(foo(6)).name();
    /*2*/ typeid(foo).name();
    /*3*/ assert(typeid(foo(3)) =3D=3D typeid(foo(2)));
    /*4*/ std::printf("%s",foo(42));
    /*5*/ foo(6).c_str();
    // to be continued ...

Even if you restrict this to cases 1,3,4,5 (a valid combination in a
function returning an arithmetic type) the problem persists.

While typeof(expression) can be realized, as an expression's type can
(almost) always be deduced locally, this use of 'declare' (however you
name it) poses many new difficulties.

-- J=F6rg Barfurth
=20
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ian McCulloch" <ipm105@rsphy1.anu.edu.au>
Date: 1999/11/29
Raw View
Joerg Barfurth wrote in message
<1e1sqci.md3mv312a23ksN@dialinb29.bn.hh.vossnet.de>...
Ian McCulloch <ipm105@rsphy1.anu.edu.au> wrote:

> [This message was originally sent last weekend - it looks like might have
> gotten lost in the post ;- ]
>
> Valentin Bonnard wrote in message <382DD2A9.41C6@wanadoo.fr>...
> >Is it usable on function return types ?
>
>
> how about setting the return 'type' to be declare, eg
>
> declare foo()
> {
>    return something_very_obscure;
> }

Here is another one (we already saw that for most uses inline might be
required)

inline declare foo(int s) {
    switch (s)
    {
    case 1: return 0;
    case 2: return &foo;
    case 3: return 1;
    case 4: return 2L;
    case 5: return 3.0;
    case 6: return std::string("A class type");

    default: return "Very obscure indeed";
    }
}

If you agree that runtime resolution of the declare does not fit into
the static typing of C++, and returning a union isn't a real option
either, then what would be the results of:
    /*1*/ typeid(foo(6)).name();
    /*2*/ typeid(foo).name();
    /*3*/ assert(typeid(foo(3)) == typeid(foo(2)));
    /*4*/ std::printf("%s",foo(42));
    /*5*/ foo(6).c_str();
    // to be continued ...

Even if you restrict this to cases 1,3,4,5 (a valid combination in a
function returning an arithmetic type) the problem persists.

While typeof(expression) can be realized, as an expression's type can
(almost) always be deduced locally, this use of 'declare' (however you
name it) poses many new difficulties.


I don't think that using declare for a function return type poses any
difficulties above other usages of declare and typeof.  What about

void foo(int s)
{
  declare x = s == 1 ? 0 : (s == 2 ? &foo : (s == 3 ? 1 : (s == 4 ? 2L : (s
== 5 ? 3.0 : (s == 6 ? std::string("A class type") : "Very obscure
indeed")))));

   cout << x << endl;
}

Probably we would both agree that this ought to be a compile time error.
Why shouldn't the function declaration version give a similar error?

Note that this is equivalent to

   typeof(s == 1 ? 0 : &foo) x = (s == 1 ? 0 : &foo);  // can't be bothered
typing the full expression

I dont think that this presents any new difficulties.  I think it is simply
an expression, the return type of which is ambiguous and therefore needs to
be specified by the programmer explicitly.

Ian McCulloch
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/23
Raw View
Dave Harris <scorp@btinternet.com> wrote in message
news:memo.19991120132038.36839B@btinternet.com...
[declare proposal]

> I've read Andrei Alexandrescu's opposing view, and he may be right,
but I
> think this view should at least be considered and rejected
explicitly.
> It's based on the belief that const variables are a good thing. They
are
> safer, simpler, easier to optimise, and (in my experience)
mutability is
> needed much less than 50% of the time. It should be the default.

At second thought, I think you are right. Encouraging use of const is
welcome. I'm amazed on how many stack variables of mine are actually
const.

> I would also consider using "let" instead of "declare". Combine both
these
> changes to deliver more bang for buck.

But, again, what about function return values? I think a good feature
would be one that would encourage support generic functions such as
min and max hassle-free. I've been thinking of that lately, and
concluded that min and max are two functions that are incredibly hard
to write in C++. Could be the theme of an upcoming GotW. Ah, let me
write Herb about that :o).


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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/11/23
Raw View
andrewalex@hotmail.com (Andrei Alexandrescu) wrote:
> > I would also consider using "let" instead of "declare". Combine both
> > these changes to deliver more bang for buck.
>
> But, again, what about function return values?

I was just comparing variations on the "declare" theme. I'm not saying
that any flavour of "declare" should be favoured over "typeof".

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/11/23
Raw View
Ian McCulloch <ipm105@rsphy1.anu.edu.au> schrieb in im Newsbeitrag:
3835e69e.0@clarion.carno.net.au...

> how about setting the return 'type' to be declare, eg
>
> declare foo()
> {
>    return something_very_obscure;
> }
>
> I dont like the way that reads though - maybe a different name would be
> better?
>
> I like this idea, it would make writing functions that return expressio=
n
> templates a _lot_ more practical.

how about:

#include <iostream>
declare foo();    // foo defined in a library (no source available)
int main()
{
    std::cout << foo();
}

-- J=F6rg Barfurth
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Darin Adler <darin@bentspoon.com>
Date: 1999/11/23
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:

> So now you need to persuade an implementor to provide something along
> these lines as an extension (which they can as long as the spell the new
> keyword _declare, or more kindly: __declare)

It would have to be __declare or _Declare if it's going to be a keyword.
_declare is only reserved in the global namespace.

    -- Darin
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: AllanW <allan_w@my-deja.com>
Date: 1999/11/23
Raw View
In article <3832F408.D0A87152@xs4all.nl>,
  Matti Puputti <MPuputti@xs4all.nl> wrote:
> I'm sorry, but I see more restrictions than usage advantages on
> using the proposed new keyword.
> - If the compiler knows the type (during compiling time), I don't
> see why I wouldn't know it. (proper usage of typeof() should do
> the job, assuming that typeof() is evaluated during compiling time)

Right! This is what (I believe) is intended. It's "syntactic sugar"
as someone else called it. You COULD type the whole type yourself.

> - If the type must be decided during the run-time, this could be
> difficult to implement.

No, it's implemented at compile-time. The keyword "declare" would
be replaced by the *static* type of the expression.

> Again, considering following code:
>
> void declareFunc( declare param )

The proper way to accomplish this is by using templates. The new
"declare" keyword isn't meant to compete with this.

The rest of your sample code [elided] demonstrates that what
you're really trying to accomplish is what Microsoft would call
a "variant" data type -- one that could hold any type of data,
a string at one moment and a floating point value at another
moment. This isn't C++, and it doesn't match the proposal.

> Perhaps the basic question is:
> If I can not use 'declare' for function parameters, shouldn't I
> know the type during the time I am writting the code (excluding
> templates)?

Yes, you should. But using the new keyword to stand in for it
would have many benefits:

    * It would make it easier to instantiate variables of
      complicated types.

          myDerivedClass::myBaseClass1::myBaseClass2::
              myContainer::reverse_iterator Iter1
              = myObject.myContainer.rbegin();

      becomes

          declare Iter1 = myObject.myContainer.rbegin();

      The first line is difficult to write. If anything is
      misspelled the compiler will catch it, but it is still
      a pain. It's also difficult to read and maintain. And
      depending on myContainer's definition of iterator and
      reverse_iterator, it's possible that if the original
      author did it wrong (i.e. used iterator instead) that
      the compiler might not catch it.

    * It simplifies the job of teaching the C++ language.
      When we explain what iterators are, we don't have to
      overwhelm the student with such a long statement. We
      simply explain that begin() and end() return iterators,
      and then explain how iterators work. We might never
      have to force the student to type the full class name
      of the iterator types!

    * It simplifies the job of writing template code. Someone
      else already posted an example from the STL. The function
      passes an extra parameter to an internal version of the
      same function; the extra parameter is not used except to
      resolve some data types, and the data type is not needed
      except for one internal variable. With the new keyword
      we could simply declare it (without knowing how to spell
      it's type). Just like today, the compiler would do the
      rest -- but we wouldn't have to use a second function to
      tell it to do the rest.

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ian McCulloch" <ipm105@rsphy1.anu.edu.au>
Date: 1999/11/24
Raw View
J.Barfurth wrote in message <81b9uk$d70$1@news.hamburg.pop.de>...
Ian McCulloch <ipm105@rsphy1.anu.edu.au> schrieb in im Newsbeitrag:
3835e69e.0@clarion.carno.net.au...

> how about setting the return 'type' to be declare, eg
>
> declare foo()
> {
>    return something_very_obscure;
> }
>
> I dont like the way that reads though - maybe a different name would be
> better?
>
> I like this idea, it would make writing functions that return expression
> templates a _lot_ more practical.

how about:

#include <iostream>
declare foo();    // foo defined in a library (no source available)
int main()
{
    std::cout << foo();
}

-- J   rg Barfurth


Obviously, the source has to be available for the compiler to deduce the
return type.  For most of the useful applications (expression templates)
this doesn't present a problem.  Its probably a one-liner, and inlined.  (if
its not inlined, its not worth returning an expression template anyway).  eg
suppose operator +, - etc all return proxy objects of type
Expression<BinaryOperator<Operation, LHS, RHS> >.  And we want to write an
arbitary function:

inline
declare foo(double a, double b, double c)
{
   return a + b * (c / a + 3.1415927 * (b-a) );
}

The return type would be something like

Expression<BinaryOperator<Addition, double,
Expression<BinaryOperator<Multiplication, double,
Expression<BinaryOperator<Addition, Expression<BinaryOperator<Division,
double, double>, Expression<BinaryOperator<Multiplication, double,
Expression<BinaryOperator<Subtraction, double, double> > > > > > > >

(I might have missed a '>' or two there, sorry!)


Actually, it is in fact possible to hack around this using typeof.
Unfortunately it requires writing the function twice, although that could
itself be hacked around with a macro (urgh!).

struct foo_traits
{
   double a, b, c;
   typedef typeof(a + b * (c / a + 3.1415927 * (b-a))) ReturnType;
};

inline
foo_traits::ReturnType foo(double a, double b, double c)
{
   return a + b * (c / a + 3.1415927 * (b-a) );
}

This easily extends to the case where foo is a template function too.

Cheers,
Ian McCulloch

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Matti Puputti <MPuputti@xs4all.nl>
Date: 1999/11/21
Raw View
Now this was my misunderstanding in the first place. I really should have read the
first message from R.Garcia (13th Nov) more than once - but instead I was only
thinking about run-time performance...

So I was thinking how 'declare' would be evaluated during run-time, and didn't
spend much effort to consider what it could give in compiling time.
I probably should take a little time-out, and in the future I'll try to consider my
opinions more than once before writing them down...

Thanks to all in this thread for their comments. I will continue following the
discussion, since, after all, it is always worth to learn from talented people.

Matti Puputti




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/11/22
Raw View
> Unfortunately, in C++ you can't always uniquely infer the type of the
> new variable from the initialization.  For example, consider
>
>  int x = 10;
>  const int x = 10;
>  const int &x = 10;
>
> Which one should
>
>  declare x = 10;
>
> yield?

The safest, most restrictive type :-)

    declare x = 10;  // int const x = 10;
    declare mutable x = 10; // int x = 10;
    declare mutable &x = 10; // int &x = 10;

I've read Andrei Alexandrescu's opposing view, and he may be right, but I
think this view should at least be considered and rejected explicitly.
It's based on the belief that const variables are a good thing. They are
safer, simpler, easier to optimise, and (in my experience) mutability is
needed much less than 50% of the time. It should be the default.

I would also consider using "let" instead of "declare". Combine both these
changes to deliver more bang for buck.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/22
Raw View
Tom Payne wrote:

> In fact, there has been a lot of research on type inference, which
> (AFIK) could be incorporated into C++.

This has nothing to do with type inference. Type
inference solves problems of the form: what can/should
be the T in

  U foo (T x) { return x + 2; }

declare is just syntaxic sugar.

Research on type inference has been done on simple
languages, whose definition of typing take one to
ten pages. Compare to the C++ standard.

--

Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/11/22
Raw View
In article <memo.19991120132038.36839B@btinternet.com>, Dave Harris
<scorp@btinternet.com> writes
>The safest, most restrictive type :-)
>
>    declare x = 10;            // int const x = 10;
>    declare mutable x = 10;    // int x = 10;
>    declare mutable &x = 10;   // int &x = 10;
>
>I've read Andrei Alexandrescu's opposing view, and he may be right, but I
>think this view should at least be considered and rejected explicitly.
>It's based on the belief that const variables are a good thing. They are
>safer, simpler, easier to optimise, and (in my experience) mutability is
>needed much less than 50% of the time. It should be the default.
>
>I would also consider using "let" instead of "declare". Combine both these
>changes to deliver more bang for buck.

So now you need to persuade an implementor to provide something along
these lines as an extension (which they can as long as the spell the new
keyword _declare, or more kindly: __declare)


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW <allan_w@my-deja.com>
Date: 1999/11/22
Raw View
In article <80nhls$v22$1@nnrp1.deja.com>,
  dennis51@my-deja.com wrote:
> The STL seems to be full of circumlocutions caused by
> the lack of typeof().
>
> Here is a randomly selected example from the STL:
>
> template <class InputIterator, class OutputIterator, class T>
> OutputIterator __unique_copy(InputIterator first, InputIterator last,
>                              OutputIterator result, T*) {
>   T value = *first;
>   *result = value;
>   while (++first != last)
>     if (value != *first) {
>       value = *first;
>       *++result = value;
>     }
>   return ++result;
> }
>
> template <class InputIterator, class OutputIterator>
> inline OutputIterator __unique_copy(InputIterator first,
>                                     InputIterator last,
>                                     OutputIterator result,
>                                     output_iterator_tag) {
>   return __unique_copy(first, last, result, value_type(first));
> }
>
> Here we see that the second __unique_copy needs to declare
> a temp to store *first in, but instead of doing
>
>   typeof( *first) value = *first;
>
> it seems to be necessary to take a detour thru value_type( first)
> and then into the first version of __unique_copy.
> Indeed, the only reason value_type() and friends exist at all,
> is to make up for the lack of typeof().
>
> Now, I know that this does not incur any runtime cost,

I'm pretty sure that it DOES incur some runtime cost. The
expression value_type(first) default-constructs an object
of type first::value_type, doesn't it?

Someone will want to say "a good optimizing compiler will
realize that this default-constructed object is unused,
and therefore elide it's construction in the first place."
Perhaps this is so, but certainly there will always be
some compilers that aren't this smart (and are ANY of them
this smart today?).

In other words, there is some cost, and it seems like it's
avoidable.

> but it sure did require someone to spend the time to think
> it up and to type it in, and, presumably, it takes longer to
> compile than a more straightforward solution using typeof() or
> var and/or const as described below.

I agree.

> // var declares a variable (same type as the expression on
> //                          the right side of the '=').
>   var value = *first;

Pretty much the same thing as the proposed "declare" keyword.

> // const declares a constant (same type as const expression on
> //                            the right side of the '=')
>   const xxx = *first;

I hadn't thought about the need for const. Would that be
important?

    { // Begin a local scope
        declare abc = (complicated_expression);
        // ... use abc...
    } // abc goes out of scope...

Would the fact that abc isn't const be important? After
all, it is a local copy of whatever the complicated_expression
returned.

> Indeed, it would make iterators much more convenient
> to work with.

That's got to be the big win. Statements like

    myContainer::reverse_iterator myIterator =
        myContainer.rbegin();

are not only clumbsy, they are error-prone. (i.e. Should that
have been myContainer::reverse_iterator, or
myContainer::const_reverse_iterator?)

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Matti Puputti <MPuputti@xs4all.nl>
Date: 1999/11/19
Raw View
You are right, I had forgotton to remove the '*'. It was purely an error in
writing. Unfortunatelly it was in the critical part of the example-code,
leading focus out of my original intention.

What I was thinking was that compiler would implement one piece of code that
would be able to handle any type requested (type in my example would have
been 'pointer to A'). In run-time it would identify the requested type and
behave accordingly.


I'm sorry, but I see more restrictions than usage advantages on using the
proposed new keyword.
- If the compiler knows the type (during compiling time), I don't see why I
wouldn't know it. (proper usage of typeof() should do the job, assuming that
typeof() is evaluated during compiling time)
- If the type must be decided during the run-time, this could be difficult to
implement.

Again, considering following code:

void declareFunc( declare param )
    {
    param++; // Is operator++ available for type of 'param'?
    cout << param << endl;    // Hmm?
    return;      // It was already defined that 'declare' is not usable for
return types.
    }

class A
{
// dummy class without any reasonable usage.
};

int main( void )
{
    int i = 1;
    const char* "string";
    A a;

    declareFunc(i);            // prints "2"
    declareFunc("string")   // prints "tring"
    declareFunc(a)            // Hmm?
}

(Hopefully this went without too many misspellings).

Naturally compiler could implement some code that during the run-time would
try to find the requested operator (something comperable to usage of DLLs in
Windows environment). However, risk of failing to find the operator remains,
and therefore can not be used.

Perhaps the basic question is:
If I can not use 'declare' for function parameters, shouldn't I know the type
during the time I am writting the code (excluding templates)?
Or perhaps I jsut didn't understand your intention?

Matti Puputti


Ram'on Garc'ia Fern'andez wrote:

> On 16 Nov 99 12:23:02 GMT, Matti Puputti <MPuputti@xs4all.nl> wrote:
> >Giving the following example:
> >
> >void usesDeclare( A* a )
> >  {
> >  declare* aa = a;
> >  aa->vm();
> >  }
>
> It should be
>         declare aa = a;
> I hope that you understood my original intention. For me
>
> declare new_variable = initialization;
>
> is a synonim for
>
> <type_of_initialization> new_variable = initialization;
>
> in particular <type_of_initialization> can be a pointer. My intention was
> that declare, declares the new object of the same static type as the
> initialization, so that
>
>         declare aa = a;
>
> is the same as:
>
>         A* aa =a;
>
> Since the new object is a copy of the old one, it must have the same
> dynamic type as well (of course, the copied object is the pointer, not
> the object pointed to), and therefore a->vm() would call B::vm() with
> my original proposal.
>
> Perhaps I did not understand you.
>
> Ramon
>
> [ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/11/19
Raw View
Ram'on Garc'ia Fern'andez wrote:
>
> On 16 Nov 99 12:23:02 GMT, Matti Puputti <MPuputti@xs4all.nl> wrote:
> >Giving the following example:
> >
> >void usesDeclare( A* a )
> >  {
> >  declare* aa = a;
> >  aa->vm();
> >  }
>
> It should be
>         declare aa = a;
> I hope that you understood my original intention. For me
>
> declare new_variable = initialization;
>
> is a synonim for
>
> <type_of_initialization> new_variable = initialization;
>
> in particular <type_of_initialization> can be a pointer. My intention was
> that declare, declares the new object of the same static type as the
> initialization, so that
>
>         declare aa = a;
>
> is the same as:
>
>         A* aa =a;
>
> Since the new object is a copy of the old one, it must have the same
> dynamic type as well (of course, the copied object is the pointer, not
> the object pointed to), and therefore a->vm() would call B::vm() with
> my original proposal.
>
> Perhaps I did not understand you.

I guess he thought of extending that to a type deduction
similar to a one-arg template:

template<class T> void foo(T* aa) { ... }

foo(a) // foo's T is A, so foo's aa has type A*

Now by replacing T with declare, and moving that declaration
from the argument list to a code line, we get:

declare* aa = a;

This might especially be useful for references:

declare& aa = a; // aa references to a, and has the correct ref type
declare const& aaa = a; // same here, but const ref
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/11/19
Raw View
Tom Payne <thp@roam-thp2.cs.ucr.edu> writes:
> In fact, there has been a lot of research on type inference, which
> (AFIK) could be incorporated into C++.

Type inference is *already* incorporated into C++, in the form of
template argument deduction. The only thing lacking is the ability
to get a deduced type lifted out of the function template in which
it is deduced, which is what typeof would accomplish. That is, in

 template<typename T> T deduce(T &);

when I call deduce with some expression, the name T represents the
type of that expression within deduce, where I can use it to declare
variables of the same type, and what not, but I have no way to get
that type out of the function.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ian McCulloch" <ipm105@rsphy1.anu.edu.au>
Date: 1999/11/20
Raw View

[This message was originally sent last weekend - it looks like might have
gotten lost in the post ;- ]

Valentin Bonnard wrote in message <382DD2A9.41C6@wanadoo.fr>...
>Is it usable on function return types ?


how about setting the return 'type' to be declare, eg

declare foo()
{
   return something_very_obscure;
}

I dont like the way that reads though - maybe a different name would be
better?

I like this idea, it would make writing functions that return expression
templates a _lot_ more practical.

While we're adding keywords, why not something analagous to typeof that
gives the return type of a function?  eg

return_type(foo()) x = foo();  // maybe return_type<foo> is better notation

which would be equivalent to

declare x = foo();

or

typeof(something_very_obscure) x = foo();

declare can be hacked around using typeof, since "declare x = expression" is
equivalent to
"typeof(expression) x = expression".  Declare could also be hacked around
using return_type, eg

template <class T>
T declare_hack(const T&);  // don't need to bother implementing this

usage:

return_type(declare_hack(x)) y;

I cant think of a practical way of hacking around return_type.  A traits
class looks like a good start though,

template <class T>
struct return_type;

template <class T>
struct return_type<T (*)()>
{
   typedef T type;
};

template <class T1, class T2>
struct return_type<T1 (*)(T2)>
{
   typedef T1 type;
};

template <class T1, class T2>
struct return_type<T1 (*)(T2&)>
{
   typedef T1 type;
};

template <class T1, class T2>
struct return_type<T1 (*)(const T2&)>
{
   typedef T1 type;
};

template <class T1, class T2, class T3>
struct return_type<T1 (*)(T2, T3)>
{
   typedef T1 type;
};

etc etc etc, and similarly for member functions.

then we have

   return_type<typeof(foo)>::type x = foo;

This _almost_ works today, except that you have to do a typedef of foo to
instantiate the template, which basically defeats the idea.  And actually
declaring the templates isn't very practical though, the combinatorial
explosion of partial specializations gets a bit crazy.

Cheers,
Ian McCulloch




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/20
Raw View
Jonathan Thornburg <jthorn@galileo.thp.univie.ac.at> wrote in message
news:199911191319.OAA04800@davinci.thp.univie.ac.at...
> int x = 10;
> const int x = 10;
> const int &x = 10;
>
> Which one should
>
> declare x = 10;
>
> yield?

The unaltered type. Then you can modify this implicit type:

declare const x = 10;
declare const &x = 10;


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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/20
Raw View
Matti Puputti <MPuputti@xs4all.nl> wrote:

> - If the compiler knows the type (during compiling time), I don't see w=
hy I
> wouldn't know it. (proper usage of typeof() should do the job, assuming=
 that
> typeof() is evaluated during compiling time)
But there currently isn't any 'typeof()' in the C++ language.
If we did have this feature, it would be quite clumsy and error prone to
use in the presence of template functions. Consider the idioms of
functional adaptors:

<example>
typeof(what goes here ??) x =3D       // no trigraph intended
    std::bind2nd(
        std::mem_fun(&X::Y::Z::foo),
        std::char_traits<wchar_t>::eof()
    );
</example>

> - If the type must be decided during the run-time, this could be diffic=
ult to
> implement.
I don't think that was intended. Nor do I think it is possible with
resonable efficiency.
=20
> Again, considering following code:
>=20
> void declareFunc( declare param )
This (like use as function return type) could not be possible. In this
specific case, what you need is a template function.

-- J=F6rg Barfurth


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Tom Payne <thp@roam-thp2.cs.ucr.edu>
Date: 1999/11/18
Raw View
Ram'on Garc'ia Fern'andez <ramon@jl1.quim.ucm.es> wrote:
[...]
> I hope that you understood my original intention. For me

> declare new_variable = initialization;

> is a synonim for

> <type_of_initialization> new_variable = initialization;

Good idea.

In fact, there has been a lot of research on type inference, which
(AFIK) could be incorporated into C++.  One argument that I've heard
against such proposals is that having the declaration in the source
code is an aid to say maintenance programmers in figuring out what the
types are.  (Of course, type-inference tools could annotate the source
code with comments telling the type of each varaible.)


Tom Payne





[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jonathan Thornburg <jthorn@galileo.thp.univie.ac.at>
Date: 1999/11/19
Raw View
Ram'on Garc'ia Fern'andez <ramon@jl1.quim.ucm.es> wrote:
> I hope that you understood my original intention. For me
> declare new_variable = initialization;
> is a synonim for
> <type_of_initialization> new_variable = initialization;

Unfortunately, in C++ you can't always uniquely infer the type of the
new variable from the initialization.  For example, consider

 int x = 10;
 const int x = 10;
 const int &x = 10;

Which one should

 declare x = 10;

yield?

--
-- Jonathan Thornburg <jthorn@galileo.thp.univie.ac.at>
   http://www.thp.univie.ac.at/~jthorn/home.html
   Universitaet Wien (Vienna, Austria) / Institut fuer Theoretische Physik
     Amount of all stock owned by the least wealthy 90% of America: 18%
     Amount of all stock owned by the most wealthy 1% of America: 41%
      -- Economic Policy Institute


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Matti Puputti <MPuputti@xs4all.nl>
Date: 1999/11/16
Raw View
Giving the following example:

#include <ostream.h>

class A
  {
  public:
  virtual void vm(void) const  { cout << "A::f" << endl; }
  };

class B : public A
  {
  public:
  virtual void vm(void) const  { cout << "B::f" << endl; }
  };

void usesDeclare( A* a )
  {
  declare* aa = a;
  aa->vm();
  }

int main( void )
  {
  B b;
  usesDeclare( &b);

  return 0;
  }



We could enlarge the definition of keyword 'declare' to make sute that 'aa' must
be exactly 'pointer to type A' (and not to any derived type). I do find it little
difficult to ensure that all compilers would be able ensure B::vm() to be called
(note that this is very simplified example of usage of virtuality).

I hope this should point out the fact that whereas virtuality is a feature of
types (class A and B, in this case), it is not a feature of data (object pointed
by 'a').



Hmm, perhaps someone do not agree. As I see this, question is how 'type' is
implemented in compiled result. As I have understood the C++ standard, compilers
do have lots of freedom in this. Adding this kind of 'new rule' would restrict
the freedom quite a bit.

I wouldn't mind to hear opinions from others.



Matti Puputti
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ramon@jl1.quim.ucm.es (Ram'on Garc'ia Fern'andez)
Date: 1999/11/16
Raw View
On 13 Nov 99 21:42:27 GMT, Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote:
>Is it usable on function return types ?
>
Certainly no. I was not thinking in this case. For that case, I think that
typeof would be the right solution.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: dennis51@my-deja.com
Date: 1999/11/16
Raw View
In article <s2qvm0lhhsq22@news.supernews.com>,
  "Andrei Alexandrescu" <andrewalex@hotmail.com> wrote:
> Ram'on Garc'ia Fern'andez <ramon@jl1.quim.ucm.es> wrote in message
> news:slrn82opje.lj1.ramon@jl1.quim.ucm.es...
> > I want to suggest a new feature to the language: allow to declare a
> variable
> > without declaring its type. The type is implicitly declared by the
> > inizialization of a variable.
>
> [details omitted, please see the original post]
>
> This would make template functions much easier to write. I fear abuse,
> though. And I'd like this unified with typeof, which is much more
> powerful.
>
> There is a kind of a precedent, coming from the opposite direction,
> interesting nonetheless. Figuring out what the name of a function
> refers to depends on contextual information:
>
> void f();
> void f(int);
>
> void (*pf)(int) = f;    // resolves f to f(int)

What kind of abuse do you fear?

I don't understand why we don't already have typeof().

The STL seems to be full of circumlocutions caused by
the lack of typeof().

Here is a randomly selected example from the STL:

template <class InputIterator, class OutputIterator, class T>
OutputIterator __unique_copy(InputIterator first, InputIterator last,
                             OutputIterator result, T*) {
  T value = *first;
  *result = value;
  while (++first != last)
    if (value != *first) {
      value = *first;
      *++result = value;
    }
  return ++result;
}

template <class InputIterator, class OutputIterator>
inline OutputIterator __unique_copy(InputIterator first,
                                    InputIterator last,
                                    OutputIterator result,
                                    output_iterator_tag) {
  return __unique_copy(first, last, result, value_type(first));
}


Here we see that the second __unique_copy needs to declare
a temp to store *first in, but instead of doing

  typeof( *first) value = *first;

it seems to be necessary to take a detour thru value_type( first)
and then into the first version of __unique_copy.
Indeed, the only reason value_type() and friends exist at all,
is to make up for the lack of typeof().

Now, I know that this does not incur any runtime cost,
but it sure did require someone to spend the time to think
it up and to type it in, and, presumably, it takes longer to
compile than a more straightforward solution using typeof() or
var and/or const as described below.

If this code was not part of the STL, I am sure that some
people would call it an abuse of the language.

What I would like to see is:

// var declares a variable (same type as the expression on
//                          the right side of the '=').
  var value = *first;

// const declares a constant (same type as const expression on
//                            the right side of the '=')
  const xxx = *first;

This would also be useful in cases like this:

int f( map<string,string> m)
{
  var i = m.begin();
  const e = m.end();
  //  ...
}

Indeed, it would make iterators much more convenient to work with.

Notice, that const does not even require adding a new keyword.
I suppose I would be willing to spell var as mutable if necessary.

And, yes, I want typeof() too.

Dennis Yelle


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ramon@jl1.quim.ucm.es (Ram'on Garc'ia Fern'andez)
Date: 1999/11/16
Raw View
On 16 Nov 99 12:23:02 GMT, Matti Puputti <MPuputti@xs4all.nl> wrote:
>Giving the following example:
>
>void usesDeclare( A* a )
>  {
>  declare* aa = a;
>  aa->vm();
>  }

It should be
 declare aa = a;
I hope that you understood my original intention. For me

declare new_variable = initialization;

is a synonim for

<type_of_initialization> new_variable = initialization;

in particular <type_of_initialization> can be a pointer. My intention was
that declare, declares the new object of the same static type as the
initialization, so that

 declare aa = a;

is the same as:

 A* aa =a;

Since the new object is a copy of the old one, it must have the same
dynamic type as well (of course, the copied object is the pointer, not
the object pointed to), and therefore a->vm() would call B::vm() with
my original proposal.

Perhaps I did not understand you.

Ramon



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ramon@jl1.quim.ucm.es (Ram'on Garc'ia Fern'andez)
Date: 1999/11/13
Raw View
I want to suggest a new feature to the language: allow to declare a variable
without declaring its type. The type is implicitly declared by the
inizialization of a variable.

This construct requires a new language keyword. I suggest declare. The syntax
is:

declare <new variable> = <initialization expression>

declares a new variable of the same type as <initialization expression>.

For example

 declare i = 256;

declares i of type integer.


Posible uses of this new feature
================================

a) Avoid to use complex types:

if the type of <expression> is a complex type it is a good thing
avoiding to write it.

For example:

std::vector<int> int_vector;

declare vbegin = int_vector.begin();
// Instead of std::vector<int>::iterator vbegin = int_vector.begin();

A related consequence is that this feature makes generic programming easier.

b) Makes the use of libraries that use partial evaluation easier.

This argument is giving to those that might think that this feature is
just cosmetic.

Some libraries use a method known as "partial evaluation". The idea
 is to take advantadge of operator overloading to delay the
evaluation of expressions until the assignment is made. And
then the best approach for making the operations is made.

This is useful for array operations. Suppose that you want to
make an operation like making operations between several
matrixes without temporaries. For example:

A = B + C*D; //without a temporary for C*D

However this libraries force you to use only one source line,
even if the statement is complex:

Matrix A;

A = ( ......... expression  1 .............)*
 (......... expression  2 ...........);

you cannot use
Matrix B = (..........expression 1.........);
Matrix C = (..........expression 2.........);
Matrix A = B*C;
because you loose the optimization.

But this problem does not arise with declare.

declare B =(......... expression 1........);
//Matrix.operator= is not executed,
//and so the expression 1 is not fully evaluated.
declare C =(......... expression 2........);

Matrix A = B*C;

Problems that would bring this new language feature
===================================================

The grammar is more ambigous: the syntax of the construct
declare variable = initial_value;
is similar to
type variable = initial_value;

thus making the implementation more complex.

Another problem is backward compatibility. What would happen if a
program have used "declare" for a user-defined type? That program would
no longer compile. However a quick workaround this problem would
be to add a preprocessor definition "declare = _user_declare". This
can be added without modifying the source code of the program.


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

Please excuse if this article is not very clear. This is a complex
matter and explaining it clearly is not easy.

As usually take into account that this article might contain spelling
errors. I would appreciate if you avoid comments about small errors
and focus your answers in the subject.


Ramon Garcia -
Depto. Quimica Fisica
Facultad de Ciencias Quimicas
Universidad Complutense
28040 MADRID
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/13
Raw View
Ram'on Garc'ia Fern'andez <ramon@jl1.quim.ucm.es> wrote in message
news:slrn82opje.lj1.ramon@jl1.quim.ucm.es...
> I want to suggest a new feature to the language: allow to declare a
variable
> without declaring its type. The type is implicitly declared by the
> inizialization of a variable.

[details omitted, please see the original post]

This would make template functions much easier to write. I fear abuse,
though. And I'd like this unified with typeof, which is much more
powerful.

There is a kind of a precedent, coming from the opposite direction,
interesting nonetheless. Figuring out what the name of a function
refers to depends on contextual information:

void f();
void f(int);

void (*pf)(int) = f;    // resolves f to f(int)


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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/13
Raw View
Is it usable on function return types ?

--

Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]