Доступен релиз языка программирования Julia 1.8, сочетающего такие качества как высокая производительность, поддержка динамической типизации и встроенные средства для параллельного программирования. Синтаксис Julia близок к MATLAB с заимствованием некоторых элементов из Ruby и Lisp. Метод манипуляции строками напоминает Perl. Код проекта распространяется под лицензией MIT.
Ключевые особенности языка:
- Высокая производительность: одной из ключевых целей проекта является достижение производительности близкой к программам на языке Си. Компилятор Julia основан на наработках проекта LLVM и генерирует эффективный нативный машинный код для многих целевых платформ;
- Поддержка различных парадигм программирования, включая элементы объектно-ориентированного и функционального программирования. Стандартная библиотека предоставляет в том числе функции для асинхронного ввода/вывода, управления процессами, ведения логов, профилирования и управления пакетами;
- Динамическая типизация: язык не требует явного определения типов для переменных по аналогии со скриптовыми языками программирования. Поддерживается интерактивный режим работы;
- Опциональная возможность явного указания типов;
- Синтаксис, превосходно подходящий для численных вычислений, научных расчётов, систем машинного обучения и визуализации данных. Поддержка многих числовых типов данных и средств для распараллеливания вычислений.
- Возможность прямого вызова функций из библиотек на языке Си без дополнительных прослоек.
Основные измененияв Julia 1.7:
- Новые возможности языка
- Поля изменяемой структуры (mutable struct) теперь могут быть аннотированы как константы, чтобы предотвратить их изменения и обеспечить возможность оптимизации.
- Аннотации типов можно добавлять к глобальным переменным.
- Пустые n-мерные массивы можно создавать, используя несколько точек с запятой внутри квадратных скобок, например “[;;;]” создаёт массив 0×0×0.
- Блоки try теперь могут дополнительно иметь блок else, который выполняется сразу после основного тела, если не было выдано никаких ошибок.
- @inline и @noinline можно размещать внутри тела функции, что позволяет аннотировать анонимную функцию.
- @inline и @noinline теперь можно применять к функции на сайте вызова или в блоке, чтобы принудительно включить (или не включить) соответствующие вызовы функций.
- ∀, ∃ и ∄ разрешены в качестве символов идентификатора.
- Добавлена поддержка спецификации Unicode 14.0.0.
- метод Module(:name, false, false) можно использовать для создания модуля, который не содержит имен, не импортирует Base или Core и не содержит ссылки на себя.
- Изменения в языке
- Вновь созданные объекты Task (@spawn, @async и т. д.) теперь world_age для методов из родительского Task при создании, что позволяет оптимизировать их исполнение. Предыдущий варианте активации доступен при помощи метода Base.invokelatest.
- Директивы несбалансированного двунаправленного форматирования Unicode теперь запрещены в строках и комментариях во избежании инъекций.
- Base.ifelse теперь определяется как общая функция, а не как встроенная, что позволяет пакетам расширять её определение.
- Каждое присвоение глобальной переменной теперь сначала проходит через вызов convert(Any, x) или convert(T, x), если для глобальной переменной был объявлен тип T. Перед использованием глобальных переменных, убедитесь, что инвариант convert(Any, x) === x всегда истинен, иначе это может привести к неожиданному поведению.
- Встроенные функции теперь похожи на универсальные функции и могут быть программно перечислены с помощью методов.
- Улучшения компилятора/среды выполнения
- Время начальной загрузки сокращено примерно на 25%.
- Компилятор на основе LLVM был отделён от runtime-библиотеки в новую библиотеку libjulia-codegen. Он загружается по умолчанию, поэтому при обычном использовании изменений быть не должно. В развёртываниях, которым не нужен компилятор (например, системные образы, в которых весь необходимый код предварительно скомпилирован), эту библиотеку (и её LLVM-зависимость) можно просто исключить.
- Вывод условного типа теперь возможен через передачу аргумента методу. Например, для Base.ifelse(isa(x, Int), x, 0) возвращает ::Int, даже если тип x неизвестен.
- SROA (Scalar Replacement of Aggregates) улучшена: исключает вызовы getfield с постоянными глобальными полями, исключает изменяемые структуры с неинициализированными полями, повышает производительность и обработку вложенных вызовов getfield.
- Вывод типов отслеживает различные эффекты — побочные изменения и отсутствие отбрасывания. Учитывается распространения констант, что значительно повышает производительность во время компиляции. В некоторых случаях, например, вызовы функций, которые не могут быть встроены по месту вызова, но не влияют на результат, будут отброшены на время выполнения. Правила для эффектов можно перезаписать вручную с помощью макроса Base.@assume_effects.
- Предварительная компиляция (с явными директивами предварительной компиляции или заданными рабочими нагрузками) теперь сохраняет больше кода, определяемого типом, что приводит к сокращению времени первого запуска. Любые новые комбинации методов/типов, необходимые вашему пакету, независимо от того, где эти методы были определены, теперь могут кэшироваться в файле прекомпиляции, если они вызваны методом, принадлежащим вашему пакету.
- Изменения параметров командной строки
- Поведение по умолчанию для наблюдения за объявлениями @inbounds теперь является опцией auto в “–check-bounds=yes|no|auto”.
- Новая опция “–strip-metadata” для удаления строк документации, информации об исходном местоположении и имён локальных переменных при создании образа системы.
- Новая опция “–strip-ir” для удаления компилятором промежуточного представления исходного кода при сборке образа системы. Результирующий образ будет работать, только если используется “–compile=all” или если весь необходимый код предварительно скомпилирован.
- Если вместо имени файла указан символ “-“, то исполняемый код читается из стандартного потока ввода.
- Изменения поддержки многопоточности
- Threads.@threads по умолчанию использует новый параметр расписания :dynamic, который отличается от предыдущего режима тем, что итерации будут планироваться динамически для доступных рабочих потоков, а не закрепляться за каждым потоком. Такой режим позволяет лучше распределять вложенные циклы с @spawn и @threads.
- Новые библиотечные функции
- eachsplit(str) для многократного выполнения split(str).
- allequal(itr) для проверки равенства всех элементов в итераторе.
- hardlink(src, dst) можно использовать для создания жёстких ссылок.
- setcpuaffinity(cmd, cpus) для установки соответствия ядра процессора запускаемым процессам.
- diskstat(path=pwd()) для получения статистики о диске.
- Новый макрос @showtime для отображения как оцениваемой строки, так и отчета @time.
- LazyString и макрос lazy”str” добавлены для поддержки отложенного построения сообщений об ошибках в путях ошибок.
- Устранена проблема параллельного доступа в Dict и других производных объектах, таких как keys(::Dict), values(::Dict) и Set. Методы итерации теперь можно вызывать для словаря или множества, при условии, что нет вызовов, изменяющих словарь или множество.
- @time и @timev теперь имеют необязательное описание, позволяющее аннотировать источник отчётов о времени, например. @time “Evaluating foo” foo().
- range принимает либо stop, либо length в качестве единственного аргумента ключевого слова.
- precision и setprecision теперь принимают base в качестве ключевого слова
- Объекты сокетов TCP теперь предоставляют closewrite метод и поддерживают использование полуоткрытого режима.
- extrema теперь принимает аргумент init.
- Iterators.countfrom теперь принимает любой тип, определяющий метод +.
- @time теперь выделяет % времени, потраченного на перекомпиляцию методов с изменёнными типами.
- Изменения стандартной библиотеки
- Ключи со значением Nothing теперь удаляются из среды в addenv.
- Iterators.reverse (и, следовательно, last) поддерживает eachline.
- Функция length для диапазонов определенных типов больше не проверяет целочисленное переполнение. Доступна новая функция checked_length, содержит логику контроля переноса разряда. При необходимости, используйте SaferIntegers.jl, дляпостроении типа диапазона.
- Итератор Iterators.Reverse реализует инвертирование eachindex, если это возможно.
- Менеджер пакетов
- Новые индикаторы ⌃ и ⌅ рядом с пакетами в статусе “pkg>”, для которых доступны новые версии. ⌅ указывает, что новые версии не могут быть установлены.
- Новый аргумент outdated::Bool для Pkg.status (–outdated или -o в режиме REPL), чтобы показать информацию о пакетах предыдущих версии.
- Новый аргумент compat::Bool для Pkg.status (–compat или -c в режиме REPL), чтобы показать любые записи [compat] в Project.toml.
- Новый режим “pkg> compat” (и Pkg.compat) для настройки записей совместимости проекта. Предоставляет интерактивный редактор через “pkg> compat” или прямое управление записью через “pkg> Foo 0.4,0.5”, который может загружать текущие записи через автозавершение по табуляции. То есть “pkg> compat Fo” автоматически дополняется до “pkg> Foo 0.4,0.5”, чтобы можно было редактировать существующую запись.
- Теперь Pkg пытается загрузить пакеты с сервера пакетов только в том случае, если сервер отслеживает реестр, содержащий пакет.
- Pkg.instantiate теперь будет выводить предупреждение, когда Project.toml не синхронизирован с Manifest.toml. Он делает это на основе хэш записей deps и compat проекта (другие поля игнорируются) в манифесте при его разрешении, чтобы можно было обнаружить любое изменение в deps Project.toml или записях compat без повторного разрешения.
- Если “pkg> add” не может найти пакет с указанным именем, теперь будут предложены пакеты с аналогичными именами, которые можно добавить.
- Версия julia, хранящаяся в манифесте, больше не включает номер сборки, т. е. master теперь будет записываться как 1.9.0-DEV.
- Прерывание теста “pkg>” теперь будет обнаруживаться стабильнее, и будет корректно возвращать в REPL.
- Новый макрос @time_imports для отчета о времени, потраченном на импорт пакетов и их зависимостей, с выделением времени компиляции и перекомпиляции в процентах на импорт.
- Подмодуль BLAS теперь поддерживает level-2 BLAS функции spr!.
- Стандартная библиотека LinearAlgebra.jl теперь полностью независима от SparseArrays.jl как с точки зрения исходного кода, так и с точки зрения модульного тестирования. Как следствие, разреженные массивы больше не возвращаются (неявно) методами из LinearAlgebra, примененными к объектам Base или LinearAlgebra. В частности, это приводит к следующим критическим изменениям:
- Конкатенации с использованием специальных “разреженных” матриц (например, диагональная) теперь возвращают плотные матрицы; Как следствие, поля D1 и D2 объектов SVD, созданные при вызовах getproperty, теперь являются плотными матрицами.
- Метод similar(::SpecialSparseMatrix, ::Type, ::Dims) возвращает плотную нулевую матрицу. Как следствие, произведения двух-, трех- и симметричных трехдиагональных матриц друг на друга приводят к порождению плотной матрицы. Кроме того, построение подобных матриц с тремя аргументами из специальных “разреженных” матриц из (нестатических) матриц теперь не удается из-за “zero(::Type{Matrix{T}})”.
- Теперь для форматирования ширины %s и %c использует аргумент textwidth.
- Профилирование загрузки процессора теперь записывает метаданные, включая потоки и задачи. Profile.print() имеет новый аргумент groupby, который позволяет группировать потоки, задачи или вложенные потоки/задачи, задачи/потоки, а также аргументы threads и tasks для обеспечения фильтрации. Кроме того, процент использования теперь сообщается или как общий, или по потокам, в зависимости от того, простаивает ли поток или нет в каждой выборке. Profile.fetch() включает новые метаданные по умолчанию. Для обратной совместимости с внешними потребителями данных профилирования его можно исключить, передав include_meta=false.
- Новый модуль Profile.Allocs позволяет профилировать выделение памяти. Записывается трассировка стека, тип и размер каждого выделения памяти, а аргумент sample_rate позволяет пропускать настраиваемое количество распределений, снижая нагрузку на производительность.
- Профилирование процессора с фиксированной продолжительностью теперь может запускаться пользователем во время выполнения задач без предварительной загрузки профиля, и отчёт будет отображаться во время выполнения. В MacOS и FreeBSD нажмите ctrl-t или вызовите SIGINFO. Для других платформ активируйте SIGUSR1, т.е. % kill -USR1 $julia_pid. В Windows это недоступно.
- RadioMenu теперь поддерживает дополнительные сочетания клавиш для прямого выбора параметров.
- Последовательность “?(x, y”, за которой следует нажатие TAB, отображает все методы, которые можно вызвать с аргументами x, y, …. (Пробел в начале не позволяет войти в режим справки). “MyModule.?(x, y” ограничивает поиск “MyModule”. Нажатие TAB требует, чтобы по крайней мере один аргумент имел тип, более конкретный, чем Any. Или используйте SHIFT-TAB вместо TAB, чтобы разрешить любые совместимые методы.
- Новая глобальная переменная err позволяет получить последнее исключение, похожее на поведение ans с последним ответом. Ввод err повторно печатает информацию об исключении.
- Код SparseArrays перемещен из репозитория Julia во внешний репозиторий SparseArrays.jl.
- Новые функции конкатенации sparse_hcat, sparse_vcat и sparse_hvcat возвращают тип SparseMatrixCSC независимо от типов входных аргументов. Это стало необходимым для унификации механизма склейки матриц после разделения кода LinearAlgebra.jl и SparseArrays.jl.
- Стандартные уровни журналов BelowMinLevel, Debug, Info, Warn, Error и AboveMaxLevel теперь экспортируются из стандартной библиотеки Logging.
- Добавлена функция isequal_normalized для проверки эквивалентности Unicode без явного построения нормализованных строк.
- Функция Unicode.normalize теперь принимает ключевое слово chartransform, которое можно использовать для предоставления пользовательских сопоставлений символов, а также предоставляется функция Unicode.julia_chartransform для воспроизведения сопоставления, используемого при нормализации идентификаторов синтаксическим анализатором Julia.
- ‘@test_throws “some message” triggers_error()’ теперь можно использовать для проверки того, содержит ли отображаемый текст ошибки “some message”, независимо от конкретного типа исключения. Также поддерживаются регулярные выражения, списки строк и функции сопоставления.
- @testset foo() теперь можно использовать для создания набора тестов из заданной функции. Имя тестового набора – это имя вызываемой функции. Вызываемая функция может содержать @test и другие определения @testset, в том числе для вызовов других функций, при этом записывая все промежуточные результаты тестирования.
- TestLogger и LogRecord теперь экспортируются из стандартной библиотеки Test.
- SSHManager теперь поддерживает рабочие потоки с обёрткой csh/tcsh через метод addprocs() и параметр shell=:csh.
- GC.enable_logging(true) можно использовать для регистрации каждой операции сборки мусора с указанием времени и объема собранной памяти.
Release.
Ссылка here.