<p>Famously, C’s functions and variables have their types specified before the function/variable name:</p>
<pre><code>bar foo() {...}
bar foo = ...;
</code></pre>
<p>Most older C derivatives also use the prefix syntax (e.x. Java, C#, C++). However, many newer languages (e.x. Rust, Kotlin, Typescript) use a postfix type syntax:</p>
<pre><code>function foo(): bar {...}
var foo: bar = ...;
</code></pre>
<p>What are the advantages of the former syntax over the latter?</p>

<syntax><types><functions>
What are the advantages/disadvantages of prefix type syntax?
CC BY-SA 4.0
2023-08-20T01:13:40.470Z
The trailing `: type` syntax is usually called "pascal" or "modula" syntax, since that is where it originated.  This was ~1970, so actually predates C by a little bit.
Chris Dodd
CC BY-SA 4.0
2023-08-20T11:38:09.577Z
C++ actually has both prefix and postfix return types.
Toby Speight
CC BY-SA 4.0
2023-08-29T20:32:33.953Z
This is not a complete answer but I don't think anyone has mentioned this yet: With the type before the name, variables which are the same type line up and their names all begin at the same indentation level, automatically.
matt_rule
CC BY-SA 4.0
2023-05-20T20:44:18.860Z
[Exact duplicate of a question on CS.SE](https://cs.stackexchange.com/questions/109817/in-function-declarations-what-advantages-are-there-to-having-the-type-of-the-pa). Posting questions that already have an answer on Stack Exchange is not a good way to populate a private beta: it suggests that the new site doesn't have its own niche.
Gilles 'SO- stop being evil'
CC BY-SA 4.0
2023-05-20T21:07:09.607Z
also related (in relation to "cross-posting"): https://meta.stackexchange.com/q/64068/997587 and https://meta.stackexchange.com/q/354865/997587
starball
CC BY-SA 4.0
2023-05-20T23:48:59.733Z
@Gilles'SO-stopbeingevil' 1.  I did not realize this, than you for pointing out. 2. we have a bit of overlap with CS 3. This is still on topic, no?
Seggan
CC BY-SA 4.0
2023-05-21T00:00:05.360Z
@Seggan Yes, this is on-topic, so I didn't vote to close.
Gilles 'SO- stop being evil'
<p>One reason that C++ introduced <em>trailing return type</em> syntax is that this allows the return type to use <em>dependent names</em>.  That is, names that represent types only with the greater knowledge obtained when reaching this position, usually because they only name types in the context of an argument, often the implicit <code>this</code> argument of a member function.</p>
<p>Not being able to do that can be seen as a disadvantage of prefix position for return types.</p>

CC BY-SA 4.0
2023-08-20T11:44:39.150Z
2023-08-20T11:44:39.150Z
Toby Speight
<p>This is largely an arbitrary choice. One language did it some way, a long time ago, and then many but not all other languages copied a familiar syntax. That being said, the choice is not <em>completely</em> arbitrary. Putting the type before or after the variable name is largely cosmetic, but there are more differences than this between the C-style syntax and the Pascal-style syntax used in languages like Rust and Scala.</p>
<p>In early languages where variable declarations had a type, the syntax of a declaration was of the form <code><em>Type</em> <em>Name</em></code> where <code><em>Type</em></code> is a reserved word and <code><em>Name</em></code> is a name chosen by the programmer. Here the order is not arbitrary: first you say what kind of thing you're declaring, then you give it a name. Compilers at the time were very primitive and needed to know early on what they were parsing; writing <code>INTEGER X</code> let the compiler know immediately that it had to work on an integer declaration, whereas <code>X INTEGER</code> would have required the compiler to first remember that it had seen <code>X</code> and only after that it would have known that it was supposed to declare an integer variable. Languages of the 1950s and 1960s such as <a href="https://en.wikipedia.org/wiki/ALGOL" rel="noreferrer">ALGOL</a> and <a href="https://en.wikipedia.org/wiki/Fortran" rel="noreferrer">FORTRAN</a> tended to use this syntax. Interestingly, at the time, in programming language descriptions, <a href="https://hal.inria.fr/hal-01399694/document" rel="noreferrer">“type” had a more general meaning that it has today</a>: today it has a specific technical meaning that's more or less synonym with “datatype”, but at the time it had its ordinary English meaning, which could cover things like integer and real, but also things like label and statement.</p>
<p><a href="https://en.wikipedia.org/wiki/C_(programming_language)" rel="noreferrer">C</a> extended this syntax in a way that allowed defining <strong>compound types</strong>. In C, the syntax of a variable declaration mimics the syntax of its use. For example, <code>int x</code> declares an integer called <code>x</code>, and <code>int *p</code> declares a pointer-to-integer called <code>p</code>, and the expression <code>*p</code> has the type <code>int</code>. This syntax is not purely prefix because accessors can be suffixes: for example <code>a[1]</code> is an <code>int</code> if <code>a</code> is an array of <code>int</code> values, so the syntax to declare an array of integers is <code>int a[]</code>.</p>
<p>C became a very popular language, so many languages after it retained a similar syntax for several things including variable declarations and types.</p>
<p>The colon syntax goes back to at least <a href="https://en.wikipedia.org/wiki/Pascal_(programming_language)" rel="noreferrer">Pascal</a> in 1971. This is the syntax used by computer scientists at least since the early 1970s. I suspect that it started in theory papers and was adopted by Pascal and later by other languages, but for all I know it may have originated with Pascal. <a href="https://cstheory.stackexchange.com/questions/43971/why-colon-to-denote-that-a-value-belongs-to-a-type">Why colon to denote that a value belongs to a type?</a> discusses the origin of $x : T$ in computer science. Modern languages that draw from modern (or not-so-modern-anymore) theory tend to use the syntax that's familiar to computer scientists, including <a href="https://en.wikipedia.org/wiki/ML_(programming_language)" rel="noreferrer">ML</a>, <a href="https://en.wikipedia.org/wiki/Scala_(programming_language)" rel="noreferrer">Scala</a>, <a href="https://en.wikipedia.org/wiki/Swift_(programming_language)" rel="noreferrer">Swift</a>, <a href="https://en.wikipedia.org/wiki/Rust_(programming_language)" rel="noreferrer">Rust</a>, and many others. <a href="https://en.wikipedia.org/wiki/Haskell_(programming_language)" rel="noreferrer">Haskell</a> is somewhat unusual in using a double colon <code>::</code> where others use a colon <code>:</code>.</p>
<p>The order $x : T$ vs $T : x$ is arbitrary: these days, compilers don't mind, and for humans, it's just a matter of habit. However, having a punctuation sign between the variable name and the type is not arbitrary. Most languages that use this syntax also allow the left-hand side to be an expression, to form a type annotation. More importantly, the right-hand side is a <strong>type expression</strong>, not just a type name. Recall that C supports declarations of variables with compound types, but the syntax is somewhat awkward, with the variable name ending up somewhere in the middle. C's syntax does not work with compound types that are made of more than one type part. For example, in ML, <code>x : bool * int * string</code> means that <code>x</code> is a triple consisting of a boolean, an integer and a string. Haskell writes this <code>x :: (Bool, Integer, String)</code>. Both the ML and the Haskell way allow building complex types. The C approach fails: where do you put the variable name?</p>
<p>Languages such as Java and C# deviate from the C syntax by putting the whole type information before the variable name: <code>int[] a</code>, <code>(bool, int, string) x</code>, <code>List&lt;int&gt; v</code>. With no separator, it's impractical to allow both sides to have an arbitrary length, but these languages do support type expressions, which can be used to declare a variable.</p>
<p><em>(reposted from <a href="https://cs.stackexchange.com/questions/109817/in-function-declarations-what-advantages-are-there-to-having-the-type-of-the-pa/109978#109978">https://cs.stackexchange.com/questions/109817/in-function-declarations-what-advantages-are-there-to-having-the-type-of-the-pa/109978#109978</a>)</em></p>

CC BY-SA 4.0
2023-05-20T20:42:57.577Z
2023-05-20T20:42:57.577Z
Gilles 'SO- stop being evil'
CC BY-SA 4.0
2023-05-20T20:56:24.950Z
Can't C represent anonymous product types like `struct { bool first; int second; char* third; } x;`?
Bbrk24
CC BY-SA 4.0
2023-05-20T21:12:36.163Z
@Bbrk24 Yes, and those deviate from the idea that the declaration syntax matches the use syntax, because that becomes very clumsy when a type has multiple fundamental destructors: you can't write “the type such that `t.first` is a `bool` and `t.second` is an `int`” without repeating the type name `t`, which would be a lot of work for everybody and thankfully C didn't go that far.
Gilles 'SO- stop being evil'
CC BY-SA 4.0
2024-06-19T17:40:51.497Z
Algol 68 had “compound types” before C, with things like **struct** ( **int** *p*, *q* ) *s*; [1] **int** *a*
texdr.aft
<h2>Disadvantage: Making the variable name harder to find between the type syntax and value</h2>
<p>Having the type before the name can make it hard to find the name, which is the most important part of a declaration. Consider a line like this:</p>
<pre class="lang-cpp prettyprint-override"><code>std::pair&lt;std::unordered_map&lt;int, std::vector&lt;double*&gt;&gt;, std::unique_ptr&lt;unsigned long long&gt;&gt; const frobnicator = std::make_pair(create_frobni(), create_cator());
</code></pre>
<p>How long does it take you to find the name? Or even to recognize that this is a variable declaration?</p>

CC BY-SA 4.0
2023-07-19T07:57:49.840Z
2023-07-19T14:54:47.053Z
2023-07-19T14:54:47.053Z
xigoi
CC BY-SA 4.0
2023-07-19T14:29:18.290Z
This is less of an issue with the ordering and more of an issue with the verbose type names. The same type in Swift might be called `([Int32: [UnsafeMutablePointer<Double>]], Unique<UInt64>)` which, besides the spelling of `double*`, is a lot shorter. (I'll add that there is no standard equivalent to `std::unique_ptr`, so I'm assuming a user-defined `Unique<T>` type.)
Bbrk24
<p>It has to do with syntactic ambiguity. In most languages, we have a different syntax for types and terms. For example, when parsing a type, <code>&lt;</code> is paired with <code>&gt;</code> and means generics, while in terms, <code>&lt;</code> and <code>&gt;</code> are comparisons.</p>
<p>Now, let's say we want to parse a statement. When we see a couple of tokens, <code>a</code>, <code>&lt;</code>, <code>b</code>, <code>&gt;</code>, <code>c</code>, we do not know if this is an expression <code>(a &lt; b) &gt; c</code> or if this is a variable definition <code>a&lt;b&gt; c</code>. Then, if there's a parse error, the compiler would expect things that either completes a definition or an expression, which can be hard to understand. With postfix-type syntax this is not even a problem.</p>

CC BY-SA 4.0
2023-05-17T00:20:55.720Z
2023-05-17T00:20:55.720Z
ice1000
<h2>Advantage: Keeping the value and name close together which can increase readability</h2>
<p>Prefix keeps the more important parts of a variable declaration (its name and initial value) together rather than separating them, making it easier to scan, i.e:</p>
<pre><code>// Prefix:
███████ spug = calculate_spug(foo) + correct_error(bar);

// Postfix
spug ███████ = calculate_spug(foo) + correct_error(bar);
</code></pre>
<p>Note that there is also a second way of writing postfix types, used in some languages:</p>
<pre><code>// Postfix after the value
var x = 7 as int;
</code></pre>
<p>which leaves the more important parts of line together and shares this advantage of code readability. However, this doesn't apply to the method given in the question.</p>

CC BY-SA 4.0
2023-07-19T12:39:39.680Z
2023-07-19T14:54:05.257Z
2023-07-19T14:54:05.257Z
Jack Aidley
CC BY-SA 4.0
2023-07-19T13:17:15.227Z
This is entirely subjective, and without any hard evidence to suggest that one is more legible than the other I want to call it a matter of opinion. Besides that, most languages with postfix types still have a `var` keyword to declare a variable (PL/pgSQL being an exception off the top of my head).
Bbrk24
CC BY-SA 4.0
2023-07-19T14:16:53.647Z
@Bbrk24: A `var` keyword just makes the advantage for prefix larger. I actually included that in the first draft but since there exist postfix languages without it, I think it is a tangential issue. As for subjectivity, I don't agree - the benefits of grouping for readability are well accepted - and it's certainly no less subjective a claim than xigoi's claim to the opposite.
Jack Aidley
CC BY-SA 4.0
2023-07-19T14:25:58.227Z
I am unsure why this answer received more negative attention than xigoi's. Both need more backing for their claims
mousetail 'he-him'
CC BY-SA 4.0
2023-07-19T14:37:56.457Z
@mousetail I would argue that neither need backing for their claims; they're not necessarily saying "this is objectively more/less readable than that", they're saying "this is an objective statement about this type of syntax which could be a reason someone [typically the author] finds it less readable"
rydwolf
CC BY-SA 4.0
2024-07-22T00:58:42.573Z
Isn't `as int` just a type-translation operator within an expression (like a cast in C, except it has low rather than high precedence)? So it's just inferring the type of `x` in the usual manner, from the type of the initialiser expression.
Martin Kealey
CC BY-SA 4.0
2024-07-22T01:01:48.527Z
Go has two forms of declarations: `var x : type` and `x := initialvalueexpression`. Horses for courses.
Martin Kealey
<p>In addition to what has been said about the relative position of declared value and its type, the prefix/postfix notation also comes up in how types themselves are denoted. In ML, types are in postfix but type parameters in prefix position:</p>
<pre><code>val assoc : 'a -&gt; ('a * 'b) list -&gt; 'b
</code></pre>
<p>The value (a function) declared is <code>assoc</code> and its second parameter is a list of tuples <code>('a * 'b)</code>. Notice that the type parameters for <code>list</code> are in prefix position. Other examples would be <code>int array</code> or <code>char list</code>. <code>array</code> and <code>list</code> are formally <em>type constructors</em>: types that take parameters and produce a type.</p>
<p>Most other languages place type parameters in postfix position. This creates a symmetry between values and types:</p>
<ul>
<li>A function takes value parameters and produces a value.</li>
<li>A type constructor takes type parameters and produces a type.</li>
</ul>
<p>Treating types and values symmetrically makes it syntactically easier to support <a href="https://serokell.io/blog/kinds-and-hkts-in-haskell" rel="nofollow noreferrer">higher-kinded types</a>.</p>

CC BY-SA 4.0
2023-08-20T07:49:17.330Z
2023-08-20T11:48:35.597Z
2023-08-20T11:48:35.597Z
Christian Lindig
CC BY-SA 4.0
2023-08-20T09:21:46.930Z
I find this an odd use of language. When we write something like `-5` we don't say "the operand 5 is in postfix position", we say "the unary operator `-` is in prefix position" or "unary `-` is a prefix operator". Likewise in `'a list`, the type operator `list` is in postfix position, and `list` is a postfix type operator. The reason being that `'a` is a type which can occur in various positions, but `list` is an operator which can only occur in one position relative to its operand.
kaya3
CC BY-SA 4.0
2023-08-20T09:44:55.987Z
Didn't the question introduce the problem by saying "postfix type syntax" when referring to the type being to the right of the value?
Christian Lindig
CC BY-SA 4.0
2023-08-20T10:17:36.283Z
OK, I see the confusion. The question is talking about declarations, like `int x;` or `void y() {}` in C or Java, or `let x: number;` or `function y(): void {}` in Typescript. In those declarations, `int`, `number` and `void` are types, and they occur either before or after the identifier they declare the type of. But `list` is not really a type in ML ─ `'a list` is a type, but `list` itself is not ─ and the term `'a list` is not a declaration saying that `'a` is the type of `list`, nor that `list` is the type of `'a`
kaya3
CC BY-SA 4.0
2023-08-20T10:23:50.887Z
Since `list` is an operator which takes an operand, it does make sense to talk about its fixity (i.e. the position of the operator relative to its operand, which is a type). But saying that "In ML ... type parameters are in prefix position" is strange and not really correct in general; in `'a -> 'b` the type parameter `'b` is not in "prefix position" in any sense, and likewise in `'a * 'b`. Hence it only really makes sense to talk about the fixity of type operators like `list` (postfix), `->` (infix) and `*` (infix), not about the fixity of types themselves.
kaya3
CC BY-SA 4.0
2023-08-20T11:13:29.190Z
I see your point. I tried to say: ML has types declared after the value and uses postfix type constructors (which I think is a mistake).
Christian Lindig
<p>The main advantage is that the syntax is shorter ─ one less keyword <code>function</code>, and one less character of punctuation <code>:</code>. A secondary reason is that this is consistent with how variables are declared, type first, in those languages ─ but this really just expands the question to be about variables as well as functions.</p>
<p>The main disadvantage with the type-first syntax is that it makes it harder for type annotations to be optional. Modern languages may have more expressive type systems where types such as <code>{x: T['bar'], y: readonly number[]}</code> might be noisy to write (and might not have a name), but they also run on modern hardware which can afford to spend computational resources on type inference, so that the compiler can know what the type is without the programmer having to write it out. Additionally, languages like Python and Typescript are &quot;gradually typed&quot;, meaning that even where a type can't be inferred, the type annotation can be omitted and the program still makes sense (with a fallback to dynamic typing). So a syntax like <code>var x: Type = value;</code> allows the <code>: Type</code> part to be omitted without needing something else in its place.</p>
<p>Other than that, the use of punctuation like <code>:</code> to indicate type annotations has benefits for languages like Typescript where the syntax for types is widely varied; a type in Typescript can begin with a letter, underscore, digit, single or double quote, backtick, parenthesis, square bracket, or brace character. By requiring a colon at the start of each type annotation, the parser (or the human reader) doesn't have to guess whether the line <code>{x: number} foo = {x: 4};</code> starts with a type annotation or something else. Not to mention that in some cases this would genuinely make the grammar ambiguous.</p>
<p>It's worth adding that the notation <span class="math-container">$x : T$</span>, with a colon rather than some other symbol, is the standard notation used by <a href="https://en.wikipedia.org/wiki/Type_theory" rel="noreferrer">type theorists</a> for the proposition that a term <span class="math-container">$x$</span> has type <span class="math-container">$T$</span>.</p>

CC BY-SA 4.0
2023-05-17T00:02:02.680Z
2023-08-19T23:46:53.157Z
2023-08-19T23:46:53.157Z
kaya3
CC BY-SA 4.0
2023-07-21T00:46:58.373Z
Type-following-declaration languages don't necessarily *need* a keyword to introduce a function definition.  You *can* use a grammar rule like `function-definition : identifier '(' argument-list ')' ':' type-description function-body`.  It needs one more symbol of lookahead to parse if you're working left-to-right, but very few languages are LL(0) so you likely need this for other parts of your language anyway, so it isn't a big deal.
occipita
CC BY-SA 4.0
2023-07-24T09:48:58.857Z
@occipita It needs more than one token of lookahead, because `identifier ( argument-list )` is also valid syntax for a function call, so you won't know it's a function definition until you see a `:` token either in or after the argument list. My language Papyri used to be like that, but it made parsing complicated, it made it complicated to read code as a human because function definitions looked too much like function calls, it made error messages confusing, and also if every function definition needs at least one `:` to be recognised as such then type annotations can't be optional.
kaya3
CC BY-SA 4.0
2023-07-24T15:34:48.460Z
kaya3: in my design functions cannot be defined in locations where expressions would also be accepted.  Therefore a function definition only needs to be distinguished from a variable declaration, an import statement, and one of several forms of type declaration (all of which *are* prefixed by a keyword).  I don't support nested named functions -- only lambdas can be nested.  If you *really* want to define a named function locally you need to store a lambda in a variable (which is easy: `id := \ x -> x` declares the identity function).
occipita
<p>Consider this line of C:</p>
<pre><code>foo(*bar);
</code></pre>
<p>This could be:</p>
<ol>
<li>A declaration of a variable named <code>bar</code>, which is of type <code>foo*</code>.</li>
<li>A call to a function named <code>foo</code>, passing an argument which is the the pointer <code>bar</code> dereferenced.</li>
</ol>
<p>The way that <a href="https://www.lysator.liu.se/c/ANSI-C-grammar-y.html" rel="noreferrer">the C grammar</a> handles this is by distinguishing between type names and other identifiers. Essentially, on every <code>typedef</code>, the symbol table is updated to say that this identifier is now a type, and the lexical analyser returns a different token.</p>
<p>One disadvantage of this is obvious: a language with this specific syntax quirk cannot use a type before it is declared, hence the need for forward declarations. It is now the 21st century, and a lot of programmers don't like this.</p>
<p>As an aside, Haskell has a similar problem with its type language, which is solved by requiring that type identifiers and type constructors start with an upper-case letter and variables start with a lower-case letter. Prolog distinguishes between variables and atoms/functors using the same approach. I digress.</p>
<p>Wirth-style syntax doesn't have this problem because type names and other identifiers don't appear in the same &quot;location&quot;, such as at the start of a statement-or-declaration.</p>
<p>Moreover, Wirth-style languages typically have <em>operator grammars</em>, which mean that no two user-defined identifiers can appear next to each other without an operator or keyword separating them. As well as making the syntax less ambiguous, it can make syntax error recovery easier.</p>
<p>The cost is a very slight increase in verbosity. Wirth syntax requires a colon where C-style syntax requires only whitespace.</p>
<p>But on the other hand, Wirth-style languages don't pay for verbosity in places where C-style languages do, such as the parentheses around conditionals or the parentheses after function calls with no arguments.</p>
<pre><code>/* Look at those parentheses. Can you see why they are
   necessary? */
if (boolean_variable) procedure_call();

{- The Pascal equivalent may superficially feel more
   verbose, but it's only one character longer. -}
if boolean_variable then procedure_call;
</code></pre>

CC BY-SA 4.0
2023-05-17T00:23:59.203Z
2023-05-17T01:08:22.863Z
2023-05-17T01:08:22.863Z
Pseudonym
CC BY-SA 4.0
2023-05-30T16:56:02.123Z
See also https://en.wikipedia.org/wiki/Most_vexing_parse.
I recall reading a paper about making changes to C++ to make the grammar context free for example by using the syntax "x:int". Alas I cannot find the link.
C++ is actually moving in this direction slowly. We now have trailing return syntax for example:    auto X() -> Y   (X is a function returning Y).
Bruce Adams
# What are the advantages/disadvantages of prefix type syntax?
Posted by: username_0 on 2023-05-16
Famously, C’s functions and variables have their types specified before the function/variable name:
bar foo() {...}
bar foo = ...;

Most older C derivatives also use the prefix syntax (e.x. Java, C#, C++). However, many newer languages (e.x. Rust, Kotlin, Typescript) use a postfix type syntax:
function foo(): bar {...}
var foo: bar = ...;

What are the advantages of the former syntax over the latter?
**Tags:** syntax types functions
> **Comments:**
> **username_4**: [Exact duplicate of a question on CS.SE](https://cs.stackexchange.com/questions/109817/in-function-declarations-what-advantages-are-there-to-having-the-type-of-the-pa). Posting questions that already have an answer on Stack Exchange is not a good way to populate a private beta: it suggests that the new site doesn't have its own niche.  
> **username_5**: also related (in relation to "cross-posting"): https://meta.stackexchange.com/q/64068/997587 and https://meta.stackexchange.com/q/354865/997587  
> **username_0**: @Gilles'SO-stopbeingevil' 1.  I did not realize this, than you for pointing out. 2. we have a bit of overlap with CS 3. This is still on topic, no?  
> **username_4**: @Seggan Yes, this is on-topic, so I didn't vote to close.  
> **username_1**: The trailing `: type` syntax is usually called "pascal" or "modula" syntax, since that is where it originated.  This was ~1970, so actually predates C by a little bit.  
> **username_2**: C++ actually has both prefix and postfix return types.  
> **username_3**: This is not a complete answer but I don't think anyone has mentioned this yet: With the type before the name, variables which are the same type line up and their names all begin at the same indentation level, automatically.  
---
## 8 answers
### Answer by username_17 on 2023-05-17. Score: 15
Consider this line of C:
foo(*bar);

This could be:

A declaration of a variable named bar, which is of type foo*.
A call to a function named foo, passing an argument which is the the pointer bar dereferenced.

The way that the C grammar handles this is by distinguishing between type names and other identifiers. Essentially, on every typedef, the symbol table is updated to say that this identifier is now a type, and the lexical analyser returns a different token.
One disadvantage of this is obvious: a language with this specific syntax quirk cannot use a type before it is declared, hence the need for forward declarations. It is now the 21st century, and a lot of programmers don't like this.
As an aside, Haskell has a similar problem with its type language, which is solved by requiring that type identifiers and type constructors start with an upper-case letter and variables start with a lower-case letter. Prolog distinguishes between variables and atoms/functors using the same approach. I digress.
Wirth-style syntax doesn't have this problem because type names and other identifiers don't appear in the same "location", such as at the start of a statement-or-declaration.
Moreover, Wirth-style languages typically have operator grammars, which mean that no two user-defined identifiers can appear next to each other without an operator or keyword separating them. As well as making the syntax less ambiguous, it can make syntax error recovery easier.
The cost is a very slight increase in verbosity. Wirth syntax requires a colon where C-style syntax requires only whitespace.
But on the other hand, Wirth-style languages don't pay for verbosity in places where C-style languages do, such as the parentheses around conditionals or the parentheses after function calls with no arguments.
/* Look at those parentheses. Can you see why they are
   necessary? */
if (boolean_variable) procedure_call();

{- The Pascal equivalent may superficially feel more
   verbose, but it's only one character longer. -}
if boolean_variable then procedure_call;
> **Comments:**
> **username_18** (2023-05-30): See also https://en.wikipedia.org/wiki/Most_vexing_parse.
I recall reading a paper about making changes to C++ to make the grammar context free for example by using the syntax "x:int". Alas I cannot find the link.
C++ is actually moving in this direction slowly. We now have trailing return syntax for example:    auto X() -> Y   (X is a function returning Y).  
---
### Answer by username_15 on 2023-05-17. Score: 13
The main advantage is that the syntax is shorter ─ one less keyword `function`, and one less character of punctuation `:`. A secondary reason is that this is consistent with how variables are declared, type first, in those languages ─ but this really just expands the question to be about variables as well as functions.

The main disadvantage with the type-first syntax is that it makes it harder for type annotations to be optional. Modern languages may have more expressive type systems where types such as `{x: T['bar'], y: readonly number[]}` might be noisy to write (and might not have a name), but they also run on modern hardware which can afford to spend computational resources on type inference, so that the compiler can know what the type is without the programmer having to write it out. Additionally, languages like Python and Typescript are "gradually typed", meaning that even where a type can't be inferred, the type annotation can be omitted and the program still makes sense (with a fallback to dynamic typing). So a syntax like `var x: Type = value;` allows the `: Type` part to be omitted without needing something else in its place.

Other than that, the use of punctuation like `:` to indicate type annotations has benefits for languages like Typescript where the syntax for types is widely varied; a type in Typescript can begin with a letter, underscore, digit, single or double quote, backtick, parenthesis, square bracket, or brace character. By requiring a colon at the start of each type annotation, the parser (or the human reader) doesn't have to guess whether the line `{x: number} foo = {x: 4};` starts with a type annotation or something else. Not to mention that in some cases this would genuinely make the grammar ambiguous.

It's worth adding that the notation $x : T$, with a colon rather than some other symbol, is the standard notation used by [type theorists](https://en.wikipedia.org/wiki/Type_theory) for the proposition that a term $x$ has type $T$.
> **Comments:**
> **username_16** (2023-07-21): Type-following-declaration languages don't necessarily *need* a keyword to introduce a function definition.  You *can* use a grammar rule like `function-definition : identifier '(' argument-list ')' ':' type-description function-body`.  It needs one more symbol of lookahead to parse if you're working left-to-right, but very few languages are LL(0) so you likely need this for other parts of your language anyway, so it isn't a big deal.  
> **username_15** (2023-07-24): @occipita It needs more than one token of lookahead, because `identifier ( argument-list )` is also valid syntax for a function call, so you won't know it's a function definition until you see a `:` token either in or after the argument list. My language Papyri used to be like that, but it made parsing complicated, it made it complicated to read code as a human because function definitions looked too much like function calls, it made error messages confusing, and also if every function definition needs at least one `:` to be recognised as such then type annotations can't be optional.  
> **username_16** (2023-07-24): kaya3: in my design functions cannot be defined in locations where expressions would also be accepted.  Therefore a function definition only needs to be distinguished from a variable declaration, an import statement, and one of several forms of type declaration (all of which *are* prefixed by a keyword).  I don't support nested named functions -- only lambdas can be nested.  If you *really* want to define a named function locally you need to store a lambda in a variable (which is easy: `id := \ x -> x` declares the identity function).  
---
### Answer by username_9 on 2023-05-17. Score: 8
It has to do with syntactic ambiguity. In most languages, we have a different syntax for types and terms. For example, when parsing a type, `<` is paired with `>` and means generics, while in terms, `<` and `>` are comparisons.

Now, let's say we want to parse a statement. When we see a couple of tokens, `a`, `<`, `b`, `>`, `c`, we do not know if this is an expression `(a < b) > c` or if this is a variable definition `a c`. Then, if there's a parse error, the compiler would expect things that either completes a definition or an expression, which can be hard to understand. With postfix-type syntax this is not even a problem.
---
### Answer by username_2 on 2023-08-20. Score: 5
One reason that C++ introduced *trailing return type* syntax is that this allows the return type to use *dependent names*. That is, names that represent types only with the greater knowledge obtained when reaching this position, usually because they only name types in the context of an argument, often the implicit `this` argument of a member function.

Not being able to do that can be seen as a disadvantage of prefix position for return types.
---
### Answer by username_4 on 2023-05-20. Score: 5
This is largely an arbitrary choice. One language did it some way, a long time ago, and then many but not all other languages copied a familiar syntax. That being said, the choice is not *completely* arbitrary. Putting the type before or after the variable name is largely cosmetic, but there are more differences than this between the C-style syntax and the Pascal-style syntax used in languages like Rust and Scala.

In early languages where variable declarations had a type, the syntax of a declaration was of the form `Type Name` where `Type` is a reserved word and `Name` is a name chosen by the programmer. Here the order is not arbitrary: first you say what kind of thing you're declaring, then you give it a name. Compilers at the time were very primitive and needed to know early on what they were parsing; writing `INTEGER X` let the compiler know immediately that it had to work on an integer declaration, whereas `X INTEGER` would have required the compiler to first remember that it had seen `X` and only after that it would have known that it was supposed to declare an integer variable. Languages of the 1950s and 1960s such as [ALGOL](https://en.wikipedia.org/wiki/ALGOL) and [FORTRAN](https://en.wikipedia.org/wiki/Fortran) tended to use this syntax. Interestingly, at the time, in programming language descriptions, [“type” had a more general meaning that it has today](https://hal.inria.fr/hal-01399694/document): today it has a specific technical meaning that's more or less synonym with “datatype”, but at the time it had its ordinary English meaning, which could cover things like integer and real, but also things like label and statement.

[C](https://en.wikipedia.org/wiki/C_(programming_language)) extended this syntax in a way that allowed defining **compound types**. In C, the syntax of a variable declaration mimics the syntax of its use. For example, `int x` declares an integer called `x`, and `int *p` declares a pointer-to-integer called `p`, and the expression `*p` has the type `int`. This syntax is not purely prefix because accessors can be suffixes: for example `a[1]` is an `int` if `a` is an array of `int` values, so the syntax to declare an array of integers is `int a[]`.

C became a very popular language, so many languages after it retained a similar syntax for several things including variable declarations and types.

The colon syntax goes back to at least [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language)) in 1971. This is the syntax used by computer scientists at least since the early 1970s. I suspect that it started in theory papers and was adopted by Pascal and later by other languages, but for all I know it may have originated with Pascal. [Why colon to denote that a value belongs to a type?](https://cstheory.stackexchange.com/questions/43971/why-colon-to-denote-that-a-value-belongs-to-a-type) discusses the origin of $x : T$ in computer science. Modern languages that draw from modern (or not-so-modern-anymore) theory tend to use the syntax that's familiar to computer scientists, including [ML](https://en.wikipedia.org/wiki/ML_(programming_language)), [Scala](https://en.wikipedia.org/wiki/Scala_(programming_language)), [Swift](https://en.wikipedia.org/wiki/Swift_(programming_language)), [Rust](https://en.wikipedia.org/wiki/Rust_(programming_language)), and many others. [Haskell](https://en.wikipedia.org/wiki/Haskell_(programming_language)) is somewhat unusual in using a double colon `::` where others use a colon `:`.

The order $x : T$ vs $T : x$ is arbitrary: these days, compilers don't mind, and for humans, it's just a matter of habit. However, having a punctuation sign between the variable name and the type is not arbitrary. Most languages that use this syntax also allow the left-hand side to be an expression, to form a type annotation. More importantly, the right-hand side is a **type expression**, not just a type name. Recall that C supports declarations of variables with compound types, but the syntax is somewhat awkward, with the variable name ending up somewhere in the middle. C's syntax does not work with compound types that are made of more than one type part. For example, in ML, `x : bool * int * string` means that `x` is a triple consisting of a boolean, an integer and a string. Haskell writes this `x :: (Bool, Integer, String)`. Both the ML and the Haskell way allow building complex types. The C approach fails: where do you put the variable name?

Languages such as Java and C# deviate from the C syntax by putting the whole type information before the variable name: `int[] a`, `(bool, int, string) x`, `List v`. With no separator, it's impractical to allow both sides to have an arbitrary length, but these languages do support type expressions, which can be used to declare a variable.

*(reposted from <https://cs.stackexchange.com/questions/109817/in-function-declarations-what-advantages-are-there-to-having-the-type-of-the-pa/109978#109978>)*
> **Comments:**
> **username_6** (2023-05-20): Can't C represent anonymous product types like `struct { bool first; int second; char* third; } x;`?  
> **username_4** (2023-05-20): @Bbrk24 Yes, and those deviate from the idea that the declaration syntax matches the use syntax, because that becomes very clumsy when a type has multiple fundamental destructors: you can't write “the type such that `t.first` is a `bool` and `t.second` is an `int`” without repeating the type name `t`, which would be a lot of work for everybody and thankfully C didn't go that far.  
> **username_7** (2024-06-19): Algol 68 had “compound types” before C, with things like **struct** ( **int** *p*, *q* ) *s*; [1] **int** *a*  
---
### Answer by username_8 on 2023-07-19. Score: 4
Disadvantage: Making the variable name harder to find between the type syntax and value
Having the type before the name can make it hard to find the name, which is the most important part of a declaration. Consider a line like this:
std::pair>, std::unique_ptr> const frobnicator = std::make_pair(create_frobni(), create_cator());

How long does it take you to find the name? Or even to recognize that this is a variable declaration?
> **Comments:**
> **username_6** (2023-07-19): This is less of an issue with the ordering and more of an issue with the verbose type names. The same type in Swift might be called `([Int32: [UnsafeMutablePointer<Double>]], Unique<UInt64>)` which, besides the spelling of `double*`, is a lot shorter. (I'll add that there is no standard equivalent to `std::unique_ptr`, so I'm assuming a user-defined `Unique<T>` type.)  
---
### Answer by username_14 on 2023-08-20. Score: 3
In addition to what has been said about the relative position of declared value and its type, the prefix/postfix notation also comes up in how types themselves are denoted. In ML, types are in postfix but type parameters in prefix position:
val assoc : 'a -> ('a * 'b) list -> 'b

The value (a function) declared is assoc and its second parameter is a list of tuples ('a * 'b). Notice that the type parameters for list are in prefix position. Other examples would be int array or char list. array and list are formally type constructors: types that take parameters and produce a type.
Most other languages place type parameters in postfix position. This creates a symmetry between values and types:

A function takes value parameters and produces a value.
A type constructor takes type parameters and produces a type.

Treating types and values symmetrically makes it syntactically easier to support higher-kinded types.
> **Comments:**
> **username_15** (2023-08-20): I find this an odd use of language. When we write something like `-5` we don't say "the operand 5 is in postfix position", we say "the unary operator `-` is in prefix position" or "unary `-` is a prefix operator". Likewise in `'a list`, the type operator `list` is in postfix position, and `list` is a postfix type operator. The reason being that `'a` is a type which can occur in various positions, but `list` is an operator which can only occur in one position relative to its operand.  
> **username_14** (2023-08-20): Didn't the question introduce the problem by saying "postfix type syntax" when referring to the type being to the right of the value?  
> **username_15** (2023-08-20): OK, I see the confusion. The question is talking about declarations, like `int x;` or `void y() {}` in C or Java, or `let x: number;` or `function y(): void {}` in Typescript. In those declarations, `int`, `number` and `void` are types, and they occur either before or after the identifier they declare the type of. But `list` is not really a type in ML ─ `'a list` is a type, but `list` itself is not ─ and the term `'a list` is not a declaration saying that `'a` is the type of `list`, nor that `list` is the type of `'a`  
> **username_15** (2023-08-20): Since `list` is an operator which takes an operand, it does make sense to talk about its fixity (i.e. the position of the operator relative to its operand, which is a type). But saying that "In ML ... type parameters are in prefix position" is strange and not really correct in general; in `'a -> 'b` the type parameter `'b` is not in "prefix position" in any sense, and likewise in `'a * 'b`. Hence it only really makes sense to talk about the fixity of type operators like `list` (postfix), `->` (infix) and `*` (infix), not about the fixity of types themselves.  
> **username_14** (2023-08-20): I see your point. I tried to say: ML has types declared after the value and uses postfix type constructors (which I think is a mistake).  
---
### Answer by username_10 on 2023-07-19. Score: 0
Advantage: Keeping the value and name close together which can increase readability
Prefix keeps the more important parts of a variable declaration (its name and initial value) together rather than separating them, making it easier to scan, i.e:
// Prefix:
███████ spug = calculate_spug(foo) + correct_error(bar);

// Postfix
spug ███████ = calculate_spug(foo) + correct_error(bar);

Note that there is also a second way of writing postfix types, used in some languages:
// Postfix after the value
var x = 7 as int;

which leaves the more important parts of line together and shares this advantage of code readability. However, this doesn't apply to the method given in the question.
> **Comments:**
> **username_6** (2023-07-19): This is entirely subjective, and without any hard evidence to suggest that one is more legible than the other I want to call it a matter of opinion. Besides that, most languages with postfix types still have a `var` keyword to declare a variable (PL/pgSQL being an exception off the top of my head).  
> **username_10** (2023-07-19): @Bbrk24: A `var` keyword just makes the advantage for prefix larger. I actually included that in the first draft but since there exist postfix languages without it, I think it is a tangential issue. As for subjectivity, I don't agree - the benefits of grouping for readability are well accepted - and it's certainly no less subjective a claim than xigoi's claim to the opposite.  
> **username_11** (2023-07-19): I am unsure why this answer received more negative attention than xigoi's. Both need more backing for their claims  
> **username_12** (2023-07-19): @mousetail I would argue that neither need backing for their claims; they're not necessarily saying "this is objectively more/less readable than that", they're saying "this is an objective statement about this type of syntax which could be a reason someone [typically the author] finds it less readable"  
> **username_13** (2024-07-22): Isn't `as int` just a type-translation operator within an expression (like a cast in C, except it has low rather than high precedence)? So it's just inferring the type of `x` in the usual manner, from the type of the initialiser expression.  
> **username_13** (2024-07-22): Go has two forms of declarations: `var x : type` and `x := initialvalueexpression`. Horses for courses.  
---
