R: Tidy eval для базовых функций R? - PullRequest
1 голос
/ 29 апреля 2019

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

Если базовая функция R является универсальной и имеет один или несколько аргументов, использующих «стандартную» нестандартную оценку, было бы целесообразно и, если да, было бы целесообразно предложить «аккуратный» метод, который бы приводил в порядок методы оценки доступны для этих аргументов? Я представляю себе какую-то концептуально стандартную оболочку, которая может быть адаптирована к каждой отдельной функции с помощью методов метапрограммирования. Это применимо только к оценке аргументов, которые в настоящее время имеют нестандартную оценку, и, возможно, только к тем, которые имеют нестандартную оценку типа цитирования, так что все текущие методы останутся доступными после сопоставления аргумента и построения с помощью NextMethod (), или любой другой эквивалент для S4, S6 и т. д.

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

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

1 Ответ

0 голосов
/ 02 мая 2019

Я провел несколько тестов, чтобы попытаться выяснить ответ, и я думаю, что он будет очень противоречивым.

Прежде всего, если вы прочитаете документацию для InternalMethods, вы увидитеследующие:

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

Таким образом, вы можете иметь примитивные функции, которыеявляются общими.

Вот некоторые из моих тестов, хотя я сомневаюсь, что они являются исчерпывающими.

library(rlang)

setClass("Foo", list(x="numeric"))
foo <- new("Foo", x=0)

Сначала я попытался определить метод $, который уже использует цитаты для списков ифреймы данных:

setMethod("$", signature(x="Foo"), function(x, name) {
  enquo(name)
})

foo$x
<quosure>
expr: ^"x"
env:  empty

По какой-то причине определенный нами универсал автоматически меняет name на символ, но, возможно, вы можете просто использовать sym и затем продолжить.

Тогда я хотелчтобы увидеть, что происходит с дженериками, которые содержат многоточие:

setMethod("predict", signature(object="Foo"), function(object, ...) {
  enquos(...)
})

predict(foo, bar, baz=bak)
<list_of<quosure>>

[[1]]
<quosure>
expr: ^bar
env:  global

$baz
<quosure>
expr: ^bak
env:  global

Никаких сюрпризов (?)

Затем я попытался определить [, который имеет несколько формальных аргументов и ...:

setMethod("[", signature(x="Foo"), function(x, i, j, ..., drop=TRUE) {
  enquos(i, j, ...)
})

foo[bar, , baz, bak]
<list_of<quosure>>

[[1]]
<quosure>
expr: ^bar
env:  global

[[2]]
<quosure>
expr: ^
env:  empty

[[3]]
<quosure>
expr: ^baz
env:  global

[[4]]
<quosure>
expr: ^bak
env:  global

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

f <- function(x) {
  print(missing(x))
  ff <- function(xx) { missing(xx) }
  eval_tidy(ff(!!enquo(x)))
}

f()
[1] TRUE
[1] FALSE

Наконец я попытался добавить формальный аргумент к методу [:

setMethod("[", signature(x="Foo"), function(x, i, j, k, ..., drop=TRUE) {
  enquos(i, j, k, ...)
})

foo[bar, , baz, bak]
<list_of<quosure>>

[[1]]
<quosure>
expr: ^i
env:  000001FCA36865F0

[[2]]
<quosure>
expr: ^j
env:  000001FCA36865F0

[[3]]
<quosure>
expr: ^baz
env:  global

[[4]]
<quosure>
expr: ^bak
env:  global

И я не знаю, является ли это поведение ошибкой, функцией или чем-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...