C++14 “Terse” Templates – an argument against the proposed syntax

Today I attended two excellent talks by Bjarne Stroustrup at the ACCU Conference 2013. The first was an inspiring explanation of the recent C++11 standard, and the second, “C++14 Early thoughts” was an exciting description of some of the features that might go into the next standard.

One of those features, which Bjarne called “Terse” Templates, might be a good idea, but the syntax Bjarne proposed seems like a bad idea to me, because it leaks unwanted names into the namespace containing the function you are writing.

Allow me to explain.

Background – Concepts Lite

I attended another excellent talk before Bjarne’s, called “Concepts Lite-Constraining Templates with Predicates” by Andrew Sutton, introducing “Concepts Lite”, which is an attempt to salvage a manageable language feature from the very large “Concepts” feature that failed to make it into C++11.

My (so far very basic) understanding of Concepts Lite is that it is a way of defining conditions that state whether a template will be expanded for a given type.

So, in C++11 (and C++98), we can declare a (stupid) template function like so:

template<typename ListOfInt>
int first( ListOfInt& list ) { return list.size() > 0 ? list[0] : 0; }

The code in this function template assumes that list has a size method, and an operator[] method. We tried to “suggest” this, by naming our template parameter ListOfInt, but the poor programmer may not realise exactly what we meant.

If we do the wrong thing, and try to use the first function with an int argument:

int i = 3;
first( i );

It goes wrong, because ints don’t have a size method:

In function 'int first(ListOfInt&) [with ListOfInt = int]':
error: subscripted value is neither array nor pointer
error: request for member 'size' in 'list', which is of non-class type 'int'

This error is not too obscure, but in complex cases the errors can be extremely long, and point to problems that appear to be unrelated to the code we are writing.

Really what we want to know is that int is not a ListOfInt.

Concepts Lite give us the ability to define what a ListOfInt means, and only expand the template for types that match that definition.

In our example we would do something like this:

template<typename ListOfInt> requires SizeAndIndex<ListOfInt>()
int first( ListOfInt& list ) { return list.size() > 0 ? list[0] : 0; }

(There is actually a neater syntax, but we’ll do it like this for now because we need the more verbose form later.)

What this means is that this template function will only be expanded for types that satisfy the constraint.

The definition of SizeAndIndex is outside the scope of this article – it allows us to check whether types satisfy some conditions. In this case we assume it checks that the type contains the methods we use.

Now when we do the wrong thing:

int i = 3;
first( i );

We get a simple error message, that properly tells us what’s wrong:

error: no matching call to ‘first(int list)’
note: candidate is ‘first(ListOfInt& list)’
note: where ListOfInt = int
note: template constraints not satisfied
note: ‘ListOfInt’ is not a/an ‘SizeAndIndex’ type since
note: ‘list.size()’ is not valid syntax

(The above is fiction, but Andrew assures us he gets real errors like this with his prototype.)

So Concepts Lite gives us the optional ability to check that our template parameters are what we expected them to be, giving a decent error message, instead of waiting for something to fail much later when we compile the instantiated template.

So far so utterly cool. (And, in my ill-informed opinion, the only bit of Concepts I really wanted anyway.)

There’s more information on this feature here: Concepts Lite: Constraining Templates with Predicates and here: Concepts-Lite.

Constraints on multiple types

The Concepts Lite feature as proposed allows us to specify constraints that describe how multiple types relate to each other, by doing something like this:

template<typename Victim1, typename Victim2> requires Lakosable<Victim1, Victim2>
void lakos( Victim1 a, Victim2 b );

Here the Lakosable constraint can specify conditions that describe how the two types relate to each other, for example that Victim1::value_type is equal to the type of Victim2.

This is very good.

Now, the bit I want to argue against.

“Terse” Templates – the syntax I don’t like

Bjarne gave us an example of the std::merge function, which has lots of arguments, and very complex constraints on them. He showed us that these could all be nicely wrapped into a single Mergeable constraint (similar to the Lakosable constraint above) but he argued that there was still too much repetition. The repetition comes from the fact that several functions in the standard library have the exact same template parameters, with the exact same constraints on them, and that you have to mention the whole list of template parameters twice: once after the template keyword, and once in the requires condition.

