Nim: совершенный язык программирования

0
9530
Добавить в избранное

Статья раскрывает самые интересные особенности языка программирования Nim. Прочти, возможно, это окажется твоим выбором!

Со временем разработчик добивается такого профессионализма, благодаря которому может понять все недочёты инструментов, которые использует, находя новые, обладающие плюсами предыдущих, лишённые их  границ. Подтверждением этого является усиливающееся течение новых методика и языков, словно грибы после дождя.

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

Совершенный язык

Сегодня мы обсудим такой малоизвестный нам  язык программирования как: Nim.

В настоящее время Nim можно назвать совершенным для меня языком по сравнению с Rust, C++, D, Java, JavaScript, Ruby, PHP и так далее.

Nim являет собой успешно объединённые концепции иных языков, таких как Python, Lisp, C, Object Pascal, Ada, Modula-3 и только лишь автор знает, каких еще.

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

Исходя из этого, начнём.

Особенности моего совершенного языка:

— Продуктивность. Точная система стандартизации предоставляет возможность написания поддерживаемого и самодокументируемого кода, не затрудняющая созданию быстрых прототипов, допустим как на Python.

— Безопасность. Хаотичность данных не мешает регулированию памяти. Очищение системных ресурсов происходит автоматически. Так или иначе, данные условия создают современные языки со сборщиком мусора и Rust.

— Простота синтаксиса. На усвоение уходит немного времени. Новички должны разобраться в коде также быстро, как если бы он был написан на уже известном им языке.

— Выразительность. Язык должен раздвигать рамки принятого и быть благосклонным к разного вида DSL. Ruby, Perl и несколько других языков имеют в этом успехи.

— Скорость. Безусловно, мы хотели бы, чтобы наши программы применяли CPU только на полезные вычисления. Такое условие исключает многие динамически типизированные языки.

— Низкий уровень.

Он нам не нужен, но порой его не обойти. Ручное управление памятью, где это необходимо, адресная арифметика, установки сурового текущего промежутка времени. В такие моменты не имеет смысла применять иной, «низкоуровневый» язык.

— Метапрограммирование. Мы не нуждаемся в использовании средств, которые создают код на нашем языке. На этапе компиляции нам необходимо, чтобы этот процесс происходил в рамках нашего языка. В числе компилируемых языков мы можем видеть Lisp, D и Rust.

— Портируемость.  Код на нашем языке обязан запускаться повсюду, так же как на С. Каждая ОС, каждая структура, в том числе ARM, PIC и AVR, применяемый в неких Arduino. Скорее было бы лучше запускать его в браузерах, поддерживающих Javascript!

Совместимость с религиозно-несовместимыми экосистемами

За десятки дней развития C, C++ и Java было написано масса грамотных библиотек. В момент нужды было бы неплохо примененить их в проекте, написанном на нашем совершенном языке.

Это может прозвучать фантастично, но Nim отвечает вышеуказанным требованиям, я бы тоже не поверил, если бы не опробовал на себе.
О синтаксисе языка, а также как начать писать на Nim и прочих мелочах вы узнаете на этих сайтах:

— Nim by example
— How I start
— Официальное руководство

В этой статье я бы хотел продемонстрировать более сложные способности Nim, почерпнув некие тонкости из презентации создателя языка Nim, Андреаса Румпфа (Andreas Rumpf), не так давно прошедшей в рамках OSCON.

Удостовериться в том, что подобные возможности могут вызывать не только академический интерес, можно  проанализировав, исходники проекта nimx, который мы создаём и применяем в нашем игровом проекте. В особенности nimx поддерживает помимо компиляции в машинный код, ещё и в Javascript+WebGL.

Шаблоны

Приступим к рассмотрению выразительности и расширяемости синтаксиса:

Произведение этого кода отобразит окончательный результат:

Заглянув в промежуточный С-код любознательный читатель, увидит то, что весь HTML-код записан одной C-строкой. За это несёт ответственность внушительный механизм сокращения констант (constant folding), осуществлённый в компиляторе Nim.

Макросы

В случае если сильная сторона шаблонов по каким-либо причинам вас не убедила, тогда на подмогу придёт тяжелая артиллерия — макросы. В Nim это методы, воспринимающие узлы AST (Abstract Syntax Tree — результат синтаксического анализа языка) в виде доказательств и возвращающие модифицированный AST.

Дальнейший образец диктует необходимость расширенных знаний языка. Для этого попытаемся дополнить в Nim анализ покрытия кода (code coverage). В качестве эксперимента пример может служить данный способ:

