DEV Community

Discussion on: What ever happened to putting the object type on the left?

Collapse
 
jballanc profile image
Joshua Ballanco

To begin with a caveat, the following is based on my own intuition and experience (and no time to do any research to back it up). That said...


This is part of a more general trend of programming environments and languages moving from accommodating the machine to accommodating the programmer. Ask yourself, in a function's declaration, what's more important: the parameter names or their types? Consider:

Fraction make_fraction(int denominator, int numerator)

How would you call that function to make the fraction ½? If you said make_fraction(1, 2), then you were probably too distracted by the type annotations to notice that I flipped the argument order from what you might have naively expected. Placing the annotations on the right makes it easier to focus on what's important:

func makeFraction(denominator:Int, numerator:Int) -> Fraction

Furthermore, if the same function is overridden to accept more different types of arguments, but keeps the same basic semantics, it would be preferable if those functions looked similar at first glance:

Fraction make_fraction(int numerator, int denominator)
Fraction make_fraction(float numerator, int denominator)
Fraction make_fraction(int numerator, float denominator)
//...
func makeFraction(numerator:Int, denominator:Int) -> Fraction
func makeFraction(numerator:Float, denominator:Int) -> Fraction
func makeFraction(numerator:Int, denominator:Float) -> Fraction
//...

So why, then, were type declarations ever put on the left? Well, if you look back far enough you'll find that C function definitions used to be written like so:

Fraction
make_fraction(numerator, denominator)
int numerator;
int denominator;
{ /*...*/ }

Well, now, that doesn't seem so developer hostile, aside from having to repeat the names of the parameters. It does give us a clue into how type-on-left probably came about, though. Remember that C was originally nothing more than "portable assembly". Well, in assembly when you want to define a function there are a few things you need to do, including setting aside registers and/or stack space for the arguments that will be passed to the function. The most important bit of information for this space allocation is not the names of the parameters, but rather the type.

So, if you're writing a compiler for a language (and especially if you're on a very memory constrained system such that you can't just go placing things in memory willy-nilly for later retrieval), you'd want the first thing your compiler encounters in the language to be the most important. In this case, that means putting the type first so your compiler can do its layout calculations.

As for why more modern, sophisticated compilers (e.g. C++ and Java) kept this declaration form, inertia is a helluva drug, and doubly so in programming language design.