This led him to look for a terser syntax.

So, he proposed a modest new construct that looks like this:

using Lakosable{Victim1,Victim2}; // (1)

that allows a radical departure from everything that has gone before in terms of declaring templates. After we’ve made the declaration (1), we can declare the exact function we declared above with this little line:

void lakos( Victim1 a, Victim2 b ); // (2)

The using declaration in (1) makes the names Victim1 and Victim2 available in the current namespace, and gives them special powers that mean functions taking parameters of type Victim1 or Victim2 are automatically function templates, even though the template keyword is nowhere to be seen.

There was some resistance in the room to this proposal. Most of it focussed on (2), and the fact that templates were being declared without it being visible because of the lack of the template keyword.

I’m actually ok with (2). In fact, my ficticious programming language Pepper (which represents everything I think is Right in programming languages) provides a feature very much like this – all non-definite parameter types act as “implicit” templates in Pepper (see “implicit_templates.pepper” on the Examples page).

Bjarne made a reasonable defence of (2), arguing that we often want new features to be “signposted” by new keywords (he cited user-defined types as an example – apparently some people wanted to require “class MyClass” instead of just “MyClass” every time we referred to a user-defined type) but later when they are familiar we want less verbose syntax. (Presumably the “new” feature he was talking about here is templates.)

My problem is with (1).

As my neighbour in the talk (whose name I missed, sorry) pointed out, what (1) does is dump 2 new names Victim1 and Victim2 in the namespace containing the lakos function template.

No-one wants these names.

In fact, why are we doing any of this?

The sole purpose of the exercise is to constrain the lakos function template. Why is the result putting 2 names into the namespace?

More seriously, in the case of the standard library, these names will go into the std:: namespace, and there could easily be clashes. If the std::merge function uses the name For for one of its template parameters (a Forward_iterator), and std::copy wants to use one with the same name, but with different constraints, it will override the definition of For.

I.e. If we do this:

namespace std {
using Mergeable{For,For2,Out};
// define std::merge
}

// and somewhere else:

namespace std {
using Copyable{For,Out};
// define std::copy
}

then the (useless) value of std::For will be different depending on the order in which we import the header files.

I Think

I think.

Please correct me if I’m wrong.

Conclusion

If I’m right, this all seems bad and Wrong.

What was wrong with:

template<typename Victim1, typename Victim2> requires Lakosable<Victim1, Victim2>
void lakos( Victim1 a, Victim2 b );

anyway?

My First Raspberry Pi Game – Part 07 – A green circle

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

Writing your first ever computer program on the Raspberry Pi.

We’re going to write a game that tests your reactions – press a key when you see green, but don’t when you see red.

Today we see some of what we have been waiting for – a genuine bona-fide green circle, made by you!

We’re going to need some random numbers, so edit your program in LeafPad, and add a line, just before import pygame near the top:

import random

This makes the “random” module available to us so we can make some numbers later.

Remember we had a function called “wait”, but it never did anything? It was supposed to wait for a random amount of time before we showed our green or red shape. Let’s write it now. Find the empty wait function and replace it with:

def wait():
    time_to_wait = random.randint( 1500, 3000 ) # Between 1.5 and 3 seconds
    pygame.time.wait( time_to_wait ) # Note bug: can't quit during this time

The first line makes a variable time_to_wait and puts a random number into it. The random.randint function gives us a random number between the two numbers we supplied, so here between 1,500 and 3,000. time_to_wait is a time in milliseconds, so this means between one and half and three seconds.

After the closing bracket, we have a hash symbol #, and then some writing. This is a “comment”, and it is completely ignored by Python. It’s just for us.

