I think the C and C++ computer languages don't have enough keywords. The current set may have been appropriate for the earliest C compilers but there are many keywords whose absence I often curse. Unfortunately it's very difficult to add new keywords to C++ because doing so tends to break a lot of existing programs. This is a curious difference between human languages and computer languages - although it seems like computer languages move much faster than human languages, the opposite is in fact true because you can add words to human languages without changing the meaning of existing documents.
Anyway, here are some of the keywords and constructs I'd like to be able to use in my programs:
Two part loops:
Often I find myself wanting a loop with the test in the middle. I usually end up writing these as an infinite loop with a "break" statement:
do {
x;
if (y)
break;
z;
} while (true); |
do {
x;
if (y)
break;
z;
} while (true);
I'd prefer to write it like this:
do {
x;
} while (!y) {
z;
} |
do {
x;
} while (!y) {
z;
}
[I realized sometime after writing this that I actually got this idea from here.]
until and unless:
I'd also like to be able to use "until" instead of "while" to reverse the sense of the test, like this:
do {
x;
} until (y) {
z;
} |
do {
x;
} until (y) {
z;
}
Similarly, I'd like to be able to use "unless (x)" instead of "if (!x)". While this doesn't really make programs any shorter, I think being able to eliminate the "!" makes programs easier to understand and helps with the "say what you mean" principle.
Grouping if statements:
As an alternative to using the "switch" statement, I sometimes write:
if (a)
b;
else
if (c)
d;
else
if (e)
f;
else
g; |
if (a)
b;
else
if (c)
d;
else
if (e)
f;
else
g;
But this has an unforuntate tendency to lean to the right. I'd prefer to write:
if (a)
b;
elseif (c)
d;
elseif (e)
f;
else
g; |
if (a)
b;
elseif (c)
d;
elseif (e)
f;
else
g;
and leave the "else if" construct for situations like:
if (a)
if (b)
c;
else
d;
else
if (b)
e;
else
f; |
if (a)
if (b)
c;
else
d;
else
if (b)
e;
else
f;
Again, it doesn't make a big difference syntactically but does tend to shed more light on the programmer's intention, which is always a good thing. Similarly there should be an "elseunless" keyword meaning elseif with the sense reversed.
[These ideas came from here, though his "unless" is a bit different to mine, and I've never missed "when".]
Done clauses:
Sometimes I'm using a loop for a search and want to do something in particular if the thing I was searching for was not found. Normally I'd have to write something like this:
bool found = false;
do {
Item current = get_next_item();
if (current == target) {
process(current);
found=true;
break;
}
} while (current != last);
if (!found)
fail(target); |
bool found = false;
do {
Item current = get_next_item();
if (current == target) {
process(current);
found=true;
break;
}
} while (current != last);
if (!found)
fail(target);
I'd prefer it if loops had something analogous to an "else" clause which is called only if the loop condition fails. I call this the "done" clause. This would make the example look like this:
do {
Item current = get_next_item();
if (current == target) {
process(current);
break;
}
} while (current != last); done
fail(target); |
do {
Item current = get_next_item();
if (current == target) {
process(current);
break;
}
} while (current != last); done
fail(target);
Much neater.
Multiple break
I'd like to break out of multiple loops at once. Suppose I'm searching a 2D array:
for (int x = 0; x < 10; ++x) {
int y = 0;
for (; y < 10; ++y)
if (array[y][x] == target) {
foobar(x, y);
break;
}
if (y < 10)
break;
} |
for (int x = 0; x < 10; ++x) {
int y = 0;
for (; y < 10; ++y)
if (array[y][x] == target) {
foobar(x, y);
break;
}
if (y < 10)
break;
}
I'd much rather write it as:
for (int x = 0; x < 10; ++x)
for (int y = 0; y < 10; ++y)
if (array[y][x] == target) {
foobar(x, y);
break break;
} |
for (int x = 0; x < 10; ++x)
for (int y = 0; y < 10; ++y)
if (array[y][x] == target) {
foobar(x, y);
break break;
}
The syntax "break continue" could be employed to mean "break out of the innermost loop and then do a 'continue' on the next loop out".
[I also posted this idea on comp.std.c++ here but it was shot down. I still think it's a good idea, though. That entire thread is a gold mine of good (and some not so good) programming language ideas.]
Exponentiation operator:
I'd like to change the meaning of the ^ operator to be exponentiation and have binary ~ mean XOR (giving a nice symmetry between unary/binary - (negative/minus) and unary/binary ~ (NOT/XOR)).
bool argument to if and while
It is surprising how many of the criticisms levelled at C and C++ can be traced back to a simple misfeature - allowing conditional statements ("if" and "while") to have arguments of any integral type. These statements should only accept bool values, thus sidestepping the whole "confusing = and ==" business altogether (well, at least until you want to compare two bool variables). The usual boolean operators !, &&, ||, ==, !=, <, >, <= and >= should all return bool values and !, && and || should also require their arguments to be bool. This would break a lot of programs, but they would be easy to fix (just sprinkle "!= 0" everywhere you see a "bool argument required" error.
Assignment not an operator
I think that having the assignment operator return a value is a mistake. I try to avoid using constructs like "if (a = b)" and "a = b = c;" in my code because they are overly terse and make refactoring more difficult. I would also eliminate the post increment and decrement operators (no more "c++"!) and make all assignments, increments and decrements statements instead of expressions. I'm not sure I would go so far as to separate functions into pure functions returning values which can be used in expressions and procedures which have no return values but can have side effects, but it is tempting.