Jump to content

Ним (язык программирования)

Nim
Логотип короны Нима
Парадигмы Мультипарадигмальность : скомпилированная , параллельная , процедурная , императивная , функциональная , объектно-ориентированная , мета.
Разработано Андреас Румпф
Разработчик Команда Ним Ланга [1]
Впервые появился 2008 год ; 16 лет назад ( 2008 )
Стабильная версия
2.0.4 [2]  Отредактируйте это в Викиданных / 16 апреля 2024 г .; 55 дней назад ( 16 апреля 2024 г. )
Дисциплина набора текста Статический , [3] сильный , [4] предполагаемый , структурный
Объем Лексический
Язык реализации Ним (самостоятельное размещение)
Платформа IA-32 , x86-64 , ARM , Aarch64 , RISC-V , PowerPC ... [5]
ТЫ Кросс-платформенный [6]
Лицензия МОЯ лицензия [7]  Отредактируйте это в Викиданных
Расширения имен файлов .ним, .нимс, .нимбл
Веб-сайт просто ним .org
Под влиянием
Ада , Модуль-3 , Лисп , C++ , Object Pascal , Python , Оберон , Rust , ParaSail [8]

Nim универсальный , мультипарадигмальный , статически типизированный , компилируемый высокого уровня язык системного программирования . [9] спроектирован и разработан командой Андреаса Румпфа. Nim задуман как «эффективный, выразительный и элегантный». [10] поддержка метапрограммирования , функционала , передачи сообщений , [11] процедурный и объектно-ориентированный стили программирования, предоставляя несколько функций, таких как генерация кода времени компиляции , алгебраические типы данных , интерфейс внешних функций (FFI) с C , C++ , Objective-C и JavaScript , а также поддержку компиляции в те же языки, что и промежуточные представления .

Описание [ править ]

Ним статически типизирован. [12] во время компиляции, Он поддерживает функции метапрограммирования такие как синтаксические макросы и макросы перезаписи терминов . [13] Макросы перезаписи терминов позволяют эффективно реализовывать библиотечные реализации общих структур данных, таких как большие числа и матрицы, с синтаксической интеграцией, как если бы они были встроенными языковыми средствами. [14] Итераторы поддерживаются и могут использоваться как объекты первого класса. [13] как и функции, позволяющие использовать методы функционального программирования . Объектно-ориентированное программирование поддерживается наследованием и множественной диспетчеризацией . Функции могут быть универсальными и перегруженными, а дженерики дополнительно расширяются благодаря поддержке Nim классов типов . перегрузка операторов . Также поддерживается [13] Nim включает в себя несколько настраиваемых стратегий управления памятью, включая отслеживание сборки мусора , подсчет ссылок и полностью ручные системы , при этом по умолчанию используется детерминированный подсчет ссылок с оптимизацией посредством семантики перемещения и циклической сборкой посредством пробного удаления. [15]

[Ним] ... представляет собой самый оригинальный дизайн, который объединяет Паскаль и Python и компилируется в код C или JavaScript. [16]

Эндрю Бинсток, главный редактор журнала Dr. Dobb's Journal , 2014 г.

По состоянию на август 2023 г. , Nim компилируется в C, C++, JavaScript, Objective-C, [17] и ЛЛВМ. [18]

История [ править ]

Ветвь Версия Дата выпуска [19]
0.х Старая версия, больше не поддерживается: 0.10.2. 2014-12-29
Старая версия, больше не поддерживается: 0.11.2. 2015-05-04
Старая версия, больше не поддерживается: 0.12.0. 2015-10-27
Старая версия, больше не поддерживается: 0.13.0. 2016-01-18
Старая версия, больше не поддерживается: 0.14.2. 2016-06-09
Старая версия, больше не поддерживается: 0.15.2. 2016-10-23
Старая версия, больше не поддерживается: 0.16.0. 2017-01-08
Старая версия, больше не поддерживается: 0.17.2. 2017-09-07
Старая версия, больше не поддерживается: 0.18.0. 2018-03-01
Старая версия, больше не поддерживается: 0.19.6. 2019-05-13
Старая версия, больше не поддерживается: 0.20.2. 2019-06-17
1.0 Старая версия, больше не поддерживается: 1.0.0. 2019-09-23
Старая версия, больше не поддерживается: 1.0.10. 2020-10-27
1.2 Старая версия, больше не поддерживается: 1.2.0. 2020-04-03
Старая версия, больше не поддерживается: 1.2.18. 2022-02-09
1.4 Старая версия, больше не поддерживается: 1.4.0. 2020-10-16
Старая версия, больше не поддерживается: 1.4.8. 2021-05-25
1.6 Старая версия, больше не поддерживается: 1.6.0. 2021-10-19
Старая версия, но все еще поддерживается: 1.6.20. 2024-04-16
2.0 Старая версия, больше не поддерживается: 2.0.0. 2023-08-01
Текущая стабильная версия: 2.0.4. 2024-04-16
Легенда:
Старая версия
Старая версия, все еще поддерживается
Последняя версия
Latest preview version
Future release
Для каждой ветки 0.x указан только последний выпуск.
Для более поздних ветвей указан первый и последний выпуск.

Первоначальная разработка Nim была начата в 2005 году Андреасом Румпфом. Первоначально он назывался Nimrod, когда проект был обнародован в 2008 году. [20] : 4–11 

Первая версия компилятора Nim была написана на языке Паскаль с использованием компилятора Free Pascal . [21] В 2008 году была выпущена версия компилятора, написанная на Nim. [22] Компилятор является бесплатным программным обеспечением с открытым исходным кодом и разрабатывается сообществом добровольцев, работающих с Андреасом Румпфом. [23] Язык был официально переименован из Nimrod в Nim с выпуском версии 0.10.2 в декабре 2014 года. [24] 23 сентября 2019 года была выпущена версия Nim 1.0, что означает развитие языка и его набора инструментов. 1 августа 2023 года была выпущена версия Nim 2.0, означающая завершение, стабилизацию и переход на модель памяти ARC/ORC. [25]

