| > 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 { ... }); |