В поисках нового внутреннего языка я, естественно, перешел от Python к новому классному ребенку: Go. Но после всего лишь одной недели Go я понял, что Go - это только половина прогресса. Лучше подходит для моих нужд, чем Python, но слишком далеко от возможностей разработчика. Мне нравилось делать Вяз во внешнем интерфейсе. Поэтому я попробовал Rust.

Python.

Что касается серверной разработки, последние три года я в основном использую Python 3. От административных скриптов до машинного обучения и приложений Flask / Django - в последнее время я много занимался Python, но в какой-то момент это больше не казалось правильным. Что ж, честно говоря, это не совсем случайный момент, когда я начал чувствовать себя неправильным, это было тогда, когда я начал получать удовольствие от программирования на строго типизированном языке: Elm.

У меня было знаменитое чувство «когда он компилируется, он работает», и как только вы это почувствуете, пути назад нет. Вы пробуете что-то, следите за сообщениями об ошибках компилятора, исправляете ошибки, и затем tada, все работает!

Итак, на этом этапе я знал, чего хочу от «идеального» языка серверной части:

  1. Статический и строгий набор
  2. Большая часть материала проверяется во время компиляции (пожалуйста, без исключений!)
  3. No null
  4. Нет изменчивости
  5. Удобная обработка параллелизма

Я вижу, как вы идете: Эй, это же« Haskell »! Да, конечно, но по какой-то причине мне никогда ничего не удавалось сделать с Haskell (и я много пытался). Возможно, это только я, но со стороны мнение Haskell кажется элитарным, отсутствует документация и практические примеры, и он вряд ли доступен для новичка. Выучи себя на Haskell навсегда - это круто, но читать очень долго и слишком абстрактно для меня (во время книги вы ничего не строите по-настоящему).

Эй, а что насчет« Scala ?!». Что вы имеете в виду под Scala? Чем лучше Java? Функциональный язык программирования с Скалаз? Функциональный язык объектно-ориентированного программирования, который может или не может дать сбой во время выполнения с java.lang.NullPointerException и нуждается в запущенной JVM 4 ГБ? Я пробовал это несколько лет назад, и определенно, мне это не подходит.

Поговорив с несколькими людьми, я решил попробовать Go. У него есть компилятор, без исключений, без null (но с нулевыми значениями), и он прекрасно справляется с параллелизмом.

Go.

Я решил переписать внутренний проект, который уже был выполнен на Python, с использованием Go. Просто чтобы почувствовать разницу между ними.

Первое ощущение: освоить Go было так легко. Однажды вечером мне удалось составить Proof Of Concept проекта, в котором были разработаны основные функции и написаны некоторые тесты. Это было очень приятное ощущение, я очень быстро добавлял функции. Сообщения компилятора были полезны, все было хорошо.

И в какой-то момент началась трагедия. Мне нужно было добавить поле в какую-то структуру, поэтому я просто изменил структуру и был готов проанализировать сообщения компилятора, чтобы узнать, где эта структура использовалась, чтобы добавить поле там, где оно было необходимо.

Я скомпилировал код и… сообщений об ошибке нет. Все прошло нормально. Но?! Я только что добавил поле в структуру, компилятор должен сказать, что мой код больше не подходит, потому что я не инициализирую значение там, где оно должно быть!

Проблема в том, что отсутствие значения для структуры не является проблемой в Go. По умолчанию это значение будет равно нулевому значению, и все будет скомпилировано. Для меня это было препятствием для шоу. Я понял, что не могу полагаться на компилятор, чтобы исправить ситуацию, когда я делал ошибки. В этот момент я задавался вопросом: зачем мне изучать Go, если компилятор не может лучше, чем Python и mypy? Конечно, параллелизм намного лучше с Go, но для меня было слишком много недостатков - невозможность полагаться на компилятор.

Не поймите меня неправильно, я по-прежнему считаю, что Go - это прогресс по сравнению с Python, и я бы окончательно рекомендовал людям изучать Go вместо Python, если бы им пришлось выбирать один из двух. Но в моем личном случае, поскольку я был человеком, который уже знал Python и хотел чего-то более безопасного, Go не принес достаточно средств в этой конкретной области.

Ржавчина.

Так что Go больше не подходил, поскольку я понял, что мне действительно нужен полезный компилятор: компилятор, который не должен полагаться на то, что я умею кодировать (как много раз было доказано, что это ложь). Вот почему я обратил внимание на Rust.

Rust не был моим первым выбором, потому что он рекламирует себя как «системный язык», а я больше веб-разработчик, чем системный. Но у него было несколько очень убедительных аргументов:

  • Без значений null, кроме типа Option (проверено во время компиляции)
  • Нет exceptions, но тип Result (проверено во время компиляции)
  • По умолчанию переменные неизменяемы.
  • Разработан с учетом параллелизма
  • Память безопасна по дизайну, нет сборщика мусора

Я решил переписать ту же программу, что и на Python и Go. Подключение было намного сложнее, чем с Go. Как и в случае с Go, я попытался сначала разобраться, но это было слишком сложно: мне потребовались некоторые новые концепции, характерные для Rust, такие как владение или время жизни, чтобы понять код, который я видел на StackOverflow. Так что у меня не было выбора, кроме как прочитать Rust Book, и мне потребовалось две недели, прежде чем я смог начать писать какой-то код (помните, что с Go у меня у меня ушло на один вечер).

Но после этого крутого начального обучения мне нравилось писать код на Rust, и я все еще наслаждаюсь этим. С Rust мне не нужно доверять себе, мне просто нужно следовать компилятору, и если я это сделаю, то, скорее всего, он будет работать, если он скомпилируется. В конце концов, это основное чувство, которое я искал при поиске нового языка для бэкенда.

Конечно, у Rust есть много недостатков:

  • Это довольно новое, и все развивается очень быстро. Я использую futures-rs и hyper.rs в своем проекте, и найти хорошую документацию было действительно сложно (спасибо людям на irc.mozilla.org # rust-beginners за помощь).
  • Это заставляет вас думать о вещах, к которым вы не привыкли, когда переходите с более высокоуровневых языков: как управляется память (с учетом времени жизни и владения).
  • Сообщения компилятора не всегда легко понять, особенно когда вы комбинируете фьючерсы и их странные длинные типы.
  • Допускается изменчивость, поэтому вы можете столкнуться с побочными эффектами

Но у него также есть много плюсов:

  • Это невероятно быстро
  • Оснастка хорошая (Cargo, rustfmt)
  • Большинство вещей проверяются во время компиляции
  • Вы потенциально можете делать с ним все, что захотите, от браузера до веб-приложения или игры.
  • Сообщество радушно
  • Поддерживается Mozilla

Подведение итогов

Go - это круто, но он не обеспечивает достаточной безопасности типов для меня. Я бы предпочел использовать Python и его экосистему, чем рисковать переписывать материал на Go, если мне не нужен параллелизм. Если мне нужен параллелизм, я бы все равно не использовал Go, поскольку его отсутствие безопасности типов наверняка в какой-то момент ударит по мне.

Rust - идеальный кандидат для обеспечения параллелизма и безопасности, даже если ящик futures-rs (так мы называем библиотеки в Rust) все еще находится на ранней стадии. Я подозреваю, что Rust может стать стандартом де-факто для множества потребностей серверной части в будущем.