Языковой дизайн [ править ]

Синтаксис [ править ]

Синтаксис Nim напоминает синтаксис Python . [26] Блоки кода и операторы вложения идентифицируются с помощью пробелов в соответствии с правилом офсайда . Многие ключевые слова идентичны их эквивалентам в Python, которые в основном представляют собой ключевые слова на английском языке, тогда как в других языках программирования обычно используются знаки препинания. С целью улучшения своих языков влияния, хотя Nim поддерживает синтаксис на основе отступов , такой как Python, он добавил дополнительную гибкость. Например, один оператор запятая или бинарный оператор может занимать несколько строк, если в конце каждой строки стоит . Nim также поддерживает определяемые пользователем операторы.

В отличие от Python, Nim реализует (встроенную) статическую типизацию. Система типов Nim позволяет легко преобразовывать типы , приводить типы и предоставляет синтаксис для общего программирования. В частности, Nim предоставляет классы типов, которые могут заменять несколько типов, и предоставляет несколько таких классов типов «из коробки». Классы типов позволяют работать с несколькими типами, как если бы они были одним типом. Например:

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

Этот пример кода демонстрирует использование классов типов в Nim]

# Let's declare a function that takes any type of number and displays its double
# In Nim functions with side effect are called "proc"
proc timesTwo(i: SomeNumber) =
  echo i * 2
# Let's write another function that takes any ordinal type, and returns
# the double of the input in its original type, if it is a number;
# or returns the input itself otherwise.
# We use a generic Type(T), and precise that it can only be an Ordinal
func twiceIfIsNumber[T: SomeOrdinal](i: T): T =
  when T is SomeNumber: # A `when` is an `if` evaluated during compile time
    result = i * 2 # You can also write `return i * 2`
  else:
    # If the Ordinal is not a number it is converted to int,
    # multiplied by two, and reconverted to its based type
    result = (i.int * 2).T
echo twiceIfIsNumber(67) # Passes an int to the function
echo twiceIfIsNumber(67u8) # Passes an uint8
echo twiceIfIsNumber(true) # Passes a bool (Which is also an Ordinal)

Влияние [ править ]

По словам создателя языка, Nim был задуман, чтобы объединить лучшие части системы типизации Ada, гибкости Python и мощной Lisp . макросистемы [27]

На Нима повлияли специфические характеристики существующих языков, в том числе следующие:

Унифицированный синтаксис вызова функций [ править ]

Nim поддерживает унифицированный синтаксис вызова функций (UFCS). [28] и равенство идентификаторов, что обеспечивает большую гибкость в использовании.

Например, каждая из этих строк печатает «hello world» , но с разным синтаксисом:

echo "hello world"
echo("hello world")
"hello world".echo()
"hello world".echo
echo("hello", " world")
"hello".echo(" world")
"hello".echo " world"

Равенство идентификаторов [ править ]

Ним почти полностью нечувствителен к стилю; два идентификатора считаются равными, если они различаются только заглавными буквами и символами подчеркивания, при условии, что первые символы идентичны. Это сделано для того, чтобы обеспечить смешивание стилей в разных библиотеках: один пользователь может написать библиотеку, используя в качестве соглашения Snake_case, и другой пользователь может без проблем использовать ее в стиле CamelCase. [29]

const useHttps = true
assert useHttps == useHttps
assert useHTTPS == useHttps
assert use_https == useHttps

Обвязка [ править ]

Функция ограничения позволяет использовать любое имя для переменных или функций, даже если имена являются зарезервированными словами для ключевых слов. Примером ограничения является возможность определить переменную с именем if, не конфликтуя с ключевым словом if. Реализация этого в Nim достигается с помощью обратных кавычек, что позволяет использовать любое зарезервированное слово в качестве идентификатора. [30]

type Type = object
  `int`: int

let `object` = Type(`int`: 9)
assert `object` is Type
assert `object`.`int` == 9

var `var` = 42
let `let` = 8
assert `var` + `let` == 50

const `assert` = true
assert `assert`

Компилятор [ править ]

Компилятор Nim C. по умолчанию генерирует быстрый оптимизированный код Он передает компиляцию объектного кода внешнему компилятору C. [31] использовать существующую оптимизацию и переносимость компилятора. Поддерживаются многие компиляторы C, включая Clang , Microsoft Visual C++ (MSVC), MinGW и GNU Compiler Collection (GCC). Компилятор Nim также может генерировать C++ , Objective-C и JavaScript код , чтобы обеспечить простое взаимодействие с интерфейсами прикладного программирования ( API ), написанными на этих языках; [9] разработчики могут просто писать на Nim, а затем скомпилировать его на любой поддерживаемый язык. Это также позволяет писать приложения для iOS и Android . Существует также неофициальный бэкэнд LLVM , позволяющий использовать компилятор Nim автономно. [18]

Компилятор Nim является автономным , то есть он написан на языке Nim. [32] Компилятор поддерживает кросс-компиляцию, поэтому он может компилировать программное обеспечение для любой из поддерживаемых операционных систем, независимо от машины разработки. Это полезно для компиляции приложений для встраиваемых систем, а также для необычных и малоизвестных компьютерных архитектур. [ нужна ссылка ]

Параметры компилятора [ править ]

По умолчанию компилятор Nim создает отладочную сборку. [33] С опцией -d:release Можно создать сборку выпуска , оптимизированную по скорости и содержащую меньше проверок во время выполнения. [33] С опцией -d:danger все проверки во время выполнения можно отключить, если требуется максимальная скорость. [33]

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

