Ним (язык программирования)
В этой статье отсутствует информация Nim об истории , языковом дизайне , инструментах и парадигмах . ( июнь 2019 г. ) |
Эта статья может быть слишком технической для понимания большинства читателей . ( январь 2024 г. ) |
Парадигмы | Мультипарадигмальность : скомпилированная , параллельная , процедурная , императивная , функциональная , объектно-ориентированная , мета. |
---|---|
Разработано | Андреас Румпф |
Разработчик | Команда Ним Ланга [1] |
Впервые появился | 2008 год |
Стабильная версия | 2.0.4 [2]
/ 16 апреля 2024 г |
Дисциплина набора текста | Статический , [3] сильный , [4] предполагаемый , структурный |
Объем | Лексический |
Язык реализации | Ним (самостоятельное размещение) |
Платформа | IA-32 , x86-64 , ARM , Aarch64 , RISC-V , PowerPC ... [5] |
ТЫ | Кросс-платформенный [6] |
Лицензия | МОЯ лицензия [7] |
Расширения имен файлов | .ним, .нимс, .нимбл |
Веб-сайт | просто ним |
Под влиянием | |
Ада , Модуль-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 г. [update], Nim компилируется в C, C++, JavaScript, Objective-C, [17] и ЛЛВМ. [18]
История [ править ]
Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( февраль 2018 г. ) |
Ветвь | Версия | Дата выпуска [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 | |
Легенда: Старая версия Старая версия, все еще поддерживается Последняя версия | ||
Для каждой ветки 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]
Языковой дизайн [ править ]
Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( февраль 2018 г. ) |
Синтаксис [ править ]
Синтаксис 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]
На Нима повлияли специфические характеристики существующих языков, в том числе следующие:
- Модуль-3 : отслеживаемые и неотслеживаемые указатели
- Object Pascal : безопасные наборы битов ( набор символов ), синтаксис оператора case, различные имена типов и имена файлов в стандартной библиотеке.
- Ada : типы поддиапазонов, отдельный тип, безопасные варианты – объекты Case.
- C++ : перегрузка операторов , универсальное программирование
- Python : правило офсайда
- Lisp : макросистема , AST манипулирование , гомоиконичность.
- Оберон : экспортный маркер
- C# : async/await , лямбда-макросы
- ParaSail : программирование без указателей [8]
Унифицированный синтаксис вызова функций [ править ]
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 effectsvar 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 или веб-браузера.
Параллелизм [ править ]
Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( июнь 2019 г. ) |
Чтобы активировать поддержку потоков в 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())
Параллельность [ править ]
Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( июнь 2019 г. ) |
Асинхронный ввод-вывод поддерживается либо через 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]
См. также [ править ]
- Си (язык программирования)
- С++ (язык программирования)
- Кристалл (язык программирования)
- D (язык программирования)
- Го (язык программирования)
- Руст (язык программирования)
- Жирный указатель
Ссылки [ править ]
- ^ «Соавторы nim-lang/Nim» . Гитхаб . Проверено 23 марта 2022 г.
- ^ https://github.com/nim-lang/Nim/releases/tag/v2.0.4 .
{{cite web}}
: Отсутствует или пусто|title=
( помощь ) - ^ «Ним своим примером» . Гитхаб . Проверено 20 июля 2014 г.
- ^ Караджов, Захари; Станимиров, Борислав (2014). Метапрограммирование с Нимродом . ВарнаКонф (на болгарском языке) . Проверено 27 июля 2014 г.
- ^ «Упаковка Нима» . Проверено 23 марта 2022 г.
- ^ «Установить Ним» . Проверено 12 октября 2018 г.
- ^ "копирование.txt" . Гитхаб .
- ^ Перейти обратно: а б Румпф, Андреас (19 октября 2017 г.). «Ним без GC» . Размышления Арака . Проверено 1 сентября 2020 г.
- ^ Перейти обратно: а б Румпф, Андреас (11 февраля 2014 г.). «Нимрод: новый язык системного программирования» . Журнал доктора Добба . Проверено 20 июля 2014 г.
- ^ «Язык программирования Ним» . Nim-lang.org . Проверено 20 июля 2014 г.
- ^ "ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ" . nim-lang.org . Проверено 27 марта 2015 г.
- ^ Керер, Аарон (akehrer) (5 января 2015 г.). «Синтаксис имени» . Гитхаб . Проверено 5 января 2015 г.
- ^ Перейти обратно: а б с «Руководство Нима» . Nim-lang.org . Проверено 20 июля 2014 г.
- ^ «Презентация Стрейнгелупа Нима» . Архивировано из оригинала 13 июля 2014 г. Проверено 30 апреля 2015 г.
- ^ «Управление памятью Нима» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ Бинсток, Эндрю (07 января 2014 г.). «Взлет и падение языков в 2013 году» . Журнал доктора Добба . Проверено 8 октября 2018 г.
- ^ Руководство пользователя компилятора Nim
- ^ Перейти обратно: а б Сиека, Яцек (18 июля 2020 г.), arnetheduck/nlvm , получено 21 июля 2020 г.
- ^ «Ним Релизы» . Проект Ним . Проверено 26 января 2020 г.
- ^ Перейти обратно: а б с д Пичета, Доминик (2017). Ним в действии . Публикации Мэннинга. ISBN 978-1617293436 .
- ^ «Источники Нима Паскаля» . Гитхаб . Проверено 5 апреля 2013 г.
- ^ «Новости» . Nim-lang.org . Архивировано из оригинала 26 июня 2016 г. Проверено 11 июня 2016 г.
- ^ «Соавторы» . Гитхаб . Проверено 5 апреля 2013 г.
- ^ Пичета, Доминик (29 декабря 2014 г.). «Выпущена версия 0.10.2» . Nim-lang.org . Проверено 17 октября 2018 г.
- ^ «Выпущен Ним v2.0» . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ Егулалп, Сердар (16 января 2017 г.). «Язык Nim основан на лучшем из Python, Rust, Go и Lisp» . Инфомир .
- ^ Интервью с создателем языка Nim Андреасом Румпфом , получено 15 октября 2023 г.
- ^ «Руководство Nim: Синтаксис вызова методов» . Проверено 12 октября 2018 г.
- ^ «Руководство Нима: Равенство идентификаторов» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ Пичета, Доминик (dom96); Уэтерфордшир, Биллингсли (птичья пасть); Фельсинг, Деннис (защита); Рааф, Ганс (одерват); Данн, Кристофер (cdunn2001); wizzardx (25 октября 2017 г.). «Советы и рекомендации» . Гитхаб . Проверено 17 октября 2018 г.
{{cite web}}
: CS1 maint: числовые имена: список авторов ( ссылка ) - ^ Румпф, Андреас (15 января 2014 г.). Нимрод: новый подход к метапрограммированию . ИнфоQ . Событие происходит в 2:23 . Проверено 20 июля 2014 г.
- ^ Румпф, Андреас (12 октября 2018 г.). «Ним Компиляция» . Гитхаб . Проверено 17 октября 2018 г.
- ^ Перейти обратно: а б с «Руководство пользователя компилятора Nim» .
- ^ «Управление памятью Нима» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ «Введение в ARC/ORC в Ниме» . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ «ORC – Преимущество через алгоритмы» . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ «Выпущен Ним v2.0» . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ «шустрый» . Гитхаб . Проверено 12 октября 2018 г.
- ^ «Выпуск Нима v0.12.0» . Гитхаб . Проверено 28 ноября 2020 г.
- ^ "c2ним" . Гитхаб . Проверено 12 октября 2018 г.
- ^ «Скрипт обслуживания Нима» . nim-lang.org . Проверено 16 ноября 2021 г.
- ^ «Руководство пользователя nimgrep» . nim-lang.org . Проверено 16 ноября 2021 г.
- ^ «Руководство по интеграции Nim IDE» . nim-lang.org . Проверено 16 ноября 2021 г.
- ^ «Руководство пользователя niminst» . nim-lang.org . Проверено 16 ноября 2021 г.
- ^ «Инструменты, доступные в Nim» . nim-lang.org . 2021-10-19. Архивировано из оригинала 9 мая 2015 г. Проверено 18 февраля 2022 г.
- ^ «выбирай» . Гитхаб . Проверено 12 октября 2018 г.
- ^ Glukhov, Yuriy (2021-11-12), nimpy , retrieved 2021-11-16
- ^ нимтероп/нимтероп , нимтероп, 12 ноября 2021 г. , получено 16 ноября 2021 г.
- ^ Стандартная библиотека Нима
- ^ Установка , Язык программирования Nim, 25 сентября 2021 г. , получено 16 ноября 2021 г.
- ^ Стефан Салевски (15 ноября 2021 г.), Привязки GTK4 и GTK3 высокого уровня для языка программирования Nim , получено 16 ноября 2021 г.
- ^ "НимКмл" . Гитхаб . 2022-11-10.
- ^ «ВхНим» . Гитхаб . 2022-11-29.
- ^ SDL2 для Nim , Язык программирования Nim, 26 октября 2021 г. , получено 16 ноября 2021 г.
- ^ Arabadzhi, Vladimir (2021-11-15), sdl2_nim 2.0.14.2 , retrieved 2021-11-16
- ^ Каир , язык программирования Nim, 5 октября 2021 г. , получено 16 ноября 2021 г.
- ^ opengl , Язык программирования Nim, 14 ноября 2021 г. , получено 16 ноября 2021 г.
- ^ Уорд (15 ноября 2021 г.), Виним , получено 16 ноября 2021 г.
- ^ «Вулканим» . Гитхаб . 30 сентября 2022 г.
- ^ «Стандартная библиотека Нима» . Документация Ним . Архивировано из оригинала 06 апреля 2015 г. Проверено 4 апреля 2015 г.
- ^ Лим, Эндрю (снаружи) (17 октября 2018 г.). "нимЛУА " Гитхаб . Получено 1 октября 2018 г.
- ^ "НимДжЛ" . Гитхаб . 24 августа 2022 г.
- ^ «Нбиндген» . Гитхаб . 17.11.2022.
- ^ "cs2ним" . Гитхаб . 10.10.2022.
- ^ Glukhov, Yuriy (2020-07-20), yglukhov/nimpy , retrieved 2020-07-21
- ^ "ц2ним" . Гитхаб . 21 ноября 2022 г.
- ^ «Руководство Нима» . nim-lang.org . Проверено 10 июля 2021 г.
- ^ «Форум Nim: Обновления по строгим функциям» . forum.nim-lang.org . Проверено 17 августа 2023 г.
- ^ «Ним на примере — функции первого класса» .
- ^ «Экспериментальные возможности Нима: строгие функции» .
- ^ «Руководство Нима: Func» .
- ^ "стандарт/секвилы" . nim-lang.org . Проверено 17 августа 2023 г.
- ^ «Руководство Нима: Варианты объектов» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ "источник/слияние/сопоставление" . nim-lang.github.io . Проверено 17 августа 2023 г.
- ^ «Учебное пособие по Nim (Часть II): Объектно-ориентированное программирование» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ Перейти обратно: а б с д «Ним на примере — объектно-ориентированное программирование» . nim-by-example.github.io . Проверено 17 августа 2023 г.
- ^ «система/исключения» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ «Руководство Nim: Классы типов» . nim-lang.org . Проверено 21 июля 2020 г.
- ^ «Урок Нима (Часть III)» . nim-lang.org . Проверено 17 августа 2023 г.
- ^ Chronos — эффективная библиотека для асинхронного программирования , Статус, 14 августа 2023 г. , получено 17 августа 2023 г.
- ^ «Ним Форум» . nim-lang.org . Проверено 4 мая 2015 г.
- ^ «Основное хранилище исходного кода и система отслеживания ошибок» . Гитхаб . Проверено 4 мая 2015 г.
- ^ "Сообщество" . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ «Онлайн-конференция Ним 2020» . Ним . Проверено 28 ноября 2020 г.
- ^ «НимКонф 2020» . Ним . Проверено 17 августа 2023 г.
- ^ «Плейлист NimConf 2020» . Ютуб . Проверено 28 ноября 2020 г.
- ^ «НимКонф 2021» . НимКонф 2021 . Проверено 17 августа 2023 г.
- ^ «Ним на OSCON 2015» . Конвенция О'Рейли по открытому исходному коду (OSCON) . О'Рейли Медиа. 20 июля 2015 г. Архивировано из оригинала 6 октября 2015 г. Проверено 17 октября 2018 г.
- ^ Румпф, Андреас; Шварц, Джейсон; Харрисон, Мэтт. «Основные языки: Nim, Scala, Python» . О'Рейли . О'Рейли Медиа . Проверено 17 октября 2018 г.
- ^ Румпф, Андреас (26 октября 2015 г.). OSCON 2015 – Ним: Обзор . Ютуб (видео) . Проверено 12 октября 2018 г.
- ^ "События" . fosdem.org . Проверено 17 февраля 2020 г.
- ^ «Ним Деврум на FOSDEM 2022 — призыв к участию» . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ «Комната разработки языка программирования Nim» . archive.fosdem.org . Проверено 17 августа 2023 г.
Внешние ссылки [ править ]
- Официальный сайт
- Nim on GitHub
- Информация о Ниме при переполнении стека
- Компьютерное программирование на языке программирования Nim. Нежное введение Стефана Салевского.
- программное обеспечение 2008 года
- Параллельные языки программирования
- Кроссплатформенное программное обеспечение
- Функциональные языки
- Мультипарадигмальные языки программирования
- Процедурные языки программирования
- Языки программирования
- Языки программирования, созданные в 2008 году.
- Программное обеспечение, использующее лицензию MIT
- Компиляторы исходного кода
- Статически типизированные языки программирования
- Языки системного программирования