Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Bjarne Stroustrup mines generic programming for a better C++"

102 views
Skip to first unread message

Lynn McGuire

unread,
Jan 23, 2017, 8:03:46 PM1/23/17
to
"Bjarne Stroustrup mines generic programming for a better C++"
http://www.infoworld.com/article/3155288/application-development/bjarne-stroustrup-mines-generic-programming-for-a-better-c.html

"Bjarne Stroustrup is on a mission to simplify generic programming."

"In a recently published paper titled "Concepts: The Future of Generic Programming," Stroustrup makes the case for concepts as a
foundation for generic programming. In concepts, Stroustrup sees the solution to the interface specification problem that has long
dogged C++, the language he founded more than 35 years ago."

Lynn

Real Troll

unread,
Jan 23, 2017, 8:31:56 PM1/23/17
to
On 24/01/2017 01:03, Lynn McGuire wrote:
> "Bjarne Stroustrup mines generic programming for a better C++"
> http://www.infoworld.com/article/3155288/application-development/bjarne-stroustrup-mines-generic-programming-for-a-better-c.html
>
> "Bjarne Stroustrup is on a mission to simplify generic programming."
>
>

OK tell us what is generic programming? Also tell us what other types
of programming are there in the wild apart from generic programming?.

Thank you.




Alf P. Steinbach

unread,
Jan 23, 2017, 8:53:25 PM1/23/17
to

JiiPee

unread,
Jan 24, 2017, 2:42:55 AM1/24/17
to
On 24/01/2017 01:03, Lynn McGuire wrote:
> "Bjarne Stroustrup is on a mission to simplify generic programming."


thats good. I dont like too complex languagages. I know, Bjarne has
always the desire to make things more simple.

David Brown

unread,
Jan 24, 2017, 2:52:05 AM1/24/17
to
As he said himself, "I have always wished for my computer to be as easy
to use as my telephone; my wish has come true because I can no longer
figure out how to use my telephone"

Daniel

unread,
Jan 24, 2017, 12:33:33 PM1/24/17
to
On Monday, January 23, 2017 at 8:03:46 PM UTC-5, Lynn McGuire wrote:
> "Bjarne Stroustrup mines generic programming for a better C++"
> http://www.infoworld.com/article/3155288/application-development/bjarne-stroustrup-mines-generic-programming-for-a-better-c.html
>
Personally, I'd rather have date, big_integer, decimal, strtod_l, a proper string class ...

Daniel

Daniel

unread,
Jan 24, 2017, 12:35:22 PM1/24/17
to
On Tuesday, January 24, 2017 at 2:42:55 AM UTC-5, JiiPee wrote:
> On 24/01/2017 01:03, Lynn McGuire wrote:
> > "Bjarne Stroustrup is on a mission to simplify generic programming."
>
>
> Bjarne has always the desire to make things more simple.

If that were that case, why do we have to implement both == and !=, < and >=?

Daniel

Manfred

unread,
Jan 24, 2017, 2:47:45 PM1/24/17
to
I would like these too (although IMHO strtod_l should come from C and
then transparently included into C++), but I do not see why these should
exclude concepts.
As far as I can see concepts can be an excellent thing, at the same time
I can see that it can be hard to design them right for the language.


>
> Daniel
>

Robert Wessel

unread,
Jan 25, 2017, 12:46:04 AM1/25/17
to
For at least some types, you cannot generate one of the pair by
negating the other. Consider FP comparisons in the presence of NaNs,
as one example. IOW "1.23 = NaN" and "1.23 != NaN" are both _false_,
if you defined _not-equals_ as the logical negation of _equals_, the
latter would evaluate as _true_.

OTOH, it might have been reasonable to allow an automatic definition
of the inverted function if an explicit definition was not made, but
allow for two different functions is necessary in the general case.

OTTH, if the _not_equals_ operator is actually just the logical
negation of the _equals_ operator, it's trivial enough to just define
it that way in your class:

bool operator!=(const X&l, const X&r){ return !(l==r);}

Similarly, three of the set (<, >, <=, >=) are usually defined in
terms of the fourth.

Daniel

unread,
Jan 25, 2017, 12:59:00 AM1/25/17
to
On Wednesday, January 25, 2017 at 12:46:04 AM UTC-5, robert...@yahoo.com wrote:
>
> For at least some types, you cannot generate one of the pair by
> negating the other. Consider FP comparisons in the presence of NaNs,
> as one example. IOW "1.23 = NaN" and "1.23 != NaN" are both _false_,
> if you defined _not-equals_ as the logical negation of _equals_, the
> latter would evaluate as _true_.
>
Good point, thanks.

Daniel

Alf P. Steinbach

unread,
Jan 25, 2017, 2:53:32 AM1/25/17
to
As Robert Wessel explains in his follow-up to the above, the core
language has to support types where e.g. `==` is not necessarily the
negation of `!=`.

Automatic definition of relational operators can to some extent be
automated via library facilities.

This can be done in a many ways.

• • •

The standard library offers a number of general operator definitions in
the `rel_ops` namespace, where it defines the other operators in terms
of `<` and `<=`. You can those definitions like this:

[code]
#include <iostream>
#include <utility> // std::rel_ops::*
using namespace std;

struct S{ int x; };

auto operator<( S const& a, S const& b )
-> bool
{ return a.x < b.x; }

auto operator==( S const& a, S const& b )
-> bool
{ return a.x == b.x; }

#define CHECK( op ) \
cout << "a " #op " b is " << (a op b) << endl;

auto main()
-> int
{
S const a{ 1 };
S const b{ 2 };

cout << boolalpha;
using namespace rel_ops;
CHECK( < ); CHECK( <= ); CHECK( == ); CHECK( >= ); CHECK( > );
cout << endl;
CHECK( != );
}
[/code]