Nim поддерживает несколько стратегий управления памятью, включая следующие: [34]

  • --gc:refc – Стандартный отложенного подсчета ссылок на основе сборщик мусора с простым резервным сборщиком мусора с маркировкой и очисткой для сбора циклов. Кучи являются локальными для потоков.
  • --gc:markAndSweep – Простой метода «метка и очистка» на основе сборщик мусора . Кучи являются локальными для потоков.
  • --gc:boehm Boehm на базе Сборщик мусора , он предлагает общую кучу.
  • --gc:go Go Сборщик мусора , полезный для взаимодействия с Go . Предлагает общую кучу.
  • --gc:arc – Автоматический подсчет ссылок (ARC) с оптимизацией семантики перемещения , предлагает общую кучу. Он предлагает полностью детерминированную производительность для систем жесткого реального времени. [35] Ссылочные циклы могут вызвать утечки памяти: их можно устранить путем аннотирования вручную. {.acyclic.} прагмы или с помощью --gc:orc.
  • --gc:orc – То же, что --gc:arc но добавляет сборщик циклов («O») на основе «пробного удаления». [36] Сборщик циклов анализирует типы, только если они потенциально цикличны.
  • --gc:none – Нет стратегии управления памятью и сборщика мусора . Выделенная память просто никогда не освобождается, если только она не освобождается вручную кодом разработчика.

Начиная с Nim 2.0, ORC является сборщиком мусора по умолчанию. [37]

Инструменты разработки [ править ]

В комплекте [ править ]

В установочный пакет Nim входит множество инструментов, в том числе:

Шустрый [ править ]

Nimble — это стандартный менеджер пакетов, используемый Nim для упаковки модулей Nim. [38] Первоначально он был разработан Домиником Пичетой, который также является основным разработчиком Nim. Nimble включен в качестве официального менеджера пакетов Nim с 27 октября 2015 года, с выпуском версии 0.12.0. [39]

Пакеты Nimble определяются .nimble файлы, содержащие информацию о версии пакета, авторе, лицензии, описании, зависимостях и т. д. [20] : 132  Эти файлы поддерживают ограниченное подмножество синтаксиса Nim, называемое NimScript, при этом основным ограничением является доступ к FFI. Эти сценарии позволяют изменять процедуру тестирования или писать собственные задачи.

Список пакетов хранится в файле нотации объектов JavaScript ( JSON ), который находится в свободном доступе в репозитории nim-lang/packages на GitHub. Этот файл JSON предоставляет Nimble сопоставление имен пакетов и URL-адресов их репозиториев Git или Mercurial.

Nimble поставляется с компилятором Nim. Таким образом, можно протестировать среду Nimble, выполнив: nimble -v. Эта команда покажет номер версии, дату и время компиляции, а также Git хеш-код . Nimble использует пакет Git, который должен быть доступен для правильной работы Nimble. Командная строка Nimble используется в качестве интерфейса для установки, удаления (деинсталляции) и обновления пакетов модулей. [20] : 130–131 

c2nim [ править ]

c2nim — это компилятор исходного кода (транскомпилятор или транспилятор), предназначенный для использования с заголовками C / C++ для создания новых привязок Nim. [40] Результатом является удобочитаемый код Nim, который можно редактировать вручную после процесса перевода.

готовить [ править ]

koch — это сценарий обслуживания, который используется для сборки Nim и предоставления HTML-документации. [41]

нимгреп [ править ]

nimgrep — универсальный инструмент для работы с текстом. Он используется для поиска регулярных выражений, шаблонов привязки и содержимого каталогов, а также может использоваться для замены задач. Он включен для помощи в поиске идентификаторов Nim, не зависящих от стиля. [42]

нимсугест [ править ]

nimsuggest — это инструмент, который помогает любому редактору исходного кода запрашивать .nim исходный файл для получения полезной информации, такой как определение символов или предложения по завершению. [43]

ниминст [ править ]

niminst — это инструмент для создания установщика программы Nim. [44] Он создает установщики .msi для Windows через Inno Setup, а также сценарии установки и удаления для Linux , macOS и Berkeley Software Distribution (BSD).

симпатичный [ править ]

nimpretty — средство улучшения исходного кода, используемое для форматирования кода в соответствии с официальным руководством по стилю Nim. [45]

Завещание [ править ]

Test — это продвинутый автоматический инструмент для запуска модульных тестов для тестов Nim. Используемый при разработке Nim, он предлагает тесты изоляции процессов, генерирует статистику тестовых случаев, поддерживает несколько целей и моделирует пробные прогоны, имеет журналирование, может генерировать отчеты HTML, может пропускать тесты из файла и многое другое.

Другие известные инструменты [ править ]

Некоторые известные инструменты, не включенные в дистрибутив Nim, включают:

выбирать [ править ]

Choosenim был разработан Домиником Пичетой, создателем менеджера пакетов Nimble, как инструмент, позволяющий устанавливать и использовать несколько версий компилятора Nim. Он загружает любую стабильную или разрабатываемую версию компилятора Nim из командной строки, позволяя легко переключаться между ними. [46]

нимпи [ править ]

nimpy — это библиотека, которая обеспечивает удобную интеграцию Python в программы Nim. [47]

пикси [ править ]

pixie — это многофункциональная библиотека 2D-графики, похожая на Cairo или Skia . Он использует SIMD- ускорение для значительного ускорения обработки изображений. Он поддерживает множество форматов изображений, смешивание, маскирование, размытие и может быть объединен с библиотекой boxy для аппаратного ускорения рендеринга.

нимтероп [ править ]

nimterop — это инструмент, предназначенный для автоматизации создания оболочек C/C++, необходимых для интерфейса внешних функций Nim. [48]

Библиотеки [ править ]

Чистые/нечистые библиотеки [ править ]

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

Нечистые библиотеки — это модули кода Nim, которые зависят от внешних библиотек, написанных на других языках программирования, таких как C.

Стандартная библиотека [ править ]