[As time goes on, I hope you will begin to see programming more and more as talking to other people, not just to the computer. It’s fairly easy to write a computer program, but much harder to understand one written by someone else. Most programs live a long time, and people need to understand them to keep them up-to-date, so making them as easy to understand as possible is very important. Comments are one way to help people understand, but in a way they are a last resort – if possible, the code itself should be so easy to understand that you don’t need many comments. Here, I thought that the translation between seconds and milliseconds might be helpful to someone looking at this later.]

The next line uses a function inside PyGame’s time module to wait for the amount of time we give it (in milliseconds, stored in time_to_wait). Note that this is not the same wait function we have seen before, pygame.event.wait. That one waits forever for an event to happen, but this one waits (and can’t be interrupted) for the amount of time we say.

I’ve added another comment to this line saying that there’s a bug in our program: if we write it like this, you can’t actually quit the game by closing the window while we’re waiting. The pygame.time.wait function won’t be interrupted by the window being closed, so we’ll ignore it. This is almost unbearably rude, but don’t worry – we’ll fix it soon (ish).

And now for the really exciting part: we’re going to draw a green shape on the screen. Let’s make a function, just above the shape function, called green_shape:

def green_shape():
    green = pygame.Color( "green" )
    centre = ( screen.get_width() / 2, screen.get_height() / 2 )
    radius = screen.get_width() / 3

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, green, centre, radius, 0 )

    pygame.display.flip()

This code makes a variable green holding onto the colour green, one called centre holding the co-ordinates of the centre of the screen, and one called radius holding the size of the circle we want to draw.

Then it uses the fill function on screen to colour in the screen white, and then draws our circle with a call to pygame.draw.circle, using the variables we have prepared as arguments, telling it where to draw the circle, in what colour, and what size.

Finally it uses flip as before to tell PyGame we have finished.

The last piece of today’s jigsaw is just to call the function we created above. Find the empty shape function, and make it look like this:

def shape():
    green_shape()

This literally just means run the green_shape function.

Take a deep breath, prepare to be excited, open LXTerminal and run our new program in the usual way:

./redgreen.py

If all has gone well, the ready screen will appear for a couple of seconds, before a white screen with a big green circle on it appears. This will then go away when you press a key.

If something goes wrong, check back what you typed, and compare your version against mine: redgreen.py.

Next time, we’ll find out whether you pressed a key or were too slow!

My First Raspberry Pi Game – Part 06 – A better class of waiting

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

Writing your first ever computer program on the Raspberry Pi.

Today we wait, but better, while we show the ready screen we made last time. In the process we cover two of the most important things you need to understand to write computer programs.

The program we’ve written so far can wait around for something to happen, but it can’t distinguish between the various possible “somethings” that might happen. Specifically, it finishes very abruptly if we even move our mouse over the window!

In this part we’ll teach our program to ignore the movements of the mouse, but keep looking out for events it is interested in. We’ll also make it able to exit quickly if someone closes its window.

First, we need to get hold of the sys object (actually it’s called a “module”) which allows us to do things with the system, like quit, which is what we’re going to do with it.

Open up LeadPad again, and immediately above the import pygame line, add this:

import sys

Now we’re going to write a new function that allows us to exit the game immediately, whenever we want to. Just above the def ready_screen() line, add this new function:

def quit():
    pygame.quit()
    sys.exit()

This function tells PyGame we are finishing (by calling pygame.quit), then exits: sys.exit() stops everything dead.

Finally, we make our waiting a bit posher, by editing the end function look like this:

def end():
    pygame.event.clear()
    event_types_that_cancel = pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN
    waiting = True
    while waiting:
        evt = pygame.event.wait()
        if evt.type == pygame.QUIT:
            quit()
        elif evt.type in event_types_that_cancel:
            waiting = False

There’s quite a lot here, but we’ll go through it line by line.

First, we clear the events as before using pygame.event.clear to make sure anything that has already happened doesn’t interfere with us.

Next we make a variable called event_types_that_cancel that is a list of all the types of events that we care about. They are key presses (KEYDOWN), and mouse clicks (MOUSEBUTTONDOWN). We’ll use this variable later.

