Ключевые особенности Nim включают мощную систему макросов, работающих на AST во время компиляции, развитую систему обобщённого программирования с концептами, множественную диспетчеризацию (multiple dispatch), детерминированное управление памятью с поддержкой нескольких стратегий (ARC/ORC, refc, маркировка-и-подметание), встроенную поддержку async/await для асинхронного программирования и FFI для простой интеграции с C/C++/JavaScript. Nim позиционируется как системный язык, подходящий для разработки от встраиваемых систем до веб-серверов, с акцентом на эффективность, безопасность памяти и удобство разработки.
Ключевые изменения:
-  Оптимизация move-семантики для полей объектов. Компилятор научился распознавать возможность применения move-операций при возврате полей объектов. Ранее конструкции вида "return obj.field" приводили к копированию данных, теперь компилятор корректно применяет перемещение:
Код:
proc getField(obj: MyObject): string =
return obj.field # Теперь move вместо copy
Это особенно важно для тяжёлых типов данных (строки, последовательности, объекты с ресурсами), где устранение лишнего копирования даёт заметный прирост производительности без изменения кода. -  Полная переработка closure-итераторов с обработкой исключений.
Механизм трансформации замыканий-итераторов полностью переписан, что кардинально улучшило стабильность async-кода с обработкой исключений. Исправлены критические проблемы, включая SIGSEGV при использовании try/except не на верхнем уровне:Также решена проблема с некорректным пробросом исключений в finally-блоках внутри closure-итераторов.Код:
iterator problematicIterator(): int {.closure.} =
for i in 0..10:
try:
if i == 5:
raise newException(ValueError, "test")
yield i
except ValueError:
discard # Ранее вызывало SIGSEGV -  Исправления, связанные с управлением памятью
- Устранена фундаментальная проблема в сборщике мусора при обработке циклических структур данных, которая могла приводить к выводу ошибки "Illegal storage access". Проблема существовала с момента создания языка и проявлялась при сложных графах объектов с взаимными ссылками.
 -  Исправлен некорректный порядок уничтожения объектов, который мог приводить к обращению к уже освобождённой памяти:
Код:
type
Resource = object
data: ptr Data
Container = object
resource: Resource
other: OtherResource
# Теперь деструкторы вызываются в правильном порядке:
# сначала other, затем resource - Сборщик ORC ошибочно помечал окружения некоторых замыканий как циклические, что приводило к задержкам освобождения памяти или утечкам. Теперь анализ циклов работает корректно.
 -  Исправлена утечка сокетов в asyncnet при ошибках согласования TLS-соединения:
Код:
proc handleClient() {.async.} =
var socket = await server.accept()
try:
await socket.setupSSL() # При ошибке здесь socket теперь корректно закрывается
except SSLError:
discard # Сокет больше не утекает 
 -  Критические исправления в компиляторе.
-  Устранена регрессия, при которой глобальные переменные, объявленные внутри процедур с static-параметрами, переинициализировались при каждом вызове:
Код:
proc test[N: static int]() =
var global {.global.}: array[N, int]
global[0] += 1
echo global[0]
test[5]() # Выводило: 1
test[5]() # Должно: 2, но выводило: 1 (было переинициализировано) - Исправлена генерация кода для глобальных переменных в рекурсивных функциях, которая приводила к неопределённому поведению.
 -  Решена древняя проблема генерации некорректного C-кода при использовании конструкторов для глобальных переменных внутри конвертеров:
Код:
converter toInt(x: MyType): int =
let global {.global.} = MyType() # Генерировал невалидный C-код
result = global.value - Устранено падение компилятора при генерации исключений типа Defect и использовании doAssert в определённых контекстах.
 
 -  Устранена регрессия, при которой глобальные переменные, объявленные внутри процедур с static-параметрами, переинициализировались при каждом вызове:
 -  Улучшения в системе типов
