Языки программирования
Содержание:
Резюме
Проблема
Нам нужно выбрать языки программирования для нашего программного обеспечения. У нас две основные потребности: язык программирования для фронтенда, подходящий для веб-приложений, и язык программирования для бэкенда, подходящий для серверных приложений.
Решение
Для фронтенда мы выбираем TypeScript.
Для бэкенда мы выбираем Rust.
Состояние
Решено. Мы открыты для новых альтернатив по мере их появления.
Подробности
Допущения
Фронтенд-приложения типичны:
Типичные пользователи и взаимодействия
Типичные браузеры и системы
Типичные разработки и развёртывания
Фронтенд-приложения, вероятно, будут быстро развиваться:
Мы хотим обеспечить быстрые и простые разработки, развёртывания, итерации и т. д.
Мы ценим доказуемость, например типобезопасность, и готовы выполнять чуть больше работы для её достижения.
Нам не нужна совместимость с устаревшими системами.
Требования к бэкенд-приложениям выше обычного:
Цели по качеству выше обычного, особенно по доказуемости, надёжности, безопасности и т. д.
Цели по работе, близкой к реальному времени, выше обычного, то есть мы не хотим пауз из-за сборки мусора виртуальной машины.
Цели по функциональному программированию выше обычного, особенно для распараллеливания, многоядерной обработки и безопасности памяти.
Мы согласны на меньшую скорость компиляции в пользу безопасности на этапе компиляции и скорости выполнения.
Ограничения
У нас есть сильное ограничение на языки, которые можно использовать с сервисами функций крупных облачных провайдеров, например Amazon Lambda.
Позиции
Мы рассматривали эти языки:
C
C++
Clojure
Elixir
Erlang
Elm
Flow
Go
Haskell
Java
JavaScript
Kotlin
Python
Ruby
Rust
TypeScript
Аргументация
Краткие итоги по каждому языку:
C: отклонён из-за низкой безопасности; Rust может почти всё делать лучше.
C++: отклонён, потому что это путаница; Rust может почти всё делать лучше.
Clojure: отличное моделирование; лучшее приближение к Lisp; отличная среда выполнения на JVM.
Elixir: отличная среда выполнения, включая развёртываемость и конкурентность; отличный опыт разработчика; относительно небольшая экосистема.
Erlang: отличная среда выполнения, включая развёртываемость и конкурентность; сложный опыт разработчика; относительно небольшая экосистема.
Elm: выглядит очень многообещающе; IBM публикует крупные кейсы с хорошими результатами; меньшая экосистема.
Flow: интересное улучшение по сравнению с JavaScript; однако разработчики отходят от него.
Go: отличный опыт разработчика; отличная конкурентность; но история плохих решений, калечащих язык.
Haskell: лучший функциональный язык; меньшее сообщество разработчиков; не достиг достаточного числа опубликованных успехов в промышленной эксплуатации.
Java: отличная среда выполнения; отличная экосистема; посредственный опыт разработчика.
JavaScript: самый популярный язык за всё время; самая обширная экосистема.
Kotlin: исправляет многое в Java; отличная поддержка JetBrains; хорошие опубликованные примеры перехода с Java на Kotlin.
Python: самый популярный язык для системного администрирования; отличные инструменты аналитики; хорошие веб-фреймворки; но покинут Google в пользу Go.
Ruby: лучший опыт разработчика за всё время; лучшие веб-фреймворки; самое приятное сообщество; но очень медленный; несколько трудно упаковывать.
Rust: лучший новый язык; упор на нулевые абстракции; упор на конкурентность; однако относительно небольшая экосистема; и сознательные ограничения на некоторые виды ускорения компилятором, например прямой доступ к памяти должен быть явно небезопасным (unsafe).
TypeScript: добавляет типы в JavaScript; отличный транспайлер; растущий упор разработчиков на переход с JavaScript на TypeScript; сильная поддержка Microsoft.
Мы решили, что у виртуальных машин есть набор компромиссов, которые нам сейчас не нужны, например дополнительная сложность, предоставляющая возможности времени выполнения.
Мы считаем, что наше основное решение определяется двумя сквозными соображениями:
Для максимальной скорости выполнения и самого тесного доступа к системе мы бы выбрали JavaScript и C.
Для скорости выполнения, близкой к максимальной, и доступа к системе, близкого к самому тесному, мы выбираем TypeScript и Rust.
Почётное упоминание получают языки виртуальных машин и веб-фреймворки, которые мы бы выбрали, если бы хотели язык с виртуальной машиной:
Clojure и Luminus
Java и Spring
Elixir и Phoenix
Следствия
Фронтенд-разработчикам придётся изучить TypeScript. Вероятно, это лёгкая кривая обучения, если основной опыт разработчика связан с JavaScript.
Бэкенд-разработчикам придётся изучить Rust. Вероятно, это средняя кривая обучения, если основной опыт разработчика связан с C/C++, и трудная кривая обучения, если основной опыт разработчика связан с Java, Python, Ruby или аналогичными языками с автоматическим управлением памятью.
TypeScript и Rust относительно новы. Это значит, что у многих инструментов ещё нет документации для этих языков. Например, devops-конвейер придётся настраивать под эти языки, и пока ни у одного из оцениваемых нами devops-инструментов нет примеров по умолчанию для них.
Время компиляции TypeScript и Rust довольно велико. Отчасти это может быть связано с новизной языков. Возможно, нам стоит рассмотреть, как смягчить медленную компиляцию, например компиляцией по требованию, конкурентной компиляцией и т. д.
Поддержка этих языков в IDE пока не повсеместна и пока не первоклассна. Например, JetBrains продаёт IDE PyCharm с первоклассной поддержкой Python, но не продаёт IDE с первоклассной поддержкой Rust; вместо этого JetBrains может использовать плагин Rust, который обеспечивает, пожалуй, 80% поддержки языка Rust по сравнению с поддержкой языка Python.
Связанное
Связанные решения
Мы будем стремиться к выбору экосистемы, согласованной с этими языками.
Например, мы хотим выбрать IDE с хорошими возможностями для этих языков.
Например, для нашего фронтенд-веб-фреймворка мы с большей вероятностью выберем фреймворк, ориентированный на TypeScript (например, Vue), чем фреймворк, ориентированный на чистый JavaScript (например, React).
Связанные требования
Вся наша цепочка инструментов должна поддерживать эти языки.
Связанные артефакты
Мы ожидаем, что часть секретов мы можем экспортировать в переменные окружения.
Связанные принципы
Семь раз отмерь, один раз отрежь. Мы отдаём приоритет некоторой безопасности перед некоторой скоростью.
Время выполнения ценнее времени компиляции. Мы отдаём приоритет использованию клиентами перед использованием разработчиками.
Примечания
Любые примечания здесь.