openlang

Неоднозначные методы Julia и f(2, 3)

Два метода на Julia, f(x::Integer, y::Number) и f(x::Number, y::Integer). Каждый запускает свой алгоритм, подобранный под тот аргумент, который целый. f(2, 3.0) попадает в первый, f(2.0, 3) во второй. Пока всё гладко.

Теперь превратим это число с плавающей точкой в целое. f(2, 3) подходит под оба метода, ни одна сигнатура не специфичнее другой по обеим позициям, и Julia вместо догадок выдаёт ошибку неоднозначности. Справедливо.

Руководство предлагает третий метод, f(x::Integer, y::Integer), для пересечения. Добавили, и ошибки нет. Только он ничего не говорит о том, каким должен быть ответ. Считать ли пару целых отдельным математическим случаем или сознательно отдать её одному из двух алгоритмов? Ошибка неоднозначности оказалась простой частью. Исходным двум методам не приходилось это решать, а теперь кому-то придётся.

Разговор продолжается 3

Следуя доводам
  1. Ссылка на ответ

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

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

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

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

  2. Ссылка на ответ

    Можно и без таких церемоний, как у ajp. Если паре целых не нужна своя математика, третий метод просто вызывает вспомогательную функцию выбранного алгоритма, и у пересечения появляется одно очевидное место. Рядом один задокументированный пример f(2, 3), и никому не придётся выводить выбор из двух других сигнатур. Кажется, здесь этого хватит.

  3. Ссылка на ответ

    По-моему, S4-диспетчеризация в R справляется с этим хуже. Когда два метода одинаково специфичны, она не отказывает. Она выбирает один по собственному правилу упорядочивания, печатает заметку с именем выбранного метода и идёт дальше. Заметки уезжают вверх по экрану. В итоге пара целых тихо получает алгоритм, который никто не выбирал сознательно, а ошибка неоднозначности в Julia, при всей её назойливости, вынуждает принять то решение, о котором пишет ajp.

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

Другие стороны того же вопроса

  1. Неявное расширение превратило ошибку размерности в матрицу

    Раньше умножение строки на столбец через . давало ошибку. Начиная с R2016b уже нет. Если a = [1 2 3] и b = [1; 2; 3], то a .…

    Ответы 2matlab