Nim

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Nim
Класс языка

мультипарадигмальный: императивный, объектно-ориентированный, функциональный, обобщённое программирование

Тип исполнения

компилируемый

Появился в

2004 год (создание языка), 2008 год (создание первой версии компилятора, способного компилировать самого себя)

Расширение файлов

.nim

Выпуск

0.17.2 (7 сентября 2017)

Система типов

статическая, с выводом типов

Испытал влияние

Lisp, Python, C, Object Pascal, Ada, Модула-3, Оберон

Лицензия

MIT[1]

Сайт

nim-lang.org

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

По утверждению разработчиков Nim сочетает мощь Lisp, простоту и понятность Python и высокую производительность C. Важной особенностью, которую Nim унаследовал от Lisp, стало то, что абстрактное синтаксическое дерево (AST) является частью спецификации языка, что позволяет поддерживать мощную систему макросов, следовательно, обеспечивает создание предметно-ориентированных языков (DSL).

Язык Nimrod был создан в 2004 году Андреасом Румпфом (Andreas Rumpf). При его создании основополагающими были три принципа, обозначенные самими авторами, как «3E» (перечисляемые в порядке их важности):

  1. Эффективность (efficiency);
  2. Выразительность (expressiveness);
  3. Элегантность (elegancy).

Разработка началась в 2004 году на языках Object Pascal (компилятор Free Pascal) и Python. Однако, первая версия, которая могла компилировать сама себя была представлена 22 августа 2008 года (версия 0.6.0). Компилятор Nim преобразует код, написанный на языке Nim, в код на языке C, C++, Objective-C или JavaScript[2] , и затем вызывает компилятор (или интерпретатор) этого языка. Поддерживается достаточно большое количество компиляторов C и C++. Однако, при компиляции чаще всего используется C, так как компиляторы C выполняют оптимизации (см. оптимизирующий компилятор) и переносимы, за счёт чего компилятор Nim и программы, написанные на языке Nim, работают в ОС Windows, Linux, BSD, MacOS X и во многих других ОС, в которых имеется C компилятор.

В языке Nim, как и в Python, в качестве разделителей блоков используются отступы, хотя фильтры препроцессора могут разделять блоки и по фигурным скобкам или ключевым словам endX. Эти фильтры можно использовать в шаблонах. Язык Nim регистро-независимый и даже стиле-независимый язык. Его довольно необычной особенностью является то, что подчеркивания и цифры в идентификаторах игнорируются.

Язык можно использовать как императивный, процедурный язык, но он также поддерживает объектно-ориентированный, функциональный и обобщённый стили программирования.

Объекты с наследованием, перегрузкой, полиморфизмом и множественной диспетчеризацией (мультиметоды) позволяют использовать объектно-ориентированное программирование. Синтаксический «сахар» подталкивает к ООП стилю и цепочкам вызовов: funct(a, b) заменяется на a.funct(b).

Поддерживается метапрограммирование с использованием шаблонов, макросов, условной компиляции с выполнением функций во время компиляции (CTFE). Nim позволяет создавать пользовательские операторы.

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

Nim также поддерживает механизм модулей для изоляции независимых библиотек или пакетов. Стандартная библиотека Nim имеет функции для выполнения ввода/вывода, для взаимодействия с ОС, для работы со строками (имеется поддержка юникода, регулярных выражений и РВ-грамматик с различными парсерами), для работы с опциями командной строки, для работы с форматами XML, CSV, SQL… и др.

Взаимодействие с другими языками[править | править вики-текст]

Двоичный интерфейс приложений (ABI) языка C поддерживается так же хорошо, как и стандартная библиотека C, включая существующие код и библиотеки. Nim поддерживает соглашения о вызовах функций языка C и функций из библиотек ОС Windows (модуль «dynlib» позволяет получить доступ к функциям динамических библиотек (файлы .dll, .so, .dylib)). К тому же поддерживаются ABI С++ и Objective C, а так же интеграция с JavaScript

Таким образом, Nim имеет привязки к большому количеству библиотек, от системных (POSIX, Windows) до баз данных (MySQL, PostgreSQL, SQLite, ODBC), от скриптовых языков (Python, Lua, TCL) до графических библиотек (OpenGL, Cairo, SDL).

Реализована поддержка привязок к GTK2, X11, IUP и Windows API.

Также полезны привязки к libcurl, libzip и PCRE.

Примеры[править | править вики-текст]

Приведённые примеры кода верны для Nim 0.17.0. Синтаксис и семантика могут изменяться в последующих версиях.[3]

Hello world[править | править вики-текст]

Код программы Hello, World! для Nim:

echo("Hello, world!")
# Скобки можно опустить
echo "Hello, world!"

Реверс строки[править | править вики-текст]

Простой пример, показывающий много особенностей Nim.

proc reverse(s: string): string =
  result = "" # неявная переменная результата
  for i in countdown(s.high, 0):
    result.add s[i]

let str1 = "Reverse This!"
echo "Reversed: ", reverse(str1)

Одной из наиболее необычных особенностей является неявная переменная result. Каждая процедура в Nim, возвращающая какое-нибудь значение, имеет неявную переменную результата. В ней хранится значение, которое вернёт функция. В цикле for происходит вызов итератора countdown. Если итератор будет опущен, то компилятор попытается использовать итераторы по элементам itemsили pairs (в зависимости от числа переменных в for),если один из таких определён для указанного типа.

Выведение типов[править | править вики-текст]

Nim поддерживает выведение типов:

let hello = "Hello, world!" # Тип указывать не нужно

# Компилятор сам может выводить типы аргументов и возвращаемых значений процедуры
proc doWork(something: auto): auto = 
  result = something + something
 
echo doWork(5)  # Выведет 10

Поддержка юникода в исходном коде[править | править вики-текст]

Nim поддерживает идентификаторы в юникоде:

proc привет(имя: string) = 
  echo("Привет, ", имя, "!")
 
привет("Человек")

Метапрограммирование[править | править вики-текст]

Пример метапрограммирования в Nim с использованием шаблонов.

template genType(name, fieldname: untyped, fieldtype: typedesc) =
  type
    name = object
      fieldname: fieldtype

genType(Test, foo, int)

var x = Test(foo: 4566)
echo(x.foo) # 4566

Шаблон genType выполняется во время компиляции и создаёт тип Test.

Обёртка над C функцией[править | править вики-текст]

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

proc printf(formatstr: cstring) {.header: "<stdio.h>", varargs.}

printf("%s %d\n", "foo", 5)

В примере хорошо известная функция printf импортируется в Nim и затем используется.[4]

См. также[править | править вики-текст]

Примечания[править | править вики-текст]

  1. Nim - FAQ.
  2. Nim Backend Integration (англ.). nim-lang.org. Проверено 17 июня 2017.
  3. Nim code examples at Rosetta Code
  4. What is special about Nim?. HookRace (1 января 2015). Проверено 20 января 2017.

Источники[править | править вики-текст]

Ссылки[править | править вики-текст]