В нём мы можем разглядеть некоторые отрасли в потоке управления. Далее надо определить, какие отрасли покрыты тестом. Перед тем как, что-либо автоматизировать, нужно произвести это самостоятельно. Для начала предлагаю написать код, благодаря которому по итогу можно будет создать макрос:

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

В итоге сбора данных мы можем видеть следующее:

Теперь, когда составляющие кода нам понятны, мы можем полноценно осуществить макрос. Для понимания этого примера необходимы углубленные знания Nim. Если вы его не понимаете, то просто пропустите.

Результат проведения:

Отсюда следует, что меньше чем в 30 строках кода мы смогли создать дельный функционал, для которого в других языках понадобились бы дополнительные средства. При помощи макросов у вас есть возможность увеличивать в языке количество функций, добавив те которых вам не хватает: интерполяция строк, pattern matching или что-то еще. Проверенный синтаксис Nim гарантирует определенность грамматики при применении расширений. Заметив «загадочный» DSL-код, вы всегда знаете, с какими аргументами вызвать grep ;).

Управление памятью

Как я уже говорил ранее, главной стороной языка программирования является присутствие развитых средств управления памятью. Nim предоставляет возможность применения как ручного, так и автоматического способа управления памятью. Поэтому в нём представлены такие модификаторы, как ref и ptr.

Разберём их функции на примере объектов:

Сейчас перед нами некоторый новый тип, исходя, из которого есть возможность создания объектов этого типа перечнем способов. Первым способом будет образование объекта по значению:

Данная переменная хранит объект по значению, согласно этому, функции, в которые эти объекты передаются, работают с копиями, таким образом, сам объект прекратит существование тогда, когда переменная выйдет из области видимости, в которой она установлена.

В противовес этому, у нас есть возможность осуществлять выделение памяти под объект в контролируемой сборщиком мусора куче, применяя функцию new:

Тогда переменная pp опираться на объект, находящийся в хранилище, контролируемом сборщиком мусора, а действительным тип переменной будет ref Person (ref — управляемая ссылка). Подобные объекты передаются в коде по ссылкам и умирают тогда, когда ссылки на такой объект в памяти отсутствуют.

Сейчас приступим к заключительному, самому низкоуровневому способу работы с памятью, точнее – к процессу работы с неконтролируемым  хранилищем памяти, которая проводится при помощи функций alloc, realloc и dealloc, по поведению аналогичная C-шные malloc, realloc и free.

Как вы можете видеть из примера, в этой ситуации переменная up, как и в предыдущем, сменяет тип, то есть ее тип — не Person, а ptr Person, что означает рискованный неконтролируемый указатель, хранящий адрес объекта в памяти.

Наряду с этим в момент потребности, для комфортного применения данных типов с модификаторами, определенно их следует отметить при помощи ключевого слова type:

Подобная адаптивность в способах регулирования памятью помогает, как писать безопасный код, не волнуясь об утечке памяти, так и всецело контролировать управление памятью, в особенности тогда, когда идет речь о взаимосвязи с иными языками.

Взаимосвязь с другими экосистемами

В структуре Nim находится C, C++, Objective-C или JavaScript как переходный код. Это означает то, что применение библиотек, прописанных на этих языках, довольно банально. Иные языки  обычно предполагают механизмы расширения через C-интерфейс. Даже в этом Nim управляется отлично, допуская писать бриджи к другим языкам, как библиотеки.

Итак, я обрисовал небольшую библиотеку jnim, понятную на GitHub. jnim делает возможным «импортировать» модули Java. Отражается это так:

Всё волшебство возникает в глубине jnim. Для любого обозначения jnimport образовывается аналогичное содержание в Nim, и создается весь нужный glue-код. В дальнейшем итогом развития jnim послужит перспектива того, что можно будет не отмечать поля и процедуры, а автоматически импортировать обозначения классов из Java-окружения на этапе компоновки.

Заключение

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

Кроме этого мы пропагандируем данный язык внутри Альянса, проводим некоторые образовательные мероприятия для наших сотрудников, а также в планах стоит пригласить в Украину автора Nim, Андреаса Румпфа.

Любопытно, а кто также развивается в этом направлении в Украине? Буду рад прочесть в комментариях ваши мнения на этот счёт. Есть ли у вас опыт использования Nim? Сталкивались ли вы с задачами, для решения которых Nim был бы более результативным инструментом?

Хотите получать больше интересных материалов с доставкой?

Подпишитесь на нашу рассылку:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Оставьте комментарий