Ним (язык программирования)
В этой статье отсутствует информация Nim об истории , языковом дизайне , инструментах и парадигмах . ( июнь 2019 г. ) |
![]() | Эта статья может быть слишком технической для понимания большинства читателей . ( январь 2024 г. ) |
![]() Логотип короны Нима | |
Парадигмы | Мультипарадигмальность : скомпилированная , параллельная , процедурная , императивная , функциональная , объектно-ориентированная , мета. |
---|---|
Разработано | Андреас Румпф |
Разработчик | Команда Ним Ланга [1] |
Впервые появился | 2008 год |
Стабильная версия | 2.0.4 [2] ![]() |
Дисциплина набора текста | Статический , [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]
# Давайте объявим функцию, которая принимает число любого типа и отображает его двойное значение
# В Nim функции с побочным эффектом называются "proc"
proc timesTwo ( i : SomeNumber ) =
echo i * 2
# Давайте напишем еще одну функцию, которая принимает любой порядковый тип и возвращает
# двойное значение входных данных в исходном типе, если это число;
# или в противном случае возвращает сам ввод.
# Мы используем общий тип Type(T) и уточняем, что это может быть только порядковая
функция дваждыIfIsNumber [ T : SomeOrdinal ] ( i : T ): T =
When T is SomeNumber : # `When` - это `if`, оцениваемый во время компиляции
result = i * 2 # Вы также можете написать `return i * 2`
else :
# Если порядковый номер не является числом, он преобразуется в int,
# умножается на два и снова преобразуется в основанный на нем тип
result = ( i .инт * 2 ) . Т
echo twiceIfIsNumber(67) # Passes an int to the function
дважды повторить эхоЕслииснумбер(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 "Привет, мир"
echo ( "Привет, мир" )
"Привет, мир" . echo ()
«привет, мир» . echo
echo ( «привет» , «мир» )
, «привет» . эхо ( «мир» )
«привет» . эхо "мир"
Равенство идентификаторов [ править ]
Ним почти полностью нечувствителен к стилю; два идентификатора считаются равными, если они различаются только заглавными буквами и символами подчеркивания, при условии, что первые символы идентичны. Это сделано для того, чтобы обеспечить смешивание стилей в разных библиотеках: один пользователь может написать библиотеку, используя в качестве соглашения Snake_case, и другой пользователь может без проблем использовать ее в стиле CamelCase. [29]
const useHttps = true
утверждать useHttps == useHttps
утверждать useHTTPS == useHttps
утверждать use_https == useHttps
Стоппинг [ править ]
Функция ограничения позволяет использовать любое имя для переменных или функций, даже если имена являются зарезервированными словами для ключевых слов. Примером ограничения является возможность определить переменную с именем if
, не конфликтуя с ключевым словом if
. Реализация этого в Nim достигается с помощью обратных кавычек, что позволяет использовать любое зарезервированное слово в качестве идентификатора. [30]
type Type = object
` int `: int
let ` object ` = Type (` int `: 9 )
Assert ` object ` is Тип
Assert ` object `.` int ` == 9
var ` var ` = 42
let ` let ` = 8
Assert ` var` + ` let` == 50
const ` assert` утверждение = true
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!" )
# Процедуры можно вызывать без скобок
echo "Hello, World!"
Другую версию «Hello World» можно реализовать, вызвав метод write
функционировать с 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 )
итератор fib3 : int =
var a = 0
var b = 1
while true :
дать своп
, a b b
+ = a
Факториал [ править ]
Программа для вычисления факториала положительного целого числа с использованием итеративного подхода, демонстрирующая обработку ошибок try/catch и циклы for:
импортировать std / strutils
var n = 0
попробовать :
stdout . напишите «Введите положительное целое число:»
n = stdin . читать строку . parseInt
кроме ValueError :
поднять новое исключение ( ValueError , «Вы должны ввести положительное число» )
var fact = 1
for i in 2 .. n :
fact = fact * i
echo fact
Используя математические вычисления модуля из стандартной библиотеки Nim:
импортировать std / math
echo fac ( x )
Переворот строки [ править ]
Простая демонстрация, показывающая неявную результирующую переменную и использование итераторов.
proc обратный ( s : строка ): строка =
для i в обратном отсчете ( s . high , 0 ):
результат . add s [ i ]
let str1 = "Переверните это!"
echo "Reversed: " , обратный ( str1 )
Одна из наиболее экзотических особенностей Nim — неявное result
переменная. Каждая процедура в Nim с непустым типом возврата имеет неявную переменную результата, которая представляет возвращаемое значение. В цикле for мы видим вызов countdown
который является итератором. Если итератор опущен, компилятор попытается использовать items
итератор, если он определен для указанного типа.
Графический интерфейс пользователя [ править ]
Использование GTK 3 с самоанализом GObject через модуль gintro :
import gintro /[ gtk , glib , gobject , gio ]
proc appActivate ( приложение : Приложение ) =
let window = newApplicationWindow ( app )
window . title = «Приложение GTK3 с самоанализом объектов»
Окно . defaultSize = ( 400 , 400 )
showAll ( window )
proc main =
let app = newApplication ( «org.gtk.example» )
Connect ( app , «activate» , appActivate )
отбросить запуск ( app )
main ()
Для работы этого кода требуется модуль gintro, который не является частью стандартной библиотеки. Для установки модуля gintro и многих других вы можете использовать инструмент nimble, который входит в состав Nim. Чтобы установить модуль gintro с помощью nimble, вы делаете следующее:
быстрая установка гинтро
Парадигмы программирования [ править ]
Функциональное программирование [ править ]
Функциональное программирование поддерживается в Nim посредством первоклассных функций и кода без побочных эффектов через noSideEffect
прагма или func
ключевое слово. [67] Ним выполнит анализ побочных эффектов и выдаст ошибки компиляции для кода, который не подчиняется контракту об отсутствии побочных эффектов при компиляции с экспериментальной функцией. strictFuncs
, который планируется использовать по умолчанию в более поздних версиях. [68]
В отличие от чисто функциональных языков программирования, Nim — это многопарадигмальный язык программирования, поэтому ограничения функционального программирования применяются для каждой функции.
Первоклассные функции [ править ]
Nim поддерживает первоклассные функции , позволяя хранить функции в переменных или передавать их анонимно в качестве параметров, которые будут вызываться другими функциями. [69] std/sugar
Модуль предоставляет синтаксический сахар для анонимных функций в объявлениях типов и создании экземпляров.
import std /[ sequtils , сахар ]
let powerOfTwo = @[ 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 ] ):
результат . добавить ( s [ i ] )
echo powerOfTwo . filter ( proc ( x : int ): bool = x > 32 )
# синтаксический сахар для вышеперечисленного, предоставленный в виде макроса из std/sugar
echo powerOfTwo . filter ( x => x > 32 )
proc moreThan32 ( x : int ): bool = x > 32
echo powerOfTwo . фильтр ( больше, чем32 )
Побочные эффекты [ править ]
Побочные эффекты функций, помеченных значком noSideEffect
прагмы проверяются, и компилятор откажется компилировать функции, не соответствующие им. Побочные эффекты в Nim включают мутацию, доступ или модификацию глобального состояния, асинхронный код, многопоточный код и ввод-вывод. Мутация параметров может произойти для функций, принимающих параметры var
или ref
type: ожидается, что он не сможет скомпилироваться с экспериментальной в настоящее время версией. strictFuncs
в будущем. [70] func
Ключевое слово представляет ярлык для noSideEffect
прагма. [71]
func binarySearch[T](a: openArray[T]; elem: T): int
# это сокращение от...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 =
# допустимо: len не имеет побочных эффектов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 , сахар ]
let Numbers = @[ , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 # a и ] 1
b — специальные идентификаторы в папке макроса
эхо -номера . фильтр ( x => x > 3 ). дедупликация . папка ( а + б ) #30
Алгебраические типы данных и сопоставление с образцом [ править ]
Nim поддерживает типы продуктов через object
тип, а для типов сумм через варианты объектов : необработанные представления тегированных объединений с тегом перечисляемого типа, который должен быть безопасно сопоставлен, прежде чем можно будет получить доступ к полям вариантов. [73] Эти типы могут быть составлены алгебраически . Сопоставление структурных шаблонов доступно, но регулируется макросами в различных сторонних библиотеках. [74]
import std / таблиц
тип
Value = uint64
Ident = string
ExprKind = enum
Literal , Variable , Abstraction , Application
Expr = ref объекта
Case тип : ExprKind
of Literal :
litIdent : Значение
переменной :
varIdent : Идентификатор
абстракции : :
paramAbs Ident
funcAbs : Expr
приложения Ident :
funcApp , argApp : Expr
func eval ( expr : Expr , context : var Table [ , ] Value Значение ) : =
case expr . вид
литерала :
return expr . litIdent
переменной :
возвращаемый контекст [ expr . varIdent ]
приложения :
case expr . funcApp . вид
абстракции :
контекст [ экспр . funcApp . paramAbs ] = выражение . argApp . eval ( контекст )
возвращает выражение . funcAbs . eval ( контекст )
else :
поднять newException ( ValueError , «Недопустимое выражение!» )
else :
поднять newException ( ValueError , «Недопустимое выражение!» )
Объектно-ориентированное программирование [ править ]
Несмотря на то, что Nim в первую очередь является императивным и функциональным языком, он поддерживает различные функции для реализации объектно-ориентированных парадигм. [75] [76]
Подтипирование и наследование [ править ]
Nim поддерживает ограниченное наследование с помощью ref objects
и of
ключевое слово. [76] Чтобы включить наследование, любой исходный («корневой») объект должен наследовать от RootObj
. Наследование имеет ограниченное применение в идиоматическом коде Nim: за заметным исключением исключений. [77]
type Animal = ссылочный объект RootObj
name : string
age : int
type Dog = ссылочный объект типа Animal
животные Cat = ссылочный объект Animal :
var животные ] seq [ Animal ] = @
. [ добавить ( Собака ( имя : «Спарки» , возраст : 10 ))
животных . добавить ( Кошка ( имя : «Варежка» , возраст : 10 ))
для a в животных :
утвердить a из Animal
Отношения подтипирования также можно запросить с помощью of
ключевое слово. [76]
Вызовы методов и инкапсуляция [ править ]
Nim Унифицированный синтаксис вызова функций позволяет вызывать обычные функции с синтаксисом, аналогичным вызову методов в других языках программирования. Это функционально для «геттеров»: и Nim также предоставляет синтаксис для создания таких «сеттеров». Объекты могут быть общедоступными для каждого поля, обеспечивая инкапсуляцию.
type Socket * = ref object
host : int # частный, отсутствует маркер экспорта
# метод получения адреса хоста
proc host * ( s : Socket ): int = s . хост
# установщик адреса хоста
proc `host=` * ( s : var Socket , значение : int ) =
s . хост = значение
var s : Socket
new s
Assert s . хост == 0 # то же, что и хост(ы), s.host()
s . хост = 34 # то же, что и `host=`(s, 34)
Динамическая отправка [ править ]
Статическая диспетчеризация является предпочтительной, более производительной и стандартной даже среди подпрограмм, ориентированных на методы. [76] Тем не менее, если желательна динамическая диспетчеризация, Nim предоставляет method
Ключевое слово для включения динамической отправки ссылочных типов.
import std / strformat
type
Person = ref объект RootObj переопределения
name : string
Student = ref объект Person Person
Teacher = ref объект метода (
введение a ( : реализации Person ) =
поднять новое исключение ( CatchableError , «Метод без )
метод ввести a » : Student ) =
echo & "Я студент по имени {a.name}!"
метод введения ( a : Учитель ) =
echo & «Я учитель по имени {a.name}!»
let люди : seq [ Человек ] = @[ Учитель ( имя : «Алиса» ), Студент ( имя : «Боб» ) ]
для человека в людях :
человек . представлять ()
Metaprogramming [ edit ]
Шаблоны [ править ]
Nim поддерживает простую замену в абстрактном синтаксическом дереве через свои шаблоны.
шаблон genType ( имя , имя поля : untyped , тип поля : typedesc ) =
типа
имя = имя объекта
имя поля : тип поля
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 (типа int)
echo addThese ( uint8 1 , uint8 2 ) # 3 (типа uint8)
# we не хочу рисковать вычитанием беззнаковых чисел!
proc subtractThese [ T : SomeSignedInt | float ] ( a , b : T ): T = a - b
echo subtractThese ( 1 , 2 ) # -1 (типа int)
import std / sequtils
# ограниченные дженерики также могут быть непосредственно в параметрах
proc CompareThese [ T ] ( a , b : строка | seq [ T ] ): bool =
for ( i , j ) в zip ( a , b ):
if i != j :
вернуть false
Можно дополнительно уточнить, какие типы будет принимать процедура, указав класс типа (в приведенном выше примере SomeSignedInt
). [78]
Макросы [ править ]
Макросы могут переписывать части кода во время компиляции. Макросы Nim являются мощными и могут работать с абстрактным синтаксическим деревом до или после семантической проверки. [79]
Вот простой пример, в котором создается макрос для двойного вызова кода:
импортируйте std / macros
макрос дважды ( arg : untyped ): untyped =
result = quote do :
` arg `
` arg `
дважды echo "Hello world!"
twice
Макрос в этом примере принимает в качестве входных данных оператор echo в форме абстрактного синтаксического дерева. В этом примере мы решили вернуть это синтаксическое дерево без каких-либо манипуляций с ним. Но делаем это дважды, отсюда и название макроса. В результате код переписывается макросом, чтобы во время компиляции он выглядел следующим образом:
эхо «Привет, мир!»
эхо «Привет, мир!»
Интерфейс внешних функций (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 : Блокировка
процесса threadFunc ( интервал : кортеж [ a , b : int ] ) {.thread.} =
for я в интервале . a .. интервал . b :
захват ( L ) # блокировка 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 = объекта
идентификатор * : int
data * : int
CalculationResult = объекта
идентификатор * : int
result * : int
var Task_queue : Channel [ CalculationTask ]
var result_queue : Channel [ CalculationResult ]
proc workerFunc () {.thread.} =
очередь_результата . open ()
, пока true :
var Task = Task_queue . Recv ()
result_queue . send ( CalculationResult ( id : Task . id , результат : Task . data * 2 ))
вар workerThread : Thread [ void ]
createThread ( workerThread , workerFunc )
Task_queue . открыть ()
Task_queue . send ( CalculationTask ( id : 1 , данные : 13 ))
Task_queue . send ( CalculationTask ( id : 2 , data : 37 ))
while true :
echo «получил результат:» , repr ( result_queue . Recv ())
Параллельность [ править ]
![]() | Этот раздел нуждается в расширении . Вы можете помочь, дополнив это . ( июнь 2019 г. ) |
Асинхронный ввод-вывод поддерживается либо через asyncdispatch
модуль в стандартной библиотеке или во внешней chronos
библиотека. [80] Обе библиотеки добавляют синтаксис async/await через систему макросов без необходимости специальной языковой поддержки. Пример асинхронного HTTP- сервера:
import std /[ asynchttpserver , asyncdispatch ]
# вместо asyncdispatch можно также использовать chronos,
# без каких-либо других изменений.
var server = newAsyncHttpServer ()
proc cb ( req : Request ) {.async.} =
await req . ответить ( Http200 , «Hello World» )
waitFor server . служить ( Порт ( 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 г.
- ^ Арабаджи, Владимир (15 ноября 2021 г.), sdl2_nim 2.0.14.2 , получено 16 ноября 2021 г.
- ^ Каир , язык программирования Nim, 5 октября 2021 г. , получено 16 ноября 2021 г.
- ^ opengl , Язык программирования Nim, 14 ноября 2021 г. , получено 16 ноября 2021 г.
- ^ Уорд (15 ноября 2021 г.), Виним , получено 16 ноября 2021 г.
- ^ «Вулканим » GitHub 2022-09-30.
- ^ «Стандартная библиотека Нима» . Документация Ним . Архивировано из оригинала 06 апреля 2015 г. Проверено 4 апреля 2015 г.
- ^ Лим, Андри (продолжительность) (17 октября 2018 г.). "нимЛУА" . Гитхаб . Проверено 17 октября 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» . YouTube . Проверено 28 ноября 2020 г.
- ^ «НимКонф 2021» . НимКонф 2021 . Проверено 17 августа 2023 г.
- ^ «Ним на OSCON 2015» . Конвенция О'Рейли по открытому исходному коду (OSCON) . О'Рейли Медиа. 20 июля 2015 г. Архивировано из оригинала 6 октября 2015 г. Проверено 17 октября 2018 г.
- ^ Румпф, Андреас; Шварц, Джейсон; Харрисон, Мэтт. «Основные языки: Nim, Scala, Python» . О'Рейли . О'Рейли Медиа . Проверено 17 октября 2018 г.
- ^ Румпф, Андреас (26 октября 2015 г.). OSCON 2015 – Ним: Обзор . YouTube видео) . Проверено 12 октября 2018 г.
- ^ "События" . fosdem.org . Проверено 17 февраля 2020 г.
- ^ «Ним Деврум на FOSDEM 2022 — призыв к участию» . Язык программирования Ним . Проверено 17 августа 2023 г.
- ^ «Комната разработки языка программирования Nim» . archive.fosdem.org . Проверено 17 августа 2023 г.
Внешние ссылки [ править ]
- Официальный веб-сайт
- Nim on GitHub
- Информация о Ниме при переполнении стека
- Компьютерное программирование на языке программирования Nim. Нежное введение Стефана Салевского.
- программное обеспечение 2008 года
- Параллельные языки программирования
- Кроссплатформенное программное обеспечение
- Функциональные языки
- Мультипарадигмальные языки программирования
- Процедурные языки программирования
- Языки программирования
- Языки программирования, созданные в 2008 году.
- Программное обеспечение, использующее лицензию MIT
- Компиляторы исходного кода
- Статически типизированные языки программирования
- Языки системного программирования