Nim

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

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

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

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

Появился в

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

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

.nim

Выпуск

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

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

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

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

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

Лицензия

MIT[1]

Сайт

nim-lang.org

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

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

История и применение[править | править код]

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

  • эффективность (англ. efficiency),
  • выразительность (expressiveness),
  • элегантность (elegancy).

Разработка началась в 2004 году на языках Object Pascal (компилятор Free Pascal) и Python. Однако, первая версия, которая могла компилировать сама себя была представлена 22 августа 2008 года (версия 0.6.0), к этому моменту к Румпфу присоединился ряд волонтёров, участвующих в разработке и развитии языка.

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

Синтаксис и парадигматика[править | править код]

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

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

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

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

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

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

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

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

Таким образом, язык имеет привязки к большому количеству библиотек, от системных (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! для Nim:

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

Обращение строки:

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

Идентификаторы могут быть набраны в юникоде:

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.

Следующая программа показывает, как используется существующий код на Си в 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.

Литература[править | править код]

Ссылки[править | править код]