Por que em quase todas as linguagens de programação modernas (Go, Rust, Kotlin, Swift, Scala, Nim e até a última versão do Python) os tipos sempre vêm após a declaração da variável, e não antes?
Sua premissa é falha em duas frentes:
- Existem novas linguagens de programação que têm o tipo antes do identificador. C♯, D ou Ceilão, por exemplo.
- Tendo o tipo após o identificador não é um fenômeno novo, ele remonta a pelo menos Pascal (projetado 1968-1969, lançado em 1970), mas na verdade foi usado na teoria matemática dos tipos, que começa em 1902. Também foi usado em 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 eram linguagens muito influentes; portanto, não é de surpreender que esse estilo de declaração de tipo permanecesse popular.
Por que x: int = 42
e não int x = 42
? O último não é mais legível que o primeiro?
A legibilidade é uma questão de familiaridade. Pessoalmente, acho o chinês ilegível, mas aparentemente o povo chinês não. Tendo aprendido Pascal na escola, brincado com Eiffel, F♯, Haskell e Scala, e tendo olhado para TypeScript, Fortress, Go, Rust, Kotlin, Idris, Frege, Agda, ML, Ocaml,…, parece completamente natural para mim .
É apenas uma tendência ou existem razões realmente significativas por trás dessa solução?
Se é uma tendência, é bastante persistente: como mencionei, remonta a cem anos em matemática.
Uma das principais vantagens de ter o tipo após o identificador é que é fácil deixar o tipo de fora, se você desejar que ele seja deduzido. Se suas declarações forem assim:
val i: Int = 10
Então é trivial deixar de fora o tipo e inferi-lo assim:
val i = 10
Considerando que, se o tipo vier antes do identificador, desta forma:
Int i = 10
Então, fica difícil para o analisador distinguir uma expressão de uma declaração:
i = 10
A solução que os designers de linguagem geralmente apresentam é a introdução de uma palavra-chave "Não quero escrever um tipo" que deve ser escrita em vez do tipo:
var i = 10; // C♯
auto i = 10; // C++
Mas isso realmente não faz muito sentido: você basicamente precisa escrever explicitamente um tipo que diz que você não escreve um tipo. Hã? Seria muito mais fácil e sensato deixar de fora, mas isso torna a gramática muito mais complexa.
(E não vamos nem falar sobre os tipos de ponteiros de função em C.)
Os projetistas de várias das línguas mencionadas anteriormente abordaram esse assunto:
Nota: os designers do Ceilão também documentaram por que usam a sintaxe do tipo de prefixo :
Prefixo em vez de anotações do tipo postfix
Por que você segue C e Java colocando as anotações de tipo primeiro, em vez de Pascal e ML colocando-as após o nome da declaração?
Porque pensamos isso:
shared Float e = ....
shared Float log(Float b, Float x) { ... }
É simplesmente muito mais fácil de ler do que isso:
shared value e: Float = ....
shared function log(b: Float, x: Float): Float { ... }
E simplesmente não entendemos como alguém poderia pensar o contrário!
Pessoalmente, acho o "argumento" deles muito menos convincente do que os outros.