• • •

Since the standard library places the burden of gathering operator
definitions on each piece of code using the class, it's grossly in
violation of the DRY principle: Don't Repeat Yourself.

Therefore one may define a class template that provides these operators
via the `friend` mechanism.

This is known as the Barton-Nackman trick and is, as far as I know, the
original example of the Curiously Recurring Template Pattern, or CRTP.
The detailed language rules involved have changed substantially:
originally this technique used so called friend injection, IIRC. The new
rules were designed expressly to keep code using this, still valid.

[code]
#include <iostream>
using namespace std;

template< class Derived >
struct With_relops_
{
auto self() const
-> Derived const&
{ return *static_cast<Derived const*>( this ); }

friend auto operator<=( Derived const& a, Derived const& b )
-> bool
{ return not( b < a ); }

friend auto operator!=( Derived const& a, Derived const& b )
-> bool
{ return not( a == b ); }

friend auto operator>=( Derived const& a, Derived const& b )
-> bool
{ return not( a < b ); }

friend auto operator>( Derived const& a, Derived const& b )
-> bool
{ return b < a; }
};

struct S
: With_relops_<S>
{
int x;
S( int _x = 0 ): x{ _x } {}
};

auto operator<( S const& a, S const& b )
-> bool
{ return a.x < b.x; }

auto operator==( S const& a, S const& b )
-> bool
{ return a.x == b.x; }

#define CHECK( op ) \
cout << "a " #op " b is " << (a op b) << endl;

auto main()
-> int
{
S const a{ 1 };
S const b{ 2 };

cout << boolalpha;
CHECK( < ); CHECK( <= ); CHECK( == ); CHECK( >= ); CHECK( > );
cout << endl;
CHECK( != );
}
[/code]

One side-effect of this approach is that the inheritance prevents the
class from being a Plain Old Data type, and thus, it needs a constructor
for initialization.

• • •

Instead of defining relational operators in terms of `<` and `==`, they
can be defined in terms of a `compare` function that returns an integer
result that's less than, equal to or greater than 0.

E.g. the standard library provides `std::basic_string::compare`.

This can more efficient and in the days before `std::tuple` it provided
a very easy and clear way to define lexicographic order for items with
multiple values. After `std::tuple` and `std::tie` were introduced with
C++11, only the efficiency advantage remains. Still worth knowing about:

[code]
#include <iostream>
using namespace std;

template< class Derived >
struct With_relops_
{
auto self() const
-> Derived const&
{ return *static_cast<Derived const*>( this ); }

friend auto operator<( Derived const& a, Derived const& b )
-> bool
{ return compare( a, b ) < 0; }

friend auto operator<=( Derived const& a, Derived const& b )
-> bool
{ return compare( a, b ) <= 0; }

friend auto operator==( Derived const& a, Derived const& b )
-> bool
{ return compare( a, b ) == 0; }

friend auto operator>=( Derived const& a, Derived const& b )
-> bool
{ return compare( a, b ) >= 0; }

friend auto operator>( Derived const& a, Derived const& b )
-> bool
{ return compare( a, b ) > 0; }

friend auto operator!=( Derived const& a, Derived const& b )
-> bool
{ return compare( a, b ) != 0; }
};

struct S
: With_relops_<S>
{
int x;
S( int _x = 0 ): x{ _x } {}
};

auto compare( S const& a, S const& b )
-> int
{ return a.x - b.x; } // SIMPLE & FAST BUT ASSUMING NO OVERFLOW

#define CHECK( op ) \
cout << "a " #op " b is " << (a op b) << endl;

auto main()
-> int
{
S const a{ 1 };
S const b{ 2 };

cout << boolalpha;
CHECK( < ); CHECK( <= ); CHECK( == ); CHECK( >= ); CHECK( > );
cout << endl;
CHECK( != );
}
[/code]

Alf P. Steinbach

unread,
Jan 25, 2017, 2:54:32 AM1/25/17
to
On 25.01.2017 08:52, Alf P. Steinbach wrote:
> in terms of `<` and `<=`

Oops, I meant `<` and `==`. Dang.

Sorry,

- Alf

Tim Rentsch

unread,
Jan 27, 2017, 2:54:52 AM1/27/17
to
My sense is this capability will be a useful addition to C++.
(That is, assuming it gets nailed down well enough and has the
kinks worked out of it, which I wasn't able to figure out from
reading the paper.)

Two complaints: the term "concepts" just isn't a good word
choice for what's being added. Also, the writing is a bit
offputting in its tone and style; IMO the author (and yes
I know who the author is) is rather too full of himself, and
the writing suffers because of that.

Manfred

unread,
Jan 27, 2017, 7:59:51 AM1/27/17
to
On 1/27/2017 8:54 AM, Tim Rentsch wrote:
> Two complaints: the term "concepts" just isn't a good word
> choice for what's being added.
I tend to agree on this. The term is attractive for its generality (btw
concepts are the foundation of human knowledge, so, what a big
thing(!)), but in fact too generic for the task it represents;
When defining the term, Bjarne himself writes (page 2):
<<The solution to the interface specification problem was named
“concepts” by Alex Stepanov (§8.8). A concept is a set of requirements
on a set of template arguments.>>

Well then, A concept is a set of requirements on a set of template
arguments. So what about 'requirement', 'constraint' or anything that
describes what this thing is doing?

Also, the writing is a bit
> offputting in its tone and style; IMO the author (and yes
> I know who the author is) is rather too full of himself, and
> the writing suffers because of that.
I don't think that the author is too full of himself. But the choice of
the name (too big) might have been influenced by his enthusiasm.
0 new messages