Now we make another variable, called waiting. We use this to decide when we’ve finished. We set it to True, which means we are waiting, i.e. we haven’t finished.

The next line while waiting is the start of a loop, which means a piece of code we run lots of times. A “while” loop keeps on running until something happens. In this case, the lines after while waiting: will run again and again until the waiting variable becomes False.

The rest of the lines are all “inside” the loop, meaning they run again and again until the loop finishes. Notice that they are indented by a further 4 spaces to show that they are inside. If we had more lines later that were not indented, they would run after the loop had finished.

The first line creates a variable called evt that holds on to what came back when we called the function pygame.event.wait(). This function waits until an event happens. When an event happens, it could be a mouse movement, or a key press, or one of several other types of events. The old version of this code just called pygame.event.wait(), but didn’t look at what type of event happened. That’s why it finished even when you moved the mouse over the window. This new version captures the event that happened in the evt variable, and then does different things depending on what type of event it was.

The line starting with if lets us decide what to do based on what is happening. The first decision we make is evt.type == pygame.QUIT, which means if the type of event we have found is a special QUIT event. This type of event happens if the user closes the window by clicking the “X” in the top right-hand corner. If this happened, we go on to the next line, which calls the quit() function we created earlier. If this didn’t happen, we skip that line, and go on to the next one that is only indented as much as the original if line.

The next line after we skip is the one starting with elif. The “condition” we are checking (decision we are making) is whether evt.type in event_types_that_cancel which means is the event we have seen one of the ones we are interested it – is its type one of the things in event_types_that_cancel. event_types_that_cancel is a list containing the event type for mouse clicks, and the one for key presses, so if something interesting happened we will go to the next line, which is waiting = False. This sets waiting to False, meaning we will stop the loop. If the event was a different type (e.g. a mouse movement), we will skip the waiting = False line as well.

If neither of the conditions was true (so the event was not the user closing the window, or pressing a key or clicking the mouse) then we do nothing in the if and elif bit, and because we’re in a loop, we go back to the beginning and wait() again for another event. This goes on forever until one of the events we’re interested in happens. When it does, we either quit() immediately, or stop looping because waiting becomes False (meaning the while line lets us escape). When we’ve stopped looping we carry on, leaving the end function, and get to the end of the program.

If you can understand this you have just grasped two of the most important parts of programming – looping and conditional execution.

I suggest a long cup of tea.

While you’re sipping, try out our new program by opening LXTerminal as before, and typing the usual incantation:

./redgreen.py

Notice this time it doesn’t quit when you move the mouse, but it does if you click, or press a key, or close the window.

If it doesn’t work compare your program with my version: redgreen.py.

Next time we’ll make an actual green shape appear, as promised a long time ago!

My First Raspberry Pi Game – Part 05 – Say something

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

Writing your first ever computer program on the Raspberry Pi.

Today we will write some writing on that blank screen we made last time.

But first, a couple of tricks (we are doing magic after all). We’re going to make our program know it is a Python program, without needing to be told. To do this we need to do 2 things.

First, open up LeadPad as normal and add this line at the very (very) top of the file. Make sure there are no empty lines above it:

#!/usr/bin/env python

That’s a “hash” (or, for Americans, “pound”) symbol, followed by an exclamation mark. Note that all the slashes are forward slashes, not backward.

This tells our Raspberry Pi that this is a Python program. Now we need to tell our Pi that this program is allowed to run by itself, instead of its name being passed to the python program like we have been doing before.

To do this, open up LXTerminal as before, and type exactly this (and press Return):

chmod +x redgreen.py

If all of this worked correctly, you should be able to run our program in a new way. Instead of typing python redgreen.py like we were before, we can type this in to LXTerminal:

./redgreen.py

That’s a dot, followed by a forward slash, followed by the name of our program.

This means run the program in this directory (that is the “./” part) called “redgreen.py”. Your Pi will look at redgreen.py and find the line we added that starts with “#!” and know to use Python to run it.

Now let’s get on with writing something on the screen. Go back to LeafPad and change the line starting with screen_size = to be these 3 lines:

