> C/Java style of annotating the return type of a function first, and then annotating the argument types before the name feels really old school at this point. Python, TypeScript, Go, Rust, etc. all opted for annotating after the name.
>
> Since this is so prevalent in newer languages, despite a pretty strong tradition in the other direction, I wonder if there is a pretty good reason for this which language design experts are keenly aware of when they design new languages.
My $0.02:
Maybe consistency between named functions and anonymous functions?
If you put the return type of a function before the name then it reads ambiguously when the name is left out (as in anonymous functions):
// Named function
int funcName (params) { ... }
// No-name function
int (params) { ... }
Which leads to the language needing alternative syntax or extra keywords when declaring anonymous functions:
// Something like this maybe?
int lambda (params) { ... }
If you put the return type after the function information but before the body then it's always consistent:
// Named function
funcName (params) : int { ... }
// No-name function
(params) : int { ... }
And, of course, to retain consistency you then make sure that all variables are declared the same way (type following variable name):
// Var declaration
myvar : int;
The disambiguation comes into its own when creating functions inline:
// Prefixed return-type looks odd
callFooWithFunc (int (argslist) { ... });
// Prefixed return-type requires extra keywords to not look odd
callFooWithFunc (int lambda (argslist) { ... });
// Suffixed return-type looks normal
callFooWithFunc ((argslist) : int { ... });