Стандартная библиотека Nim включает модули для всех основных задач, в том числе: [49]

  • Системные и основные модули
  • Коллекции и алгоритмы
  • Обработка строк
  • Управление временем
  • Общие службы операционной системы
  • Математические библиотеки
  • Интернет-протоколы и поддержка
  • Резьба
  • Парсеры
  • Документы
  • XML-обработка
  • Генератор XML и HTML-кода
  • Хеширование
  • Поддержка баз данных (PostgreSQL, MySQL и SQLite)
  • Обертки (Win32 API, POSIX)

Использование других библиотек [ править ]

Программа Nim может использовать любую библиотеку , которую можно использовать в программе C, C++ или JavaScript. Языковые привязки существуют для многих библиотек, включая GTK , [50] [51] Qt QML, [52] wxвиджеты , [53] СДЛ 2 , [54] [55] Каир , [56] OpenGL , [57] WinAPI , [58] zlib , libzip , OpenSSL , Вулкан [59] и КУЛР . [60] Ним работает с базами данных PostgreSQL , MySQL и SQLite .

Существуют инструменты с открытым исходным кодом различной степени поддержки, которые можно использовать для взаимодействия Nim с Lua . [61] Юля , [62] Ржавчина , [63] С# , [64] и Питон [65] языки программирования или транспилировать Nim в TypeScript . [66]

Примеры [ править ]

Привет, мир [ править ]

Программа «Привет, мир!» программа в Ниме:

echo("Hello, World!")
# Procedures can be called with no parentheses
echo "Hello, World!"

Другую версию «Hello World» можно реализовать, вызвав метод write функционировать с stdout транслировать:

stdout.write("Hello, World!\n")
write(stdout, "Hello, World!\n")

