Випуск мови програмування Julia 1.8

Доступний реліз мови програмування Julia 1.8, що поєднує такі якості, як висока продуктивність, підтримка динамічної типізації та вбудовані засоби для паралельного програмування. Синтаксис Julia близький до MATLAB із запозиченням деяких елементів з Ruby та Lisp. Метод маніпуляції рядками нагадує Perl. Код проекту розповсюджується під ліцензією MIT.

Ключові особливості мови:

  • Висока продуктивність: однією з ключових цілей проекту є досягнення продуктивності близької до програм мовою Сі. Компілятор Julia заснований на напрацюваннях проекту LLVM та генерує ефективний нативний машинний код для багатьох цільових платформ;
  • Підтримує різні парадигми програмування, включаючи елементи об'єктно-орієнтованого та функціонального програмування. Стандартна бібліотека надає у тому числі функції для асинхронного введення/виводу, управління процесами, ведення логів, профілювання та управління пакетами;
  • Динамічна типізація: мова не вимагає явного визначення типів змінних за аналогією зі скриптовими мовами програмування. Підтримується інтерактивний режим роботи;
  • Опціональна можливість явної вказівки типів;
  • Синтаксис, що чудово підходить для чисельних обчислень, наукових розрахунків, систем машинного навчання та візуалізації даних. Підтримка багатьох числових типів даних та засобів для розпаралелювання обчислень.
  • Можливість прямого виклику функцій з бібліотек мовою Сі без додаткових прошарків.

Основні зміни Julia 1.8:

  • Нові можливості мови
    • Поля зміни структури (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 (і, отже, останнє) підтримує кожнуline.
    • Функція length для діапазонів певних типів більше не перевіряє ціле переповнення. Доступна нова функція checked_length, що містить логіку контролю перенесення розряду. При необхідності, використовуйте SaferIntegers.jl, дляпобудови типу діапазону.
    • Ітератор Iterators.Reverse реалізує інвертування кожногоindex, якщо це можливо.
  • Менеджер пакетів
    • Нові індикатори ⌃ та ⌅ поруч із пакетами у статусі «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.
  • InteractiveUtils
    • Новий макрос @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}})».
  • Printf
    • Тепер для форматування ширини %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
    • Код SparseArrays переміщений із репозиторію Julia у зовнішній репозиторій SparseArrays.jl.
    • Нові функції конкатенації sparse_hcat, sparse_vcat та sparse_hvcat повертають тип SparseMatrixCSC незалежно від типів вхідних аргументів. Це стало необхідним для уніфікації механізму склеювання матриць після поділу коду LinearAlgebra.jl та SparseArrays.jl.
  • Запис
    • Стандартні рівні журналів BelowMinLevel, Debug, Info, Warn, Error та AboveMaxLevel тепер експортуються зі стандартної бібліотеки Logging.
  • Unicode
    • Додано функцію 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) можна використовувати для реєстрації кожної операції складання сміття із зазначенням часу та обсягу зібраної пам'яті.

Джерело: opennet.ru

Додати коментар або відгук