Почему я больше не рекомендую Julia

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Много лет я пользовался языком программирования Julia для преобразования, очистки, анализа и визуализации данных, расчёта статистики и выполнения симуляций.

Я опубликовал несколько опенсорсных пакетов для работы с такими вещами, как поля расстояний со знаком, поиск ближайших соседей и паттерны Тьюринга (а также с другими), создавал визуальные объяснения таких концепций Julia, как broadcasting и массивы, а ещё применял Julia при создании генеративной графики для моих визиток.

Какое-то время назад я перестал пользоваться Julia, но иногда мне задают о нём вопросы. Когда люди спрашивают меня, я отвечаю, что больше не рекомендую его. Мне подумалось, что стоит написать, почему.

После многолетнего использования Julia я пришёл к выводу, что в его экосистеме слишком много багов корректности и сочетаемости, и это не позволяет использовать этот язык в контекстах, где важна корректность.

По моему опыту, Julia и его пакеты имеют наибольшую частоту серьёзных багов корректности из всех использованных мной программных систем, а ведь я начинал программировать с Visual Basic 6 в середине 2000-х.

Наверно, будет полезно привести конкретные примеры.

Вот проблемы корректности, о которых я составил отчёты:

  • Сэмплирование плотности вероятности даёт некорректный результат
  • Сэмплирование массива может давать результаты со смещением
  • Функция произведения может давать некорректные результаты для 8-битных, 16-битных и 32-битных integer
  • Подгонка гистограммы под массив Float64 может давать некорректные результаты
  • Базовые функции sum!, prod!, any! и all! могут возвращать некорректные результаты без сообщения об ошибке

Вот похожие проблемы, о которых сообщали другие люди:

  • Summarystats возвращает квантили NaN для массивов со средним значением 0
  • OrderedDict может повреждать ключи
  • Ошибка смещения на единицу в dayofquarter() в високосные годы
  • Некорректные результаты симуляции при использовании типа number с величиной ошибки
  • Pipeline со stdout=IOStream выполняет запись не по порядку
  • Неверные результаты, поскольку некоторые методы copyto! не выполняют проверку на наложение
  • Неверный поток управления if-else

Я сталкивался с багами подобного уровня серьёзности достаточно часто, поэтому это заставило меня подвергнуть сомнению корректность любых вычислений умеренной сложности на Julia.

Особенно справедливо это было при использовании нового сочетания пакетов или функций — комбинирование функциональности из нескольких источников было существенным источником багов.

Иногда проблемы возникают из-за несочетаемых друг с другом пакетов, в других случаях к неожиданному сбою приводит неожиданное сочетание возможностей Julia внутри одного пакета.

Например, я выяснил, что евклидово расстояние из пакета Distances не работает с векторами Unitful. Другие люди обнаружили, что функция Julia для запуска внешних команд не работает с подстроками. Кто-то выяснил, что поддержка отсутствующих значений Julia в некоторых случаях ломает матричное умножение. И что макрос стандартной библиотеки @distributed не работал с OffsetArray.

OffsetArray вообще оказался серьёзным источником багов корректности. Пакет предоставляет тип массива, использующий гибкую функцию настраиваемых индексов Julia, позволяющую создавать массивы, индексы которых не обязаны начинаться с нуля или единицы.

Их использование часто приводит к доступу к памяти out-of-bounds, с которым вы могли встречаться в C или C++. Если повезёт, это приведёт к segfault, а если нет, то результаты будут неверными без сообщений об ошибках. Однажды я нашёл баг в ядре Julia, который может привести к доступу к памяти out-of-bounds, даже если и пользователь, и создатели библиотеки написали корректный код.

Я отправил множество отчётов о проблемах индексации в организацию JuliaStats, занимающуюся обслуживанием статистических пакетов наподобие Distributions, от которого зависят 945 пакетов, и StatsBase, от которого зависят 1660 пакетов. Вот некоторые из них:

  • Большинство методов сэмплирования небезопасно и некорректно в случае наличия смещённых осей
  • Выравнивание распределения DiscreteUniform может вернуть некорректный ответ без сообщения об ошибке
  • counteq, countne, sqL2dist, L2dist, L1dist, L1infdist, gkldiv, meanad, maxad, msd, rmsd и psnr со смещёнными индексами могут возвращать некорректные результаты
  • Некорректное использование @inbounds может вызывать неверный расчёт статистики
  • Colwise и pairwise могут возвращать некорректные расстояния
  • Отображение вектора Weights, оборачивающего массив со смещением, выполняет доступ к памяти out-of-bounds

Первопричиной этих проблем является не сама индексация, а её совместное использование с другой фичей Julia под названием @inbounds, позволяющей Julia удалять проверки границ при доступе к массивам.

Пример:

function sum(A::AbstractArray)
    r = zero(eltype(A))
    for i in 1:length(A)
        @inbounds r += A[i] # ← 						
Источник: https://habr.com/ru/post/666332/


Интересные статьи

Интересные статьи

Это будет моя самая короткая статья.Когда-то я был молод и зелен и решал проблемы именно так, как их решают джуны. Алгоритм такой:1. Узнать о проблеме2. Локализовать проблему3. Загуглить проблему и ре...
Знаете ли вы, что существует целая индустрия, которая занимается шрифтами? Шрифты и типографика – понятия, которые имеют активное хождение в этой области, а задача специалистов – создавать начерта...
От переводчика: Эта статья – своего рода анонс возможного. Профессор Дэвид Блэр кратко представляет научную работу, прокладывающую путь к тому, чтобы повысить чувствительность детект...
TL;DR Context и Redux — это одно и тоже? Нет. Это разные инструменты, делающие разные вещи и используемые в разных целях. Является ли контекст инструментом «управления состоянием...
Мы поговорим о модели песчаной кучи. Песок (не настоящий, модельный), пересыпаясь, создаёт вот такие картинки: Песчаные кучи можно складывать (это легко, если вы привыкли складывать всякие...