Bjarne Stroustrup Thinks He Has A Better Way To Do Generics
Written by Mike James   
Wednesday, 01 February 2017

Bjarne Stroustrup is, of course, the inventor of C++. Over time he has added features to it and now he is proposing to add Concepts to make generics work like they always should have. 

stroustrupatdesk

I have had a mixed reaction to C++ over its entire lifetime. I was, and am, amazed by the way Bjarne Stroustrup managed to turn C into an object oriented language with nothing but the help of a preprocessor.

That is, C++ was, at first, syntactic sugar that was mapped fairly directly to C. It was a simple language that you could understand in terms of how it was mapped to C which was an even simpler language. However, over time I have encountered C++ programs and idioms that had me feeling that the language was over complex and capable of expressing things in ways that were at best misguided attempts at abstraction and at worse just attempts to impress. 

One thing has always remained true, however. Whenever I read anything by the language's originator, Bjarne Stroustrup, I am once again convinced that C++ is a simple clean language capable of great clarity of expression. In other words, C++ as written by Bjarne is the language it was always supposed to be. If you don't believe me then try reading one of his books listed in the sidebar. 

Generics are a problem in any language, but it seems that C++ templates introduced in 1987 were a particular disappointment to Bjarne: 

I failed. I wanted three properties for templates:

• Full generality/expressiveness

• Zero overhead compared to hand coding

• Well-specified interfaces

Then, nobody could figure out how to get all three, so we got

• Turing completeness

• Better than hand-coding performance

• Lousy interfaces (basically compile-time duck typing)

 

The big problem that we face is that if you adopt a strongly typed language then you cannot write an algorithm that works on widely dissimilar object types. For example, if you want a sort method then you have to write it for integers, floats, characters, strings, vectors and so on. The algorithm is largely independent of type, but it cannot be directly expressed in a type definite way without creating a version for each type it is supposed to work with. 

This is where generics come in. Usually, by making type a parameter of the definition, you can write a single function that can be used to implement the algorithm. 

For example using a C++ template you can implement a sort function

template <class T> void sort(T& c){};

and when you use the function you give the "type parameter" T a value which then allows the compiler to type check the code. 

vector<string> vs;
sort(vs);

The problem is that the template will attempt to accept any type the user cares to try to use it with and any errors are only generated when the template is instantiated. As the new paper puts it:

double d = 7;

sort(d); // error: d doesn’t have a [] operator

We have problems:

• As you probably know, the error message we get from sort(d) is verbose and nowhere near as precise and helpful as my comment might suggest.

• To use sort, we need to provide its definition, rather than just its declaration, this differs from ordinary code and changes the model of how we organize code.

• The requirements of sort on its argument type are implicit (“hidden”) in its function body.

• The error message for sort(d) will appear only when the template is instantiated, and that may be long after the point of call.

• The template<typename T> notation is unique, verbose, repetitive, and widely disliked.

The real problem, however, is that there is no explicit statement of what properties T has to have to be a valid type for the template. This is where concepts come in. A concept is a predicate that evaluates to true or false when applied to a type. It is a condition that has to be true for the type to be acceptable to the template. For example:

// Generic code using a concept (Sortable):

void sort(Sortable& c);
// Concepts: accept any c that is Sortable

vector <string> vs = { "Hello", "new", "World" };

sort(vs); // fine: vs is a Sortable container

double d = 7; sort(d);

// error: d is not Sortable (double does not provide [], etc.)

Thus we have used a concept to specify the exact functionality a type has to have for it to work in the template. 

Of course, things get more complicated and the example in the paper demonstrates a typical concept;

template <typename S, typename T>
 requires Sequence<S> &&
   Equality_comparable<Value_type<S>, T>
    Iterator_of<S> find(S& seq, const T& value);

Let’s look at it line for line:

• This is a template that takes two template type arguments (nothing new here).

• The first template argument must be a sequence (Sequence<S>) and we have to be able to
compare elements of the sequence to value using the == operator
(Equality_comparable<Value_type<S>, T>).

• This find() takes its sequence by reference and the value to be found as a const reference. It returns an iterator (nothing new here).

The idea is that there will be a lot of concepts defined in libraries that you can just use to specify what properties types has to have, but there is also a way to define new concepts. 

So is this the way to go?

If you want a strongly typed language you have to invent something like this otherwise you might as well forget templates and use object pointers to write generic code and give up type checking.

Of course there are languages - JavaScript for example - where everything is generic simply because type checking isn't enforced. Instead the JavaScript programmer has to write explicit code to make sure that the object being used does have the required properties. 

Standing back for a moment, it does make you feel a bit strange. First we start out writing generic functions because there is no type. Then we invent strong typing so there are no generic functions. Then we invent templates, or something similar, and we have generic functions, but no strong typing. Then we invent concepts, or something similar, to control the templates and make clear the conditions the types have to satisfy...

It's a long repeating journey and it makes you wonder if concepts aren't the deeper reality - ignoring the exceptionally esoteric Curry-Howard, that is. 

 

More Information

Concepts: The Future of Generic Programming

Related Articles

Towards Objects and Functions - Computer Languages In The 1980s

A Recursive Interview With Bjarne Stoustrup  

C++ 14 Approved

Programming: Principles and Practice Using C++, 2e (book review) 

A Tour of C++ (book review)

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

Banner


Prompt Engineering Techniques To Make You An Expert
18/11/2024

Introducing a GitHub repository full of hot tips and instructions on how to build the perfect prompt presented in a collection of Jupiter Notebooks.



Go At Highest Rank Ever in TIOBE Index
20/11/2024

Go is currently in 7th place in the TIOBE Index for November 2024. Not only is this is the highest position it has ever had, it's percentage rating is almost equal to its all-time-high. Will Go contin [ ... ]


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info

<ASIN:0321992784>

<ASIN:0321563840>

<ASIN:0201543303>

Last Updated ( Wednesday, 01 February 2017 )