Fibonacci[editФибоначчи

Несколько реализаций функции Фибоначчи , демонстрирующие неявные возвраты, параметры по умолчанию, итераторы, рекурсию и циклы while:

proc fib(n: Natural): Natural =
  if n < 2:
    return n
  else:
    return fib(n-1) + fib(n-2)
    
func fib2(n: int, a = 0, b = 1): int =
  if n == 0: a else: fib2(n-1, b, a+b)
  
iterator fib3: int =
  var a = 0
  var b = 1
  while true:
    yield a
    swap a, b
    b += a

Факториал [ править ]

Программа для вычисления факториала положительного целого числа с использованием итеративного подхода, демонстрирующая обработку ошибок try/catch и циклы for:

import std/strutils

var n = 0
try:
  stdout.write "Input positive integer number: "
  n = stdin.readline.parseInt
except ValueError:
  raise newException(ValueError, "You must enter a positive number")

var fact = 1
for i in 2..n:
  fact = fact * i

echo fact

Используя математические вычисления модуля из стандартной библиотеки Nim:

import std/math
echo fac(x)

Переворот строки [ править ]

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

proc reverse(s: string): string =
  for i in countdown(s.high, 0):
    result.add s[i]

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

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

Графический интерфейс пользователя [ править ]

Использование GTK 3 с самоанализом GObject через модуль gintro :

import gintro/[gtk, glib, gobject, gio]

proc appActivate(app: Application) =
  let window = newApplicationWindow(app)
  window.title = "GTK3 application with gobject introspection"
  window.defaultSize = (400, 400)
  showAll(window)

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard run(app)

main()

Для работы этого кода требуется модуль gintro, который не является частью стандартной библиотеки. Для установки модуля gintro и многих других вы можете использовать инструмент nimble, который входит в состав Nim. Чтобы установить модуль gintro с помощью nimble, вы делаете следующее:

nimble install gintro

Парадигмы программирования [ править ]

Функциональное программирование [ править ]

Функциональное программирование поддерживается в Nim посредством первоклассных функций и кода без побочных эффектов через noSideEffect прагма или func ключевое слово. [67] Ним выполнит анализ побочных эффектов и выдаст ошибки компиляции для кода, который не подчиняется контракту об отсутствии побочных эффектов при компиляции с экспериментальной функцией. strictFuncs, который планируется использовать по умолчанию в более поздних версиях. [68]

В отличие от чисто функциональных языков программирования, Nim — это многопарадигмальный язык программирования, поэтому ограничения функционального программирования применяются для каждой функции.

Первоклассные функции [ править ]

Nim поддерживает первоклассные функции , позволяя хранить функции в переменных или передавать их анонимно в качестве параметров, которые будут вызываться другими функциями. [69] std/sugar Модуль предоставляет синтаксический сахар для анонимных функций в объявлениях типов и создании экземпляров.

import std/[sequtils, sugar]

let powersOfTwo = @[1, 2, 4, 8, 16, 32, 64, 128, 256]

proc filter[T](s: openArray[T], pred: T -> bool): seq[T] =
  result = newSeq[T]()
  for i in 0 ..< s.len:
    if pred(s[i]):
      result.add(s[i])

echo powersOfTwo.filter(proc (x: int): bool = x > 32)
# syntactic sugar for the above, provided as a macro from std/sugar
echo powersOfTwo.filter(x => x > 32)

proc greaterThan32(x: int): bool = x > 32
echo powersOfTwo.filter(greaterThan32)

Побочные эффекты [ править ]

Побочные эффекты функций, помеченных значком noSideEffect прагмы проверяются, и компилятор откажется компилировать функции, не соответствующие им. Побочные эффекты в Nim включают мутацию, доступ или модификацию глобального состояния, асинхронный код, многопоточный код и ввод-вывод. Мутация параметров может произойти для функций, принимающих параметры var или ref type: ожидается, что он не сможет скомпилироваться с экспериментальной в настоящее время версией. strictFuncs в будущем. [70] func Ключевое слово представляет ярлык для noSideEffect прагма. [71]

func binarySearch[T](a: openArray[T]; elem: T): int
# is short for...
proc binarySearch[T](a: openArray[T]; elem: T): int {.noSideEffect.}

{.experimental: "strictFuncs".}

type
  Node = ref object
    le, ri: Node
    data: string

func len(n: Node): int =
  # valid: len does not have side effects
  var it = n
  while it != nil:
    inc result
    it = it.ri

func mut(n: Node) =
  let m = n # is the statement that connected the mutation to the parameter
  m.data = "yeah" # the mutation is here
  # Error: 'mut' can have side effects
  # an object reachable from 'n' is potentially mutated

Композиция функций [ править ]

Единый синтаксис вызова функций позволяет создавать цепочки произвольных функций , что, возможно, лучше всего иллюстрируется примером std/sequtils библиотека. [72]

import std/[sequtils, sugar]

let numbers = @[1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]
# a and b are special identifiers in the foldr macro
echo numbers.filter(x => x > 3).deduplicate.foldr(a + b) # 30

Алгебраические типы данных и сопоставление с образцом [ править ]

Nim поддерживает типы продуктов через object тип, а для типов сумм через варианты объектов : необработанные представления тегированных объединений с тегом перечисляемого типа, который должен быть безопасно сопоставлен, прежде чем можно будет получить доступ к полям вариантов. [73] Эти типы могут быть составлены алгебраически . Сопоставление структурных шаблонов доступно, но регулируется макросами в различных сторонних библиотеках. [74]

import std/tables

type
  Value = uint64
  Ident = string
  ExprKind = enum
    Literal, Variable, Abstraction, Application
  Expr = ref object
    case kind: ExprKind
    of Literal:
      litIdent: Value
    of Variable:
      varIdent: Ident
    of Abstraction:
      paramAbs: Ident
      funcAbs: Expr
    of Application:
      funcApp, argApp: Expr

func eval(expr: Expr, context: var Table[Ident, Value]): Value =
  case expr.kind
  of Literal:
    return expr.litIdent
  of Variable:
    return context[expr.varIdent]
  of Application:
    case expr.funcApp.kind
    of Abstraction:
      context[expr.funcApp.paramAbs] = expr.argApp.eval(context)
      return expr.funcAbs.eval(context)
    else:
      raise newException(ValueError, "Invalid expression!")
  else:
    raise newException(ValueError, "Invalid expression!")

Объектно-ориентированное программирование [ править ]

Несмотря на то, что Nim в первую очередь является императивным и функциональным языком, он поддерживает различные функции для реализации объектно-ориентированных парадигм. [75] [76]

Подтипирование и наследование [ править ]

Nim поддерживает ограниченное наследование с помощью ref objects и of ключевое слово. [76] Чтобы включить наследование, любой исходный («корневой») объект должен наследовать от RootObj. Наследование имеет ограниченное применение в идиоматическом коде Nim: за заметным исключением исключений. [77]

type Animal = ref object of RootObj
  name: string
  age: int
type Dog = ref object of Animal
type Cat = ref object of Animal

var animals: seq[Animal] = @[]
animals.add(Dog(name: "Sparky", age: 10))
animals.add(Cat(name: "Mitten", age: 10))

for a in animals:
  assert a of Animal

Отношения подтипирования также можно запросить с помощью of ключевое слово. [76]

Вызовы методов и инкапсуляция [ править ]

Nim Унифицированный синтаксис вызова функций позволяет вызывать обычные функции с синтаксисом, аналогичным вызову методов в других языках программирования. Это функционально для «геттеров»: и Nim также предоставляет синтаксис для создания таких «сеттеров». Объекты могут быть общедоступными для каждого поля, обеспечивая инкапсуляцию.

type Socket* = ref object
  host: int # private, lacks export marker

# getter of host address
proc host*(s: Socket): int = s.host

# setter of host address
proc `host=`*(s: var Socket, value: int) =
  s.host = value

var s: Socket
new s
assert s.host == 0  # same as host(s), s.host()
s.host = 34         # same as `host=`(s, 34)

Динамическая отправка [ править ]

Статическая диспетчеризация является предпочтительной, более производительной и стандартной даже среди подпрограмм, ориентированных на методы. [76] Тем не менее, если желательна динамическая диспетчеризация, Nim предоставляет method Ключевое слово для включения динамической отправки ссылочных типов.

import std/strformat

type
  Person = ref object of RootObj
    name: string
  Student = ref object of Person
  Teacher = ref object of Person

method introduce(a: Person) =
  raise newException(CatchableError, "Method without implementation override")

method introduce(a: Student) =
  echo &"I am a student named {a.name}!"

method introduce(a: Teacher) =
  echo &"I am a teacher named {a.name}!"
  
let people: seq[Person] = @[Teacher(name: "Alice"), Student(name: "Bob")]
for person in people:
  person.introduce()

Metaprogramming [ edit ]

Шаблоны [ править ]

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

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

Дженерики [ править ]

Nim поддерживает как ограниченное, так и неограниченное обобщенное программирование. Обобщенные шаблоны можно использовать в процедурах, шаблонах и макросах. Неограниченные общие идентификаторы ( T в этом примере) определяются после имени подпрограммы в квадратных скобках. Ограниченные дженерики можно размещать в универсальных идентификаторах или непосредственно в параметрах.

proc addThese[T](a, b: T): T = a + b
echo addThese(1, 2) # 3 (of int type)
echo addThese(uint8 1, uint8 2) # 3 (of uint8 type)

# we don't want to risk subtracting unsigned numbers!
proc subtractThese[T: SomeSignedInt | float](a, b: T): T = a - b
echo subtractThese(1, 2) # -1 (of int type)

import std/sequtils

# constrained generics can also be directly on the parameters
proc compareThese[T](a, b: string | seq[T]): bool =
  for (i, j) in zip(a, b):
    if i != j:
      return false

Можно дополнительно уточнить, какие типы будет принимать процедура, указав класс типа (в приведенном выше примере SomeSignedInt). [78]

Макросы [ править ]

Макросы могут переписывать части кода во время компиляции. Макросы Nim являются мощными и могут работать с абстрактным синтаксическим деревом до или после семантической проверки. [79]

Вот простой пример, в котором создается макрос для двойного вызова кода:

import std/macros

macro twice(arg: untyped): untyped =
  result = quote do:
    `arg`
    `arg`

twice echo "Hello world!"

twice Макрос в этом примере принимает в качестве входных данных оператор echo в форме абстрактного синтаксического дерева. В этом примере мы решили вернуть это синтаксическое дерево без каких-либо манипуляций с ним. Но делаем это дважды, отсюда и название макроса. В результате код переписывается макросом, чтобы во время компиляции он выглядел следующим образом:

echo "Hello world!"
echo "Hello world!"

Интерфейс внешних функций (FFI) [ править ]

FFI Nim используется для вызова функций, написанных на других языках программирования, в которые он может компилироваться. Это означает, что в исходном коде Nim можно использовать библиотеки, написанные на C, C++, Objective-C и JavaScript. Следует помнить, что библиотеки JavaScript и C, C++ или Objective-C не могут быть объединены в одной программе, поскольку они не так совместимы с JavaScript, как друг с другом. И C++, и Objective-C основаны на C и совместимы с ним, но JavaScript несовместим как динамический клиентский веб-язык. [20] : 226 

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

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

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

В этом коде printf функция импортируется в Nim и затем используется.

Базовый пример использования console.log непосредственно для цели компиляции JavaScript :

proc log(args: any) {.importjs: "console.log(@)", varargs.}
log(42, "z", true, 3.14)

Код JavaScript, созданный компилятором Nim, может быть выполнен с помощью Node.js или веб-браузера.

Параллелизм [ править ]

Чтобы активировать поддержку потоков в Nim, программу следует скомпилировать с помощью --threads:on аргумент командной строки. Каждый поток имеет отдельную кучу для сбора мусора, а совместное использование памяти ограничено, что повышает эффективность и предотвращает возникновение состояний гонки между потоками.

import std/locks

var
  thr: array[0..4, Thread[tuple[a,b: int]]]
  L: Lock

proc threadFunc(interval: tuple[a,b: int]) {.thread.} =
  for i in interval.a..interval.b:
    acquire(L) # lock stdout
    echo i
    release(L)

initLock(L)

for i in 0..high(thr):
  createThread(thr[i], threadFunc, (i*10, i*10+5))
joinThreads(thr)

У Нима также есть channels модуль, упрощающий передачу данных между потоками.

import std/os

type
  CalculationTask = object
    id*: int
    data*: int

  CalculationResult = object
    id*: int
    result*: int

var task_queue: Channel[CalculationTask]
var result_queue: Channel[CalculationResult]

proc workerFunc() {.thread.} =
  result_queue.open()

  while true:
    var task = task_queue.recv()
    result_queue.send(CalculationResult(id: task.id, result: task.data * 2))

var workerThread: Thread[void]
createThread(workerThread, workerFunc)

task_queue.open()
task_queue.send(CalculationTask(id: 1, data: 13))
task_queue.send(CalculationTask(id: 2, data: 37))

while true:
  echo "got result: ", repr(result_queue.recv())

Параллельность [ править ]

Асинхронный ввод-вывод поддерживается либо через asyncdispatch модуль в стандартной библиотеке или во внешней chronos библиотека. [80] Обе библиотеки добавляют синтаксис async/await через систему макросов без необходимости специальной языковой поддержки. Пример асинхронного HTTP- сервера:

import std/[asynchttpserver, asyncdispatch]
# chronos could also be alternatively used in place of asyncdispatch,
# with no other changes.

var server = newAsyncHttpServer()
proc cb(req: Request) {.async.} =
  await req.respond(Http200, "Hello World")

waitFor server.serve(Port(8080), cb)

Сообщество [ править ]

Онлайн [ править ]

У Нима есть активное сообщество на самостоятельном и самостоятельно разработанном официальном форуме. [81] Кроме того, проект использует репозиторий Git, систему отслеживания ошибок, систему отслеживания RFC и вики, размещенные на GitHub , где сообщество взаимодействует с языком. [82] Существуют также официальные онлайн-чаты, соединенные между IRC , Matrix , Discord , Gitter и Telegram . [83]

Соглашения [ править ]

Первая конференция Nim, NimConf, состоялась 20 июня 2020 года. Из-за COVID-19 она проводилась в цифровом формате с открытым приглашением к выступлениям участников в виде видеороликов на YouTube . [84] Конференция началась с обзоров языка, сделанных разработчиками Nim Андреасом Румпфом и Домиником Пичетой. Темы презентаций включали разговоры о веб-фреймворках, мобильной разработке , устройствах Интернета вещей (IoT) и разработке игр , включая доклад о написании Nim для Game Boy Advance . [85] NimConf 2020 доступен в виде плейлиста на YouTube. [86] NimConf 2021 состоялась в следующем году, также прошла в цифровом формате и включала в себя доклады о разработке игр , REPL , операционных системах реального времени , Nim в отрасли, объектно-реляционном отображении (ORM), языковом дизайне и графических библиотеках . [87]

Помимо официальных конференций, Ним выступал на различных других конференциях. Презентация Nim была представлена ​​на конференции O'Reilly Open Source Convention (OSCON) в 2015 году. [88] [89] [90] Четыре спикера представляли Ним на FOSDEM 2020, включая создателя языка Андреаса Румпфа. [91] На FOSDEM 2022 компания Nim организовала собственную комнату для разработчиков практически из-за пандемии COVID-19 . [92] Были проведены переговоры по параллелизму , встроенному программированию , программированию для графических процессоров , сущностно-компонентным системам , разработке игр , механизмам правил , с Python взаимодействию и метапрограммированию . [93]

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

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

  1. ^ «Соавторы nim-lang/Nim» . Гитхаб . Проверено 23 марта 2022 г.
  2. ^ https://github.com/nim-lang/Nim/releases/tag/v2.0.4 . {{cite web}}: Отсутствует или пусто |title= ( помощь )
  3. ^ «Ним своим примером» . Гитхаб . Проверено 20 июля 2014 г.
  4. ^ Караджов, Захари; Станимиров, Борислав (2014). Метапрограммирование с Нимродом . ВарнаКонф (на болгарском языке) . Проверено 27 июля 2014 г.
  5. ^ «Упаковка Нима» . Проверено 23 марта 2022 г.
  6. ^ «Установить Ним» . Проверено 12 октября 2018 г.
  7. ^ "копирование.txt" . Гитхаб .
  8. ^ Перейти обратно: а б Румпф, Андреас (19 октября 2017 г.). «Ним без GC» . Размышления Арака . Проверено 1 сентября 2020 г.
  9. ^ Перейти обратно: а б Румпф, Андреас (11 февраля 2014 г.). «Нимрод: новый язык системного программирования» . Журнал доктора Добба . Проверено 20 июля 2014 г.
  10. ^ «Язык программирования Ним» . Nim-lang.org . Проверено 20 июля 2014 г.
  11. ^ "ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ" . nim-lang.org . Проверено 27 марта 2015 г.
  12. ^ Керер, Аарон (akehrer) (5 января 2015 г.). «Синтаксис имени» . Гитхаб . Проверено 5 января 2015 г.
  13. ^ Перейти обратно: а б с «Руководство Нима» . Nim-lang.org . Проверено 20 июля 2014 г.
  14. ^ «Презентация Стрейнгелупа Нима» . Архивировано из оригинала 13 июля 2014 г. Проверено 30 апреля 2015 г.
  15. ^ «Управление памятью Нима» . nim-lang.org . Проверено 17 августа 2023 г.
  16. ^ Бинсток, Эндрю (07 января 2014 г.). «Взлет и падение языков в 2013 году» . Журнал доктора Добба . Проверено 8 октября 2018 г.
  17. ^ Руководство пользователя компилятора Nim
  18. ^ Перейти обратно: а б Сиека, Яцек (18 июля 2020 г.), arnetheduck/nlvm , получено 21 июля 2020 г.
  19. ^ «Ним Релизы» . Проект Ним . Проверено 26 января 2020 г.
  20. ^ Перейти обратно: а б с д Пичета, Доминик (2017). Ним в действии . Публикации Мэннинга. ISBN  978-1617293436 .
  21. ^ «Источники Нима Паскаля» . Гитхаб . Проверено 5 апреля 2013 г.
  22. ^ «Новости» . Nim-lang.org . Архивировано из оригинала 26 июня 2016 г. Проверено 11 июня 2016 г.
  23. ^ «Соавторы» . Гитхаб . Проверено 5 апреля 2013 г.
  24. ^ Пичета, Доминик (29 декабря 2014 г.). «Выпущена версия 0.10.2» . Nim-lang.org . Проверено 17 октября 2018 г.
  25. ^ «Выпущен Ним v2.0» . Язык программирования Ним . Проверено 17 августа 2023 г.
  26. ^ Егулалп, Сердар (16 января 2017 г.). «Язык Nim основан на лучшем из Python, Rust, Go и Lisp» . Инфомир .
  27. ^ Интервью с создателем языка Nim Андреасом Румпфом , получено 15 октября 2023 г.
  28. ^ «Руководство Nim: Синтаксис вызова методов» . Проверено 12 октября 2018 г.
  29. ^ «Руководство Нима: Равенство идентификаторов» . nim-lang.org . Проверено 17 августа 2023 г.
  30. ^ Пичета, Доминик (dom96); Уэтерфордшир, Биллингсли (птичья пасть); Фельсинг, Деннис (защита); Рааф, Ганс (одерват); Данн, Кристофер (cdunn2001); wizzardx (25 октября 2017 г.). «Советы и рекомендации» . Гитхаб . Проверено 17 октября 2018 г. {{cite web}}: CS1 maint: числовые имена: список авторов ( ссылка )
  31. ^ Румпф, Андреас (15 января 2014 г.). Нимрод: новый подход к метапрограммированию . ИнфоQ . Событие происходит в 2:23 . Проверено 20 июля 2014 г.
  32. ^ Румпф, Андреас (12 октября 2018 г.). «Ним Компиляция» . Гитхаб . Проверено 17 октября 2018 г.
  33. ^ Перейти обратно: а б с «Руководство пользователя компилятора Nim» .
  34. ^ «Управление памятью Нима» . nim-lang.org . Проверено 17 августа 2023 г.
  35. ^ «Введение в ARC/ORC в Ниме» . Язык программирования Ним . Проверено 17 августа 2023 г.
  36. ^ «ORC – Преимущество через алгоритмы» . Язык программирования Ним . Проверено 17 августа 2023 г.
  37. ^ «Выпущен Ним v2.0» . Язык программирования Ним . Проверено 17 августа 2023 г.
  38. ^ «шустрый» . Гитхаб . Проверено 12 октября 2018 г.
  39. ^ «Выпуск Нима v0.12.0» . Гитхаб . Проверено 28 ноября 2020 г.
  40. ^ "c2ним" . Гитхаб . Проверено 12 октября 2018 г.
  41. ^ «Скрипт обслуживания Нима» . nim-lang.org . Проверено 16 ноября 2021 г.
  42. ^ «Руководство пользователя nimgrep» . nim-lang.org . Проверено 16 ноября 2021 г.
  43. ^ «Руководство по интеграции Nim IDE» . nim-lang.org . Проверено 16 ноября 2021 г.
  44. ^ «Руководство пользователя niminst» . nim-lang.org . Проверено 16 ноября 2021 г.
  45. ^ «Инструменты, доступные в Nim» . nim-lang.org . 2021-10-19. Архивировано из оригинала 9 мая 2015 г. Проверено 18 февраля 2022 г.
  46. ^ «выбирай» . Гитхаб . Проверено 12 октября 2018 г.
  47. ^ Glukhov, Yuriy (2021-11-12), nimpy , retrieved 2021-11-16
  48. ^ нимтероп/нимтероп , нимтероп, 12 ноября 2021 г. , получено 16 ноября 2021 г.
  49. ^ Стандартная библиотека Нима
  50. ^ Установка , Язык программирования Nim, 25 сентября 2021 г. , получено 16 ноября 2021 г.
  51. ^ Стефан Салевски (15 ноября 2021 г.), Привязки GTK4 и GTK3 высокого уровня для языка программирования Nim , получено 16 ноября 2021 г.
  52. ^ "НимКмл" . Гитхаб . 2022-11-10.
  53. ^ «ВхНим» . Гитхаб . 2022-11-29.
  54. ^ SDL2 для Nim , Язык программирования Nim, 26 октября 2021 г. , получено 16 ноября 2021 г.
  55. ^ Arabadzhi, Vladimir (2021-11-15), sdl2_nim 2.0.14.2 , retrieved 2021-11-16
  56. ^ Каир , язык программирования Nim, 5 октября 2021 г. , получено 16 ноября 2021 г.
  57. ^ opengl , Язык программирования Nim, 14 ноября 2021 г. , получено 16 ноября 2021 г.
  58. ^ Уорд (15 ноября 2021 г.), Виним , получено 16 ноября 2021 г.
  59. ^ «Вулканим» . Гитхаб . 30 сентября 2022 г.
  60. ^ «Стандартная библиотека Нима» . Документация Ним . Архивировано из оригинала 06 апреля 2015 г. Проверено 4 апреля 2015 г.
  61. ^ Лим, Эндрю (снаружи) (17 октября 2018 г.). "нимЛУА " Гитхаб . Получено 1 октября 2018 г.
  62. ^ "НимДжЛ" . Гитхаб . 24 августа 2022 г.
  63. ^ «Нбиндген» . Гитхаб . 17.11.2022.
  64. ^ "cs2ним" . Гитхаб . 10.10.2022.
  65. ^ Glukhov, Yuriy (2020-07-20), yglukhov/nimpy , retrieved 2020-07-21
  66. ^ "ц2ним" . Гитхаб . 21 ноября 2022 г.
  67. ^ «Руководство Нима» . nim-lang.org . Проверено 10 июля 2021 г.
  68. ^ «Форум Nim: Обновления по строгим функциям» . forum.nim-lang.org . Проверено 17 августа 2023 г.
  69. ^ «Ним на примере — функции первого класса» .
  70. ^ «Экспериментальные возможности Нима: строгие функции» .
  71. ^ «Руководство Нима: Func» .
  72. ^ "стандарт/секвилы" . nim-lang.org . Проверено 17 августа 2023 г.
  73. ^ «Руководство Нима: Варианты объектов» . nim-lang.org . Проверено 17 августа 2023 г.
  74. ^ "источник/слияние/сопоставление" . nim-lang.github.io . Проверено 17 августа 2023 г.
  75. ^ «Учебное пособие по Nim (Часть II): Объектно-ориентированное программирование» . nim-lang.org . Проверено 17 августа 2023 г.
  76. ^ Перейти обратно: а б с д «Ним на примере — объектно-ориентированное программирование» . nim-by-example.github.io . Проверено 17 августа 2023 г.
  77. ^ «система/исключения» . nim-lang.org . Проверено 17 августа 2023 г.
  78. ^ «Руководство Nim: Классы типов» . nim-lang.org . Проверено 21 июля 2020 г.
  79. ^ «Урок Нима (Часть III)» . nim-lang.org . Проверено 17 августа 2023 г.
  80. ^ Chronos — эффективная библиотека для асинхронного программирования , Статус, 14 августа 2023 г. , получено 17 августа 2023 г.
  81. ^ «Ним Форум» . nim-lang.org . Проверено 4 мая 2015 г.
  82. ^ «Основное хранилище исходного кода и система отслеживания ошибок» . Гитхаб . Проверено 4 мая 2015 г.
  83. ^ "Сообщество" . Язык программирования Ним . Проверено 17 августа 2023 г.
  84. ^ «Онлайн-конференция Ним 2020» . Ним . Проверено 28 ноября 2020 г.
  85. ^ «НимКонф 2020» . Ним . Проверено 17 августа 2023 г.
  86. ^ «Плейлист NimConf 2020» . Ютуб . Проверено 28 ноября 2020 г.
  87. ^ «НимКонф 2021» . НимКонф 2021 . Проверено 17 августа 2023 г.
  88. ^ «Ним на OSCON 2015» . Конвенция О'Рейли по открытому исходному коду (OSCON) . О'Рейли Медиа. 20 июля 2015 г. Архивировано из оригинала 6 октября 2015 г. Проверено 17 октября 2018 г.
  89. ^ Румпф, Андреас; Шварц, Джейсон; Харрисон, Мэтт. «Основные языки: Nim, Scala, Python» . О'Рейли . О'Рейли Медиа . Проверено 17 октября 2018 г.
  90. ^ Румпф, Андреас (26 октября 2015 г.). OSCON 2015 – Ним: Обзор . Ютуб (видео) . Проверено 12 октября 2018 г.
  91. ^ "События" . fosdem.org . Проверено 17 февраля 2020 г.
  92. ^ «Ним Деврум на FOSDEM 2022 — призыв к участию» . Язык программирования Ним . Проверено 17 августа 2023 г.
  93. ^ «Комната разработки языка программирования Nim» . archive.fosdem.org . Проверено 17 августа 2023 г.

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: e695a05914593d4a8435a5f4cfa1124f__1713859620
URL1:https://arc.ask3.ru/arc/aa/e6/4f/e695a05914593d4a8435a5f4cfa1124f.html
Заголовок, (Title) документа по адресу, URL1:
Nim (programming language) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)