I've been watching an interview with Herb Sutter on Channel9 and he mentioned at the end of the video that left to right language syntax would be on the top on his whishlist for a future C++ standard(although he acknowledges that modifying C++ in that way would pretty much make for a completely different beast).

Apart from:

  • more understandable by humans, clearer to the naked eye;e.g.

    //C syntax
    /*pointer to function taking a pointer to function(which takes 2 integers as 
    arguments and returns an int), and an int as arguments and returning an int*/
    int (*fp)(int (*ff)(int x, int y), int b)
    //Go analogous syntax which is left to write
    f func(func(int,int) int, int) int
  • easier to parse(leads to better tool support as mentioned in the video - e.g. code refactoring)

what other advantages are there with a "left to right" syntax in a programming language. I know only of Pascal and Go employing that kind of syntax(and Go does not even go the full way as I understand from this blog post from which I took also the examples) Would it be feasible to have a systems programming language with that kind of syntax?

  • 1
    haskell uses left to right: f :: (Int -> Int -> Int) -> Int -> Int Commented Aug 18, 2011 at 8:08
  • 1
    ActionScript as well: function strlen(s:String):int {...}. Also, typed lambda calculus (hence, Haskell).
    – outis
    Commented Aug 18, 2011 at 8:10
  • 2
    Could anyone explain please the closing votes :)? I cannot see any reason for closing it but maybe I'm asking a "wrong" question.
    – celavek
    Commented Aug 18, 2011 at 8:12
  • 1
    I did not vote to close, but, the comment by @Devjosh is pertinent, it's more appropriate for Programmers, hopefully someone will migrate it....
    – Nim
    Commented Aug 18, 2011 at 8:19
  • 3
    @Frank: and do not forget, in case of functions pointers, that the syntax is awkward because the actual type is split! That's a low blow... Commented Aug 18, 2011 at 12:17

3 Answers 3


The basic advantage is that parsing is simpler and unique. Note that after the line is parsed, the compiler will know what the exact type is, so from there on, how the type was defined is irrelevant.

Any function that returns an argument of array type, or function pointer type are hard to read currently:

// common way of obtaining the static size in elements of an array:
template <typename T, int N>
char (&array_size_impl( T (&)[N] ))[N];
// alternative parser:
template <typename T, int N>               // this would probably be changed also
array_simple_impl function( T [N] & ) char [N] &;

And there would be less chance for misunderstanding (as the most-vexing-parse):

// Current C++
type x( another_type() );      // create an instance x of type passing a
                               // default constructed another_type temporary?
                               // or declare a function x that returns type and takes as argument
                               // a function that has no arguments and returns another_type
// How the compiler reads it:
x function( function() another_type ) type;

// What many people mean:
x type { another_type{} };

Using a similar approach to uniform initialization in C++0x (i.e. {} to identify initialization). Note that with a left to right approach it is much clearer what we are defining. Many people (me for sure) have been bitten at any point by this parsing error in the past (more than once), and that would not be the case with a left-to-right syntax.

  • How about expressions? How would this "left to right syntax" affect the operator precedence and order of evaluation?
    – celavek
    Commented Aug 18, 2011 at 8:40
  • 1
    @celavek: If you go back to the interview, you will note that he does not want to change the whole syntax of the language, only declarations and definitions. Of course, that might permeate in other expressions, I am not too sure that the last line in the examples above is proper left-to-right (think on how the temporary is created, that might need to be changed... in C# that is solved by giving two semantics to the new operator for struct or class, which is not applicable to C++ as in C++ there is no distinctions on value/reference types. Commented Aug 18, 2011 at 8:56

I think you somewhat missed the point when you focused on the left-to-right bit.

The problem of C and C++ are the horrendous grammar they have, which is difficult to both read (humans) and parse (tools).

Having a more consistent (or regular) grammar makes it easier on both. And easier parsing mean easier tooling: most current tools do not get C++ right, not even the latest plugin of Eclipse as they sought to reinvent the wheel... and failed, and they probably have more people than the average OS project.

So you probably nailed it when focusing on reading and parsing... and that's a big deal :)

  • That’s a big surprise about Eclipse still being unable to parse things like the declarations above. Why don’t they use a real C parser like from gcc?
    – tchrist
    Commented Aug 18, 2011 at 14:07
  • @tchrist: I have detected two issues with Eclipse, and both seems linked to macros. Perhaps more a preprocessor issue than AST generation thus. Commented Aug 18, 2011 at 15:09

How We Got Here

The C syntax for declaring function points was intended to mirror usage. Consider a regular function declaration like this from <math.h>:

double round(double number);

To have a point variable you can assign that to with type safety using

fp = round;

you’d need to have declared that fp point variable this way:

double (*fp)(double number);

So all you have to do is look at how you would use the function, and replace the name of that function with a pointer reference, making round into *fp. However, you need an extra set of parens, which some would say makes it a bit messier.

Arguably, this used to be easier in the original C, which didn’t even have function signature, but let’s not go back there, ok?

The place it becomes especially nasty is figuring out how to declare a function that either takes as an argument or returns a pointer to a function, or both.

If you had a function:

void myhandler(int signo);

you could pass it to the signal function(3) this way:

signal(SIGHUP, myhandler);

or if you want to keep the old handler, then

old_handler = signal(SIGHUP, new_handler);

which is pretty easy. What is pretty easy — nor pretty, nor easy — is getting the declarations right.

signal(int signo, ???)

Well, you just go back to your function declaration and swap the name for a point reference:

signal(int sendsig, void (*hisfunc)(int gotsig));

Because you are not declaring gotsig, you might find it easier to read if you omit:

signal(int sendsig, void (*hisfunc)(int));

Or maybe not. :(

Except that that is not good enough, because signal(3) also returns the old handler, as in:

old_handler = signal(SIGHUP, new_handler);

So now you have to figure out how to declare all those.

void (*old_handler)(int gotsig);

is enough for the variable you’re going to assign to. Note that you are not really declaring gotsig here, only old_handler. So this is really enough:

void (*old_handler)(int);

That brings us to a correct definition for signal(3):

void (*signal(int signo, void (*handler)(int)))(int);

Typedefs to the Rescue

By this time, I think everyone will agree that that’s a mess. Sometimes it’s better to name your abstractions; often, really. With the right typedef, this becomes much easier to understand:

typedef void (*sig_t) (int);

Now your own handler variable becomes

sig_t old_handler, new_handler;

and your declaration for signal(3) becomes just

sig_t signal(int signo, sig_t handler);

which is suddenly comprehensible. Getting rid of the *’s also gets rid of some of the confusing parentheses (and they say parens always make things easier to understand — hah!). Your usage is still the same:

old_handler = signal(SIGHUP, new_handler);

but now you have chance of understanding the declarations for old_handler, new_handler, and even signal when you first encounter them or need to write them.


Very few C programmers, it turns out, are capable of devising the correct declarations for these things on their own without consulting reference materials.

I know, because we once had this very question on our interview questions for people doing kernel and device driver work. :) Sure, we lost a lot of candidates that way as they crashed and burned on the whiteboard. But we also avoided hiring people who claimed they had previous experience in this area but couldn’t actually do the work.

Because of this widespread difficulty, though, it is probably not just sensible but indeed reasonable to have a way to go about all those declarations that no longer require you to be a triple-alpha geek programmer sitting three sigmas above the mean just to use this sort of thing comfortably.

  • 1
    Contrived, hard to follow ... +1 for the effort though as it illustrates the point that it's sometimes hard to get that right in C.
    – celavek
    Commented Aug 18, 2011 at 19:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.