TGViewer
Гепардово гнездо Гепардово гнездо @gepardchan · 617 subscribers
Post #144 1.28K
Чем я заnimался

Все описанное в посте происходило несколько месяцев назад, и у меня долго не доходили лапки оформить пост, но все же…

Как вы уже, наверное, догадались из заголовка, речь пойдет про язык программирования Nim.

Я уже писал ранее про свои коммиты в Nim, но с тех пор пришлось еще немного в него поконтрибутить. На этот раз не в стандартную библиотеку, а аж в сам компилятор!

В современных языках обычно принято писать компиляторы на них же самих. Nim здесь не исключение. Когда-то давным-давно его компилятор был написан на Object Pascal, но с тех пор весь код на паскале автоматически сконвертили в код на Nim. Результат этой конвертации хорошо описывается словами из compiler/readme.md:
So the code is not a poster child of good Nim code.


Другая особенность компилятора Nim — это то, что он не использует LLVM (хотя существует сторонняя реализация, которая юзает LLVM как бэкенд компиляции), а транслирует код в Си, и только потом уже собирает бинарник при помощи gcc, clang или любого другого компилятора, который существует в системе. Подход хорош тем, что позволяет очень и очень просто заюзать любую функцию из любой библиотеки на Си (просто указываешь, какую функцию из какого хедера ты хочешь импортировать в Nim, и какую библиотеку надо влинковать — и все работает. А этот ваш Rust так может?). Еще можно попросить компилятор скомпилить код не в Си, а C++ — это может пригодиться для интеропа с C++ и позволяет юзать классы из кода на C++ в коде на Nim.

Конечно же, у такой двухэтапной компиляции есть и проблемы. Основная заключается в том, что, вообще говоря, Си и C++ — языки с достаточно большим количеством странностей и не всегда консистентным поведением. Например, ссылки в C++, которые умеют неявно разыменовываться, а сами ссылки нельзя никак изменять. Или массивы фиксированного размера в Си, которые ведут себя иногда как значение, а иногда как указатель на первый элемент — зависит от того, где и как массив используется. И, конечно же, при переводе кода на C/C++ эти все особенности надо учитывать. Естественно, учет особенностей приводит к костылям и багам в компиляторе. А избегать их иногда сложно, потому что хочется хороший интероп с C/C++.

Я несколько раз находил баги компилятора (раз, два, три) разной степени критичности. Кстати, баги в Nim исправляют довольно оперативно — через неделю-две созданный мной issue уже оказывался исправленным и закрытым. Но вот один раз мой баг игнорили аж целую неделю, поэтому я решил попробовать свои силы и исправить его самостоятельно.

Десяток часов времени, горстка отладочных echo по коду — и баг исправлен. Пора делать PR. Кстати, довольно много времени ушло не на то, чтобы понять причину бага, а на то, чтобы понять, как наиболее правильно его исправить и не поломать старые костыли, учитывающие всевозможные хитрые случаи. А еще в случае с C++ для фикса надо было уметь копировать ссылку — это сложная задача, поэтому пришлось немного покостылить и сделать так, чтобы вместо нее копировался указатель.

В итоге баг повержен, PR залит, issue закрыт. Победа? А вот и нет!

Для начала пришлось немного попотеть, чтобы бэкпортировать фикс в stable ветку. При попытке это сделать падали тесты, и пришлось черри-пикнуть в stable еще один коммит, чтобы все заработало.

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

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

Стоит отметить, что описанные выше проблемы с компиляцией пытаются потихоньку решить. В частности, авторы языка изобрели промежуточный байткод между самой логикой Nim и C/C++ бэкендами, что позволит, я надеюсь, упростить компилятор и уменьшить количество багов.
  • 👍 17
  • 🤯 2
  • 🤔 1
More from @gepardchan
  1. Sep 7, 2025Итак, расскажу о том, что я сделал еще давно, но про что все никак не доходили руки написа…
  2. Dec 10, 2024https://habr.com/ru/post/472970/ Статья 2019 года, то есть довольно старая, с учетом того,…
  3. Nov 30, 2024Сегодня читал про то, как Debian везде перешел на 64-х битный time_t. Изменение войдет в р…
  4. Nov 26, 2024https://www.ryanliptak.com/blog/every-rc-exe-bug-quirk-probably/ Не знаю, как вы, а я прос…
  5. Nov 22, 2024Еще про проклятые фичи баша https://yossarian.net/til/post/some-surprising-code-execution-…
  6. Nov 21, 2024Про переписывание истории В баше (а точнее, в GNU Readline, который используется башом), е…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →