Построение функции вручную в R

В качестве признака того, что R является функциональным языком, можно указать множество структур управления, используя чистую функциональную нотацию. Например, оператор if:

> as.list((substitute(if(a == 1) 1 else 2)))
[[1]]
`if`

[[2]]
a == 1

[[3]]
[1] 1

[[4]]
[1] 2

> as.list(substitute(`if`(a == 1, 1, 2)))
[[1]]
`if`

[[2]]
a == 1

[[3]]
[1] 1

[[4]]
[1] 2

Из любопытства я попытался сделать то же самое для определения функции. Функции, как правило, строятся с использованием синтаксиса function(args) body, но также существует функция с именем function в R. Проблема, с которой я столкнулся, заключается в том, что неопределенное определение функции будет содержать парный список:

> substitute(function(x = 1, a) {x + a})[[2]]
$x
[1] 1

$a
[empty symbol]

Второй аргумент - это список пар между именами аргументов и значениями по умолчанию, которые, возможно, являются пустыми символами. Насколько я знаю, невозможно передать список или парный список как часть выражения, используя только ручные вызовы. Ниже приведены мои попытки:

> substitute(`function`(x, {x + 1}))
Error: badly formed function expression
> substitute(`function`((x), {x + 1}))
function(`(`, x) {
    x + 1
}

Если я передаю один символ в качестве второго аргумента в `function`, возникает ошибка (и это не будет работать для функции с несколькими аргументами). При передаче вызова в качестве второго аргумента вызов оказывается принудительным для списка при анализе.

Это можно злоупотреблять, используя первый аргумент как имя вызова:

> substitute(`function`(a(x), {x + 1}))
function(a, x) {
     x + 1
}

Однако вызов фактически не преобразуется в парный список и только выглядит так. При оценке этого выражения возникает ошибка. Было бы идеально, чтобы каким-то образом вставить список/парный список в результат вызова для замены. Кто-нибудь знает, как это сделать?

Ответ 1

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

Просто попробуйте этот код:

   as.list((substitute(function(x = 1, a) {x + a})))
   [[1]]

    `function`

  [[2]]

  [[2]]$x

  [1] 1

  [[2]]$a

  [[3]]
   {
      x + a
    }
 [[4]]
      function(x = 1, a) {x + a}