Как те из вас, которые следуют за мной в Твиттере, знают, я не очень люблю C++. У него свои обычные проблемы с заголовочными файлами, отстойными шаблонами, и так далее. И большая проблема — найти альтернативу. Я рассматривал вариант перейти на C#, но сделать так, чтобы он хорошо заработал на всех платформах, кажется очень сложной задачей (например, на данный момент поддержка x86 на Mac практически отсутствует). К тому же некоторым людям такой выбор будет не по вкусу.
Мне нравится (Common) Lisp. Я восхищаюсь устройством его макросов, в нём есть та элегантность, которая встречается не во всех языках. Однако он кажется каким-то чужеродным для многих людей, так что вкладывать в проект станет намного сложнее. К тому же я хочу по возможности использовать язык без сборщика мусора, и хотя Lisp можно сильно ускорить, сделать это не так уж просто.
Вхождение в Rust
Я следил за Rust несколько лет, но никогда ничего не писал на нём, до того, как в мае 2015-го вышла версия 1.0. Когда я стал приглядываться к Rust, я хотел понять, есть ли в нём что-то полезное для меня. На бумаге всё выглядело хорошо (приведу список самых интересных для меня моментов):
- Гарантированная безопасность использования памяти.
- Потоки без гонки данных.
- Минимальная среда выполнения.
- Эффективные привязки к C.
- Отсутствие сборщика мусора.
- Модули.
- Использование LLVM.
- Компилируется в нативный код.
Я решил посмотреть, к чему использование Rust меня приведёт. Я так же сделал презентацию про Rust, которую можно посмотреть здесь.
На тот момент я начал рассматривать список поддерживаемых Rust платформ. Он поддерживает Mac, Windows и Linux. Обычно поддержка Windows так себе, по крайней мере для «новых» языков. Я был приятно удивлён, что Rust прекрасно работает на Windows, за что большая благодарность команде Rust.
Другой мой вопрос: «используется ли Rust для больших проектов?» Переход на язык, который не будет нигде использоваться в ближайшие несколько лет, — отстой, и хотя это и не конец света, но итог может быть весьма болезненным. Похоже, что сам Rust написан на Rust, и он достаточно большой. Servo от Mozilla тоже большой проект, и так же написан на Rust.
Подходит ли Rust для плагинов?
Мой следующих ход — к концу рождественских праздников добавить поддержку Rust для плагинов (сейчас поддерживается только C/C++) чтобы узнать, насколько просто будет писать на нём плагины. И похоже, что оборачивание Rust вокруг C API на основе структур с указателями на функции прекрасно работает. Вот (ранний) пример.
Хотя много кода в этом примере может быть улучшено, если его сделать более идиоматичным для Rust, он действительно работает с C API, что я и хотел доказать.
Можно ли ProDBG переписан на Rust без полного переписывания?
Я начал играться, раскрывая разные части кода C++ и вызывая только «prodbg_main» из Rust. После починки нескольких ошибок линковки, всё заработало! Это одно из достоинств Rust: будучи компилируемым языком, его можно линковать с кодом на C/C++ без клея в виде DLL.
Затем я начал раскрывать остальные части кода. Я написал «обработчик плагинов», который загружает динамические библиотеки (плагины) и показывает один из них на экране. Одновременно я добавил перезагрузку плагинов, так что теперь при компиляции плагина (который может быть написан на Rust или C/C++) он будет перезагружен на лету, что замечательно.
Вот тут можно посмотреть на тестовый код, с которым можно поиграться перед более глубоким погружением в основной код (на данный момент код уже не доступен — прим. перев.).
И что теперь?
После того, как я немного поигрался с Rust, язык определённо захватил меня. Это великолепный язык, который предлагает великолепные фичи (см. мою презентацию). Особенно хочется отметить систему времён жизни и заимствования. Что хорошо в заимствовании/времени жизни, компилятор Rust может управляться с по настоящему неизменяемым состоянием, что позволяет включить noalias фазы LLVM, так что Rust может даже обогнать C-код по производительности.
Участие в сообществе Rust и наблюдение за развитием языка даёт мне надежду на его будущее, так что я решил взяться за написание ProDBG на Rust. В то же время я буду опираться на внешний код на С++ (вроде imgui, Scintilla, bgfx). Мне нет причины переписывать всё на Rust. Так же открытое для плагинов API всё ещё будет на C. Благодаря этому добавление поддержки для других языков (Lua, Python, JS, .NET) в будущем становится намного проще.
Недостатки
Переход на язык, которым пользуется на так много народу, как C/C++, всегда имеет свои проблемы. Более медленный компилятор (над этой проблемой работают), сложности в отладке (пока что нет хорошего фронт-енда, но думаю, для меня это хорошая мотивация :), меньше людей, которые знают язык, и никто не знает, что случится в будущем. Несмотря на всё сказанное, я всё же считаю, что Rust идёт по верному пути, и мне кажется, что перейти на него — верное решение.
Самый большой недостаток в том, что переход в начале замедлит разработку проекта, что отстойно. Я надеялся к настоящему моменту уже достичь версии 0.1, но теперь релиз откладывается.
Послесловие
Вот такие дела. Решение не было лёгким, потому что оно влияет на всех участников проекта. Заметьте, что API будет на C, и я принимаю вклад в виде плагинов, написанных на C/C++.
И всё же я думаю, что решение было верным. Вот здесь (англ.) можно почитать о том, что происходило с языком в течение 2015 года, и что его ждёт в 2016-м.
Автор: kstep