Множественная отправка: мощная парадигма программирования

Рассказал через объектив Юлии

Julia - один из моих любимых языков программирования на все времена. Его не только легко подобрать, как Python, но он также имеет скорость C. Однако говорят, что пользователи Julia приходят из-за производительности и остаются для многократной отправки. Но что это за любопытная особенность и что делает ее привлекательной как для новичков, так и для ветеранов?

Как работает множественная рассылка?

Начнем с того, что вспомним, как выглядит система динамических типов Джулии. Типы Julia можно разделить на конкретные и абстрактные (есть также составные и параметрические, но пока забудем о них). Абстрактные типы образуют основу иерархии типов, в которую могут вписываться конкретные типы.

Существует много способов представления чисел в Julia: данное число может быть действительным или сложным, рациональным или иррациональным, знаковым или беззнаковым. Они организованы в иерархию, часть которой представлена ​​в дереве выше. Узлы-листы относятся к конкретным типам, а промежуточные узлы - к абстрактным типам. В самом деле, конкретные типы не могут быть разделены на подтипы в Julia; их супертипы всегда являются абстрактными типами. Это отражает наследование поведения, а не структуры. Для более детального обзора системы типов Julia, мы отсылаем к руководству пользователя l.

Мы также отмечаем различие между функциями и методами. Функция может иметь несколько вариантов поведения. По определению одно возможное поведение функции называется методом. Более подробное обсуждение методов Julia см. Здесь.

Теперь множественная отправка - это правило выполнения, по которому поведение функции определяется комбинацией и количеством типов аргументов (в соответствии с их высшими уровнями специфичности). Другими словами, множественная диспетчеризация решает, какой метод выполнить, в зависимости от комбинации типов ввода функции.

Например, мы можем определить следующее:

Функция встретить перегружена и для данной комбинации входных данных выберет желаемое поведение на основе типов входных данных. В приведенном выше коде турист является подтипом человека, но олень будет иначе реагировать на туриста, чем обычный человек. Мы можем легко определить дополнительные и более сложные поведения функций, добавив дополнительные входные аргументы, например foo.

Сопоставление на основе всех типов ввода целесообразно во многих случаях, в том числе в математике:

Множественная отправка особенно полезна для математического кода, где нет смысла искусственно считать, что операции «принадлежат» одному аргументу больше, чем любому из других: принадлежит ли операция сложения в x + y к x больше, чем к y? (Руководство Джулии)

Ниже мы выделяем два конкретных преимущества множественной отправки.

Выразительность

Языки, которые реализуют множественную отправку, имеют экспоненциально большую выразительность, чем те, которые этого не делают. При нулевой диспетчеризации функция имеет только одно поведение для любой допустимой комбинации входов. При однократной отправке (когда функция выполняет отправку на одном входе) количество возможных вариантов поведения или методов линейно зависит от размера входного пространства. При многократной отправке количество возможных вариантов поведения зависит от произведения размеров всех входных пространств! Другими словами, количество вариантов поведения, которые можно выразить, составляет порядка

Это, безусловно, большое пространство и дает пользователю достаточно места для контроля над поведением функций за счет специфичности более высокого порядка.

Повторное использование кода

Как разрекламировано в моем руководстве по передовым методам программирования Extreme Programming Explained Кента Бека и Синтии Андрес, повторное использование кода имеет первостепенное значение при разработке программного обеспечения. Это экономит нам, программистам, драгоценное время и энергию, максимально устраняя дублирование кода.

Как множественная отправка облегчает совместное использование, перепрофилирование и, в конечном итоге, повторное использование пакетов Julia, написанных авторами, которые никогда не встречались и не разговаривали друг с другом? В Julia можно основываться на предопределенном типе и множестве его поведений, просто определяя новую функцию, которая работает с другой комбинацией или упорядочением типов ввода. Например, если бы я хотел расширить приведенный выше код demo.jl, я мог бы импортировать пакет и использовать существующие типы или определить новое поведение для функции обнаружения следующим образом.

Несложно сохранить и добавить к предопределенным типам и функциям, таким как Person, Tourist и meeting.

Совет: чтобы расширить функцию из другого пакета, необходимо явно импортировать ее. Например, чтобы расширить детерминантную функцию из модуля линейной алгебры, необходимо сначала добавить следующую строку в начало скрипта

Мы отмечаем, что знакомые концепции, такие как наследование структур и перегрузка функций в статически типизированных языках, не так оптимальны для повторного использования кода по тонким причинам. В статически типизированной системе, такой как C ++, например, для определения поведения функции используются статические типы аргументов перегруженной функции, а не более конкретные типы, которые, возможно, неизвестны компилятору до времени выполнения. Это затрудняет эффективное обеспечение правильного поведения. Действительно, множественная отправка в значительной степени ответственна за необычно большое повторное использование кода в экосистеме Julia.

Резюме

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

  • Мы можем определять новые типы, к которым могут применяться существующие операции
  • Мы можем определять новые операции, которые могут применяться к существующим типам

Это упрощает пользователям создание существующих пакетов, а также функций и предопределенных типов, которые они привносят. Как оказалось, это также способствует повышению скорости и производительности Джулии, облегчая специализацию и оптимизацию скомпилированного кода для различных типов данных. Множественная отправка, несомненно, является ценной функцией, которая отличает Julia от других языков научных вычислений, таких как Matlab, и является благом для членов сообщества Julia.

использованная литература