-  Исправлена невозможность возврата lent-значений из case/if выражений:
Код:
proc getBest(a, b: string): lent string =
if a.len > b.len:
return a # Ранее: ошибка компиляции
else:
return b -  Устранена проблема с некорректным сохранением значений lent-полей в обобщённых типах:
Код:
type
Wrapper[T] = object
data: lent T
proc process[T](w: Wrapper[T]) =
echo w.data # Значение теперь корректно сохраняется -  Восстановлена проверка инициализации переменной result для типов с requiresInit, которая была сломана в версии 2.2:
[/codebox]
type
MustInit {.requiresInit.} = object
value: int
proc test(): MustInit =
discard # Теперь корректно выдаёт ошибку о неинициализированном result
[/codebox] -  Исправлено игнорирование некопируемости (".noCopy") базового типа:
Код:
type
Base {.noCopy.} = object
Derived = object of Base
var a: Derived
var b = a # Теперь корректно запрещено 
 -  Исправлена невозможность возврата lent-значений из case/if выражений:
 -  Оптимизации производительности
-  Ускорение оператора "@" для тривиальных типов: устранена критическая деградация производительности при создании последовательностей из массивов простых типов:
Код:
let arr = [1, 2, 3, 4, 5]
let s = @arr # Было крайне медленно, теперь оптимально - Оптимизация vmgen.sameConstant: значительно ускорена компиляция за счёт оптимизации сравнения констант в виртуальной машине компилятора и сокращения операций выделения памяти.
 -  Разыменование результата cast в одиночном выражении больше не вызывает ненужное копирование:
Код:
let data = cast[ptr MyType](address)[] # Теперь без копирования 
 -  Ускорение оператора "@" для тривиальных типов: устранена критическая деградация производительности при создании последовательностей из массивов простых типов:
 -  Исправления в бэкенде для компиляции в JavaScript:
- =destroy для не-var типов: исправлена генерация деструкторов, которая ранее приводила к ошибкам компиляции.
 - cast[char] для значений › 255: теперь корректно выполняется усечение, как в C-backend.
 - Концепты в varargs: устранён вывод ошибки "internal error" при передаче концептов в varargs.
 
 -  В бэкенде для компиляции в C++ восстановлена L-valueness для совместимых типов что было сломано в регрессии между версиями 2.2.2 и 2.2.4:
Код:
# nim cpp
var x: CppCompatibleType
takeRef(x) # Снова работает как lvalue -  Исправления в бэкенде для компиляции в C (refc):
- pthread на некоторых платформах: исправлена генерация кода для pthread_mutex_t с использованием .abi;
 - Обобщённые типы с GC-памятью: устранена генерация некорректного C-кода для generic-типов, содержащих управляемую память;
 
 -  Виртуальная машина
- Глобальные переменные и присваивания: множественные исправления работы с глобальными переменными на этапе компиляции.
 - Case-объекты из compileTime proc: исправлена передача вариантных объектов как static-параметров.
 - repr для длинных строк под refc: устранён RangeDefect при использовании repr.
 
 -  Исправления в стандартной библиотеке
-  В strutils.formatSize исправлена работа с большими значениями, близкими к int64.high:
Код:
echo formatSize(9223372036854775807) # Теперь корректный результат - В deques восстановлена совместимость поведения итератора items между версиями 2.0.16 и 2.2.0.
 - В lists.SinglyLinkedList.remove устранён AssertionDefect при удалении элементов из односвязного списка.
 - В tables.withValue исправлено условие проверки в макросе withValue для неизменяемых таблиц.
 
 -  В strutils.formatSize исправлена работа с большими значениями, близкими к int64.high:
 -  Прагмы и области видимости
- В "{.push raises: [].}" исправлено некорректное игнорирование лексических областей видимости для push-прагм с raises.
 -  Устранён эффект «утечки» отключения предупреждений за пределы pragma-блоков:
Код:
{.push warning[UnusedImport]: off.}
import module1
{.pop.}
import module2 # Предупреждения теперь корректно включены 
 -  Прочие важные исправления
- Сравнение cstring: добавлены отсутствовавшие операторы "‹" и "cmp" для cstring.
 - Проверка диапазонов float: включена корректная проверка диапазонов для чисел с плавающей точкой
 - filterIt и rvalue: исправлено ошибочное возвращение rvalue вместо lvalue
 - Устранён FieldDefect при сравнении указателей на этапе компиляции.
 - hasCustomPragma после копирования typedesc: восстановлена работоспособность после копирования дескрипторов типов.
 - nim doc и приватные поля: исправлено использование комментариев от приватных полей для публичных.
 
 
Источник: https://www.opennet.ru/opennews/art.shtml?num=64173
(opennet.ru, основная лента)