Используя универсальные функции R, когда и почему? - PullRequest
14 голосов
/ 16 марта 2012

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

Например, в настоящее время у меня есть функция logLikSSM, которая вычисляет логарифмическую вероятность модели пространства состояний. Вместо того, чтобы использовать эти функции, я мог бы сделать функцию logLik.SSM или что-то в этом роде, так как в R. есть универсальная функция logLik. Преимущество этого состоит в том, что logLik короче, чем logLikSSM, но есть ли вообще какой-то другой момент в это?

Аналогичный случай, в пакете статистики есть универсальная функция, называемая симуляцией, так что теоретически я мог бы использовать ее вместо simulateSSM. Но теперь описание функции имитации говорит, что функция используется для «симуляции ответов», но моя функция фактически имитирует скрытые состояния, поэтому она действительно не вписывается в описание функции имитации. Так что, вероятно, в этом случае я не должен использовать обобщенную функцию, верно?

Прошу прощения, если этот вопрос слишком неопределенный для этого.

Ответы [ 3 ]

10 голосов
/ 16 марта 2012

Преимущества создания методов для дженериков из ядра R включают:

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

  2. Использование существующей функциональности .Кроме того, любые другие функции, которые используют обобщенные методы, для которых вы создаете методы, могут автоматически использовать и ваши;в противном случае они должны быть изменены.Например, AIC использует logLik.

A Недостаток заключается в том, что универсальный включает в себя дополнительный уровень диспетчеризации, а если logLik находится во внутреннейЦикл оптимизации может оказать влияние (хотя, возможно, и не материальное).В этом случае вы можете проверить производительность вызова универсального метода вместо прямого вызова метода и использовать последний, если это имеет существенное значение.

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

Возможно, вы захотите прочитать руководство по дизайну zoo (см. Ссылку на zoo Design в разделе «Виньетки» внизу этой страницы), где обсуждаются идеи дизайна, которые вошли в пакет зоопарка.К ним относится идея, обсуждаемая здесь.

РЕДАКТИРОВАТЬ: добавлены недостатки.

4 голосов
/ 16 марта 2012

хороший вопрос.

Я разделю ваш Вопрос на две части; вот первый:

Есть ли еще какой-то смысл в [создании общих функций]?

Что ж, этот шаблон обычно вызывается , когда разработчик не знает класс объекта для каждого объекта, который, как он / она ожидает, пользователь передаст в рассматриваемому методу.

И из-за этой неопределенности вызывается этот шаблон проектирования (называемый перегрузкой во многих других языках), который требует R для оценки класса объекта, а затем dispatch , что объект в соответствующий метод с учетом типа объекта.

секунда часть вашего Вопроса: [в] этом случае я не должен использовать [универсальную функцию], верно?

Чтобы попытаться дать вам полезный ответ, выходящий за рамки деталей вашего Вопроса, подумайте, что происходит с исходным методом, когда вы вызываете setGeneric , передавая этот метод.

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

showMethods () позволит вам увидеть все те методы, которые вызываются вновь созданной диспетчерской функцией (универсальной функцией).

1 голос
/ 03 августа 2016

А теперь еще один огромный недостаток:

Простота MISUse : Пользователи вашего пакета, уже знакомые с этими генериками, могут сделать определенную сумму, не читая документацию.

И в этом заключается ошибка, что компоненты, повторно используемые объекты, сервисы и т. Д. Являются легкой панацеей от всех проблем с программным обеспечением.

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

БЫЛА причина для статической компоновки и небольших исполняемых файлов. Но это поколение кода сейчас, платят сейчас, отлаживают позже, если когда-либо, до наступления временных увольнений / IPO, не помнит те дни, когда код действительно работал очень надежно, а для установки / интеграции не требовалось 200 долларов / час. или хакеры, которые проводят неделю, пытаясь установить и продуктивно запустить какой-нибудь «простой» продукт с открытым исходным кодом.

Но если вы хотите продолжить традицию написания более коротких имен функций / методов, будьте моим гостем.

...