screen_width = 640
screen_height = 480
screen_size = screen_width, screen_height

This creates 3 variables – screen_width, screen_height and the one we had before screen_size, which is now made by putting the first 2 together. We’re going to use screen_height later.

Just below those 3 lines, type this:

screen = None
ready_text = None

This gets 2 variables ready for us, and makes them empty. We’re going to fill them in inside start.

Change the start function to look exactly like this:

def start():
    global screen, ready_text
    pygame.init()
    screen = pygame.display.set_mode( screen_size )
    font = pygame.font.Font( None, screen_height / 5 )
    ready_text = font.render( "Ready?", 1, pygame.Color( "white" ) )

The green lines above are the bits we’ve added. The line beginning global tells Python we want to work with those variables we got ready earlier inside this function, even though we created them outside it. (Without saying they were “global” we would be in danger of working with versions of them that only existed while we were inside the function, and disappeared as soon as we left.)

The font line makes a new font (a font is a typeface, or way of writing text). The first argument we passed was None because we don’t care at the moment which font we use (e.g. “Arial” or “Times New Roman”) – we are happy with the default. The second argument is for the size of the font we want, and we passed in screen_height / 5, which means the value of the screen_height variable we created near the top, divided by 5. The “/” character is how we write division in Python – it is supposed to look a bit like a fraction.

Finally, on the last line we create another variable called ready_text, which contains the “rendered” version of the word “Ready?”, using the font we created, in white. “Render” means we create a picture showing the writing we wanted. We’ll draw this picture onto the screen in a second.

Now that all our preparation is over, we can finally write a fuller version of the ready_screen function. Change it to look like this:

def ready_screen():
    textpos = ready_text.get_rect(
        centerx = screen.get_width() / 2,
        centery = screen.get_height() / 2
    )

    screen.blit( ready_text, textpos )
    pygame.display.flip()

The first 4 lines (textpos up to the closing bracket all on its own) are really all one “line of code” – they are like one sentence of our program, that happens to span multiple lines. In Python if we want to continue a sentence (we call it a “statement”) we just leave a bracket unclosed. Python knows we have finished when we have closed all the brackets.

This “line” from textpost = up to ) creates a variable called textpos, which contains the place on the screen where we want to put our writing. We look inside ready_text (which is our rendered writing that we created above) for a function called get_rect that calculates a rectangle for us that is the right place on the screen to put the writing. The arguments we pass to get_rect are screen.get_width() / 2 and screen.get_height() / 2, which are telling it that it should calculate the rectangle by putting its centre in the middle of the screen. The middle of the screen is half-way across its width, and half-way down its height, which is why we are dividing the width and the height of the screen by 2.

Something worth noticing here is that the arguments to get_rect have names – we wrote centerx = and centery =. In Python we are allowed to give the names of arguments, or sometimes we can miss them out if we are happy just to put them in the right order. The get_rect function can actually take lots of different arguments, so it needs to know which ones you mean, which is why we named them.

Finally the last 2 lines do the real work. The screen.blit line tells PyGame to write the ready_text picture (the rendered writing) onto the screen at the position stored inside textpos. pygame.display.flip() is what we do to tell PyGame we’ve finished messing about with the screen, and we’re ready for it to display what we’ve done.

[The word “blit” is an oddity from the olden days which I’m afraid you’ll just have to memorise, and “flip” comes from the fact that behind the scenes there are really two screens – the one we are displaying, and the one we are working on. flip() switches them over, displaying the one we were working on, and making the other one ready to be worked on.]

If you’ve got this far, well done! With any luck, we’re going to see the word “Ready?” on the screen in big letters.

Switch to LXTerminal again and type our new spell:

./redgreen.py

Don’t move the mouse or press anything: a window should appear, with the word “Ready?” written in big white letters. When you press a key or move the mouse over it, it should disappear.

If something goes wrong, check back over the instructions carefully, and compare your file with this one: redgreen.py.

My First Raspberry Pi Game – Part 04 – A small black screen

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

