È perché quando si hanno funzioni di ordine superiore (funzioni che possono assumere altre funzioni come parametri o restituire altre funzioni), il tipo dopo la variabile rende le dichiarazioni del tipo lette da sinistra a destra invece che in una spirale strana. / p>
Considera questo esempio da un eccellente blog sul perché golang ha seguito questa strada :
int (*fp)(int (*ff)(int x, int y), int b)
È piuttosto difficile dire quale sia un tipo di ritorno e cosa sia un argomento, e hai bisogno di parentesi per disambiguare molto di questo. È una delle ragioni principali per cui le persone evitano i puntatori di funzioni come la piaga in C. Con il tipo alla fine, quell'ambiguità viene rimossa senza parentesi.
Come sottolineato da Amon, i linguaggi recenti della famiglia C sono più simili a:
std::function<int(std::function<int(int x, int y)> ff, int b)> fp
Sì, anche qui viene rimossa l'ambiguità, ma era anche per l'esempio C. Abbiamo appena scelto un diverso set di delimitatori (la funzione std :: function < >) per disambiguare. Abbiamo ancora una sintassi speciale per la dichiarazione dei puntatori di funzioni che è al di fuori della normale sintassi della dichiarazione del tipo. Non leggiamo più a spirale, il che è un grande miglioramento, ma non abbiamo nemmeno aggiunto i generici nel mix e abbiamo già una firma di tipo piuttosto lunga e impegnata.
Confronta con la firma del tipo postfissa per una dichiarazione di funzione:
def f(ff: (Int, Int) => Int, b: Int): Int
Questo si legge molto chiaramente, da sinistra a destra. Posso scorrere il lato sinistro della pagina e trovare facilmente i nomi delle mie funzioni. È facile da analizzare, perché hai già una dichiarazione, basta aggiungere un : type signature
opzionale alla fine. Dichiarare una variabile che contiene un riferimento a questa funzione è quasi identica:
val fp: (ff: (Int, Int) => Int, Int) => Int = f
// although usually because of type inference you can just write:
val fp = f
Anche qui utilizziamo il colon come delimitatore per risolvere l'ambiguità, ma il delimitatore sull'altro lato era già lì, o la virgola o il paren di chiusura o qualsiasi altro token, quindi è molto meno invadente. Questo semplicemente non è possibile con type-first. devi circondare la dichiarazione della funzione, in un modo o nell'altro.
Quando usi sempre le funzioni di ordine superiore, è utile un po 'di leggibilità aggiunta. Ecco perché le lingue che intendono supportare in modo idiomatico le funzioni di ordine superiore a un certo punto usano l'ultima sintassi tipo-ultima dall'inizio.