R中函数调用的优先级

Jon*_*aus 9 r function-calls operator-precedence

运算符优先级的标准R帮助页面上,它们不包括函数调用,在我看来这似乎相当草率.这导致了一些问题,所以我决定只使用反复试验,substitute并发现优先级似乎介于[[和之间^:

> substitute(a^b())[[1]]
`^`
> substitute(a[b]())[[1]]
a[b]
Run Code Online (Sandbox Code Playgroud)

在中缀表示法中,这些将是(^ a (b ()))(([ a b) ())(表示呼叫操作符为()).在简单的英语中,第一个示例显示在参数上调用指数函数a,b()而在第二个示例中,最终结果是对函数的调用a[b].

这种优先权在每种情况下都适用吗?看起来奇怪的是,函数调用的优先级不会是常量,但如果它确实是常量的话,它就不会包含在上面的帮助页面中.

Ale*_*own 9

函数调用的优先级不变的

R非常像lisp,引擎盖下.

它有lisp 这样的SEXP ; SEXP是一个元组(列表),其中元组的第一个元素([[1]])是运算符,其余元素(通常是其他SEXP)是运算符的参数.

当你写作

paste("a",1 + 2)
Run Code Online (Sandbox Code Playgroud)

R明白了

(`paste`,"a",(`+`, 1, 2))
Run Code Online (Sandbox Code Playgroud)

当您运行替换时,您将获得SEXP(尽管它们像R代码一样打印),并且(最外层)SEXP的第一个元素是将在表达式中应用的最后一个运算符 - 即最低优先级.

您可能知道,您可以使用以下内容查看表达式的各个部分:

> str(as.list(quote(a^b())))
List of 3
 $ : symbol ^
 $ : symbol a
 $ : language b()
Run Code Online (Sandbox Code Playgroud)

要将此理解应用于示例中的优先级.

什么是最后一个运营商a^b()

让我们逐步考虑它

  1. 替代和评估 a
  2. 替代和评估 b
  3. 评估(步骤的结果)2没有参数(这称为调用)
  4. 替代和评估 ^
  5. 4用参数评估13

所以最后一个运算符是名为的值 ^

接下来,最后一个运算符是a[b]()什么?

  1. 替代和评估 a
  2. 替代和评估 b
  3. 替代和评估 [
  4. 3用参数(步骤的结果)1和(步骤的结果)评估(步骤的结果)2
  5. 评估(步骤的结果) 4

在这种情况下(步骤的结果)4具有方便的名称a[b].

因此,最后一个运算符是一个调用(没有参数的求值)a[b].


编辑:警告

我简化了这里的实际情况,因为由于R的特殊性,函数参数作为未评估(环境,表达式)对传递给函数(运算符),而不是通过引用或通过值传递,而'commit'订单与上述大致相同,实际的发货订单实际上是相反的 - 甚至是错过了步骤.但是,您还不必担心.