Почему почти во всех современных языках программирования (Go, Rust, Kotlin, Swift, Scala, Nim и даже последняя версия Python) типы всегда идут после объявления переменной, а не раньше?
Ваша предпосылка ошибочна по двум направлениям:
- Есть новые языки программирования, которые имеют тип перед идентификатором. C♯, D или Цейлон, например.
- Наличие типа после идентификатора не является новым явлением, оно восходит, по крайней мере, к Паскалю (разработанному в 1968–1969 гг., Выпущенному в 1970 г.), но фактически использовалось в математической теории типов, которая начинается ~ 1902 г. Он также использовался в ML (1973), CLU (1974), Hope (1970-е), Modula-2 (1977–1985), Ada (1980), Miranda (1985), Caml (1985), Eiffel (1985), Oberon. (1986), Modula-3 (1986–1988) и Haskell (1989).
Pascal, ML, CLU, Modula-2 и Miranda были очень влиятельными языками, поэтому неудивительно, что этот стиль объявлений типов оставался популярным.
Почему x: int = 42
и нет int x = 42
? Разве последнее не более читабельно, чем первое?
Читаемость - это вопрос знакомства. Лично я считаю, что китайский нечитаем, но, видимо, китайцы этого не делают. Изучив Паскаль в школе, поболтав с Эйфелевой, F♯, Haskell и Scala, и посмотрев на TypeScript, Fortress, Go, Rust, Kotlin, Идрис, Фреге, Agda, ML, Ocaml,…, для меня это выглядит совершенно естественно ,
Это просто тенденция или есть какие-то действительно значимые причины такого решения?
Если это тенденция, она довольно устойчивая: как я уже говорил, в математике она насчитывает сто лет.
Одним из основных преимуществ наличия типа после идентификатора является то, что он легко опускается, если вы хотите, чтобы он был выведен. Если ваши объявления выглядят так:
val i: Int = 10
Тогда тривиально опустить тип и вывести его следующим образом:
val i = 10
Принимая во внимание, что если тип предшествует идентификатору, как это:
Int i = 10
Затем парсеру становится трудно отличить выражение от объявления:
i = 10
Решение, которое обычно предлагают разработчики языка, состоит в том, чтобы ввести ключевое слово «Я не хочу писать тип», которое должно быть написано вместо типа:
var i = 10; // C♯
auto i = 10; // C++
Но на самом деле это не имеет особого смысла: вы должны явно написать тип, который говорит, что вы не пишете тип. А? Было бы намного проще и разумнее просто оставить это, но это делает грамматику намного более сложной.
(И давайте даже не будем говорить о типах указателей на функции в C.)
Разработчики нескольких из вышеупомянутых языков взвесили эту тему:
Примечание: разработчики Ceylon также задокументировали, почему они используют синтаксис префиксного типа :
Префикс вместо постфиксных аннотаций
Почему вы следуете за C и Java, помещая сначала аннотации типов, а не Pascal и ML, помещая их после имени объявления?
Потому что мы думаем это:
shared Float e = ....
shared Float log(Float b, Float x) { ... }
Просто намного легче читать, чем это:
shared value e: Float = ....
shared function log(b: Float, x: Float): Float { ... }
И мы просто не понимаем, как кто-то мог думать иначе!
Лично я нахожу их «аргумент» гораздо менее убедительным, чем другие.