Writing your first ever computer program on the Raspberry Pi.

Today we will get an actual window to appear, with nothing on it!

Last time we wrote a magic spell describing the bare outline of what how our game will work. It’s going to pause, show a shape, and then the player must either press a key (if it’s green) or not press a key (if it’s red).

The program we’ve written calls several mini-programs called functions, but they don’t exist yet, and if we run it, it fails with an error. The names of the functions we have imagined are start, ready_screen, wait, shape and end.

The first thing we need to do is write those functions, so that the program runs correctly, even though it does nothing.

Open up LeafPad again and open redgreen.py from inside the pi folder. At the top, above the code we’ve already written (which uses the functions) type exactly this:

def start():
    pass

def ready_screen():
    pass

def wait():
    pass

def shape():
    pass

def end():
    pass

Notice that the word pass is “indented” by 4 spaces. This is how Python knows which lines of code are part of your function, and which are another part of the program. It’s very important that all lines are indented by the same amount, and that you never mix “tab” characters with spaces. To make life simple, I suggest always using 4 spaces.

What we’ve done is define 5 functions (the ones we call further down). def just means define a function, and we’ve followed that by the name of the function, then (). So far, each of our functions is empty: they are all just one line, which says pass, which means “do nothing”.

If we’ve typed this correctly, our program should now run correctly, and do nothing. Let’s try it. Open LXTerminal and type:

python redgreen.py

If it’s working, the computer should say absolutely nothing to you, and give you another prompt, ending with $.

If you get an error message, read it (especially the last line) and try to work out what you typed wrong.

Now we’re going to write some actual useful code, and make a black screen appear.

At the very top, above everything else we’ve done today, add this line:

import pygame

This tells Python we want to use the PyGame library, which is some code written by someone else, designed to help us write games in Python. The Raspberry Pi comes with PyGame already installed, so to use it all we need to do is add this line.

Just below that line, type this:

screen_size = 640, 480

This is how we define a “variable”. A variable is a thing with a name and a value that we can refer back to later. The variable’s name is screen_size and its value is “640, 480”. We’re going to use this variable to remember how big we want our window to be.

Now we need to modify our start function to bring up a black screen. Replace both lines of the start function with this:

def start():
    pygame.init()
    screen = pygame.display.set_mode( screen_size )

The first line, starting with def is the same as before – it means we are defining a function called “start”.

Where we used to have just pass, we now have 2 lines (both indented by 4 spaces as before). The pygame.init() line just tells PyGame to get ready to start. We need something like this in our program whenever we use PyGame. The second line creates a window of the size we want. It calls a function inside pygame. The dots mean we should “look inside” the thing on the left, so pygame.display.set_mode means something like “look inside pygame for something called display, then look inside display for something called set_mode”. set_mode is a function, which we are calling (that is what the brackets mean).

Unlike other functions we have called, which just use “()”, set_mode takes an “argument” which means we are passing information to it. The information we are passing is the size of the screen, which we have already stored in the variable screen_size. So the value “640, 480” gets passed in to set_mode, telling it how big to make the window.

We’ve made a window, but if we leave things as they are now, we will open it, then immediately finish, so it will go away again. We need to wait a while.

Edit the end function to look like this:

def end():
    pygame.event.clear()
    pygame.event.wait()

This code means “wait until something happens”.

The first line (clear) tells PyGame we’re not interested in anything that happened before – clear the list of events that has built up – and the second line (wait) means wait until something happens. In this case we are waiting until the person using the program presses a key, closes the window, or even moves the mouse in front of the window.

Let’s try it out. Open up LXTerminal as before, and type the same thing we’ve typed before:

python redgreen.py

Make sure you don’t move the mouse or press any keys after you’ve pressed Return. If all has gone well, a small, black, empty window will appear. Then if you press a key or move the mouse in front of it, it should disappear.

If this isn’t what happens, check back and make sure you typed everything exactly as above. Your complete file should look like this: redgreen.py.

Well done! You made a window appear. Next time, if we’re lucky, we’ll put something in it…