Perché in quasi tutti i linguaggi di programmazione moderni (Go, Rust, Kotlin, Swift, Scala, Nim, persino Python ultima versione) i tipi vengono sempre dopo la dichiarazione delle variabili, e non prima?
La tua premessa è imperfetta su due fronti:
- Esistono linguaggi di programmazione nuovi che hanno il tipo prima dell'identificatore. C♯, D o Ceylon, per esempio.
- Avere il tipo dopo l'identificatore non è un nuovo fenomeno, risale almeno a Pascal (progettato nel 1968-1969, rilasciato nel 1970), ma in realtà è stato usato nella teoria del tipo matematica, che inizia ~ 1902. Fu anche usato in ML (1973), CLU (1974), Hope (1970), Modula-2 (1977-1985), Ada (1980), Miranda (1985), Caml (1985), Eiffel (1985), Oberon (1986), Modula-3 (1986-1988) e Haskell (1989).
Pascal, ML, CLU, Modula-2 e Miranda erano tutti linguaggi molto influenti, quindi non sorprende che questo stile di dichiarazioni di tipo rimase popolare.
Perché x: int = 42
e no int x = 42
? Il secondo non è più leggibile del primo?
La leggibilità è una questione di familiarità. Personalmente, trovo il cinese illeggibile, ma a quanto pare, i cinesi non lo fanno. Avendo imparato Pascal a scuola, dilettandosi con Eiffel, F♯, Haskell e Scala, e avendo guardato TypeScript, Fortress, Go, Rust, Kotlin, Idris, Frege, Agda, ML, Ocaml, ..., mi sembra del tutto naturale .
È solo una tendenza o ci sono ragioni davvero significative dietro una simile soluzione?
Se è una tendenza, è abbastanza persistente: come ho già detto, risale a cento anni fa in matematica.
Uno dei principali vantaggi di avere il tipo dopo l'identificatore è che è facile lasciarlo fuori se si desidera dedurlo. Se le tue dichiarazioni sono così:
val i: Int = 10
Quindi è banale tralasciare il tipo e farlo dedurre in questo modo:
val i = 10
Considerando che se il tipo precede l'identificatore in questo modo:
Int i = 10
Quindi inizia a diventare difficile per il parser distinguere un'espressione da una dichiarazione:
i = 10
La soluzione che i designer linguistici di solito escogitano è quella di introdurre una parola chiave "Non voglio scrivere un tipo" che deve essere scritta al posto del tipo:
var i = 10; // C♯
auto i = 10; // C++
Ma questo non ha molto senso: in pratica devi scrivere esplicitamente un tipo che dice che non scrivi un tipo. Eh? Sarebbe molto più semplice e sensato lasciarlo fuori, ma ciò rende la grammatica molto più complessa.
(E non parliamo nemmeno dei tipi di puntatore a funzione in C.)
I progettisti di alcune delle lingue summenzionate hanno approfondito questo argomento:
Nota: i progettisti di Ceylon hanno anche documentato perché usano la sintassi del tipo di prefisso :
Prefisso invece delle annotazioni del tipo postfisso
Perché segui C e Java inserendo prima le annotazioni dei tipi, invece di Pascal e ML inserendole dopo il nome della dichiarazione?
Perché pensiamo questo:
shared Float e = ....
shared Float log(Float b, Float x) { ... }
È semplicemente molto più facile da leggere di questo:
shared value e: Float = ....
shared function log(b: Float, x: Float): Float { ... }
E semplicemente non capiamo come si possa pensare diversamente!
Personalmente, trovo il loro "argomento" molto meno convincente degli altri.