views:

425

answers:

11

I just came across this question in the Go FAQ, and it reminded me of something that's been bugging me for a while. Unfortunately, I don't really see what the answer is getting at.

It seems like almost every non C-like language puts the type after the variable name, like so:

var : int

Just out of sheer curiosity, why is this? Are there advantages to choosing one or the other?

+1  A: 

It's just how the language was designed. Visual Basic has always been this way.

Most (if not all) curly brace languages put the type first. This is more intuitive to me, as the same position also specifies the return type of a method. So the inputs go into the parenthesis, and the output goes out the back of the method name.

Robert Harvey
laguages that put the type last also put the return type last, eg name(arg : type) : return_type
Chris Dodd
C++0x allows you to put the function return type last: `auto func(int arg1) -> int`
jmucchiello
+7  A: 

the 'most other' languages you speak of are those that are more declarative. They aim to allow you to program more along the lines you think in (assuming you aren't boxed into imperative thinking).

type last reads as 'create a variable called NAME of type TYPE'

this is the opposite of course to saying 'create a TYPE called NAME', but when you think about it, what the value is for is more important than the type, the type is merely a programmatic constraint on the data

Luke Schafer
+1 Well said...and 15 more characters.
wheaties
+1  A: 

I'm not sure, but I think it's got to do with the "name vs. noun" concept.

Essentially, if you put the type first (such as "int varname"), you're declaring an "integer named 'varname'"; that is, you're giving an instance of a type a name. However, if you put the name first, and then the type (such as "varname : int"), you're saying "this is 'varname'; it's an integer". In the first case, you're giving an instance of something a name; in the second, you're defining a noun and stating that it's an instance of something.

It's a bit like if you were defining a table as a piece of furniture; saying "this is furniture and I call it 'table'" (type first) is different from saying "a table is a kind of furniture" (type last).

McWafflestix
+2  A: 

Putting the type first helps in parsing. For instance, in C, if you declared variables like

x int;

When you parse just the x, then you don't know whether x is a declaration or an expression. In contrast, with

int x;

When you parse the int, you know you're in a declaration (types always start a declaration of some sort).

Given progress in parsing languages, this slight help isn't terribly useful nowadays.

Keith Randall
If ease of parsing is your goal, you would have a keyword that introduces all variable declarations, such as var: `var i: int` or `var int i`
jmucchiello
And for user-defined types (typedefs): xyz abc; -- which is the type and which is the name? As long as the language agrees on the rules, there isn't a problem -- and if the language can't agree on the rules, it probably isn't parseable.
Jonathan Leffler
A: 

What about dynamically (cheers @wcoenen) typed languages? You just use the variable.

Spence
You mean "dynamically typed". "weakly vs strongly typed" is not the same distinction as "statically vs dynamically typed". For example, python is dynamically and strongly typed language: http://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language
Wim Coenen
Weakly typed languages like awk or (old) Perl; or Fortran with its implicitly typed variables - names starting with I through N are integers; the rest are REAL.
Jonathan Leffler
+4  A: 

If the name of the variable starts at column 0, it's easier to find the name of the variable.

Compare

QHash<QString, QPair<int, QString> > hash;

and

hash : QHash<QString, QPair<int, QString> >;

Now imagine how much more readable your typical C++ header could be.

Jurily
+1 name first is more readable, it clues you in to what the statement is acting on straight away... assuming of course you're using meaningful variable names.
bobince
+6  A: 

In formal language theory and type theory, it's almost always written as var: type. For instance, in the typed lambda calculus you'll see proofs containing statements such as:

x : A   y : B
-------------
 \x.y : A->B

I don't think it really matters, but I think there are two justifications: one is that "x : A" is read "x is of type A", the other is that a type is like a set (e.g. int is the set of integers), and the notation is related to "x ε A".

Some of this stuff pre-dates the modern languages you're thinking of.

Edmund
+4  A: 

An increasing trend is to not state the type at all, or to optionally state the type. This could be a dynamically typed langauge where there really is no type on the variable, or it could be a statically typed language which infers the type from the context.

If the type is sometimes given and sometimes inferred, then it's easier to read if the optional bit comes afterwards.

There are also trends related to whether a language regards itself as coming from the C school or the functional school or whatever, but these are a waste of time. The languages which improve on their predecessors and are worth learning are the ones that are willing to accept input from all different schools based on merit, not be picky about a feature's heritage.

Marcus Downing
A: 

Fortran puts the type first:

REAL*4 I,J,K
INTEGER*4 A,B,C

And yes, there's a (very feeble) joke there for those familiar with Fortran.

There is room to argue that this is easier than C, which puts the type information around the name when the type is complex enough (pointers to functions, for example).

Jonathan Leffler
You've invented obfuscate FORTRAN. Well done.
jmucchiello
+5  A: 

There is a parsing issue, as Keith Randall says, but it isn't what he describes. The "not knowing whether it is a declaration or an expression" simply doesn't matter - you don't care whether it's an expression or a declaration until you've parsed the whole thing anyway, at which point the ambiguity is resolved.

Using a context-free parser, it doesn't matter in the slightest whether the type comes before or after the variable name. What matters is that you don't need to look up user-defined type names to understand the type specification - you don't need to have understood everything that came before in order to understand the current token.

Pascal syntax is context-free - if not completely, at least WRT this issue. The fact that the variable name comes first is less important than details such as the colon separator and the syntax of type descriptions.

C syntax is context-sensitive. In order for the parser to determine where a type description ends and which token is the variable name, it needs to have already interpreted everything that came before so that it can determine whether a given identifier token is the variable name or just another token contributing to the type description.

Because C syntax is context-sensitive, it very difficult (if not impossible) to parse using traditional parser-generator tools such as yacc/bison, whereas Pascal syntax is easy to parse using the same tools. That said, there are parser generators now that can cope with C and even C++ syntax. Although it's not properly documented or in a 1.? release etc, my personal favorite is Kelbt, which uses backtracking LR and supports semantic "undo" - basically undoing additions to the symbol table when speculative parses turn out to be wrong.

In practice, C and C++ parsers are usually hand-written, mixing recursive descent and precedence parsing. I assume the same applies to Java and C#.

Incidentally, similar issues with context sensitivity in C++ parsing have created a lot of nasties. The "Alternative Function Syntax" for C++0x is working around a similar issue by moving a type specification to the end and placing it after a separator - very much like the Pascal colon for function return types. It doesn't get rid of the context sensitivity, but adopting that Pascal-like convention does make it a bit more manageable.

Steve314
*EDIT* - confession - with recursive descent, it *is* somewhat easier to parse if the construct is easily identifiable near its start. Having a keyword near the start is good for that. I don't really count C type-then-variable-name in this, though, because it doesn't really identify the construct any earlier than variable-then-type. It could be a variable declaration - or a function declaration, or a function-style typecast on an a variable on the left-hand-side of an assignment, or...
Steve314
Isn't this more of a function of the colon though? Like I can tell that `var : int` is a variable name because of the colon. It seems like it would be just as easy to do `int : var` (albeit maybe a bit more ugly :-) ).
Jason Baker
@Jason Baker - sorry for the delay. A compiler can handle "varname int" or "int varname", assuming "int" is a keyword. However, "varname mytype" or "mytype varname" is more of an issue - not because "mytype" is an identifier exactly, but because you need the dictionary lookup to determine which syntactic constructs might apply. The old C syntax where struct names weren't valid typenames (you'd write "struct structname myvar;") was simpler, as that "struct" prefix shows syntactically that the type *is* a type. A colon can help, but it's neither the whole nor the only solution.
Steve314
+1  A: 

I always thought the way C does it was slightly peculiar: instead of constructing types, the user has to declare them implicitly. It's not just before/after the variable name; in general, you may need to embed the variable name among the type attributes (or, in some usage, to embed an empty space where the name would be if you were actually declaring one).

As a weak form of pattern-matching, it is intelligable to some extent, but it doesn't seem to provide any particular advantages, either. And, trying to write (or read) a function pointer type can easily take you beyond the point of ready intelligability. So overall this aspect of C is a disadvantage, and I'm happy to see that Go has left it behind.

comingstorm