Приоритет вызова функции является постоянным
R очень похож на lisp, только внутри.
Есть SEXP, например lisp; SEXP — это кортеж (список), где первый элемент ([[1]]
) кортежа является оператором, а остальные элементы (которые обычно сами являются другими SEXP) являются аргументами оператора.
Когда вы пишете
paste("a",1 + 2)
Р понимает
(`paste`,"a",(`+`, 1, 2))
Когда вы запускаете замену, вы получаете SEXP (хотя они красиво печатаются, как код R), и первым элементом (самого внешнего) SEXP является оператор last, который будет применяться в выражении - то есть самый низкий приоритет.
Как вы, наверное, знаете, вы можете просмотреть части выражения, используя что-то вроде:
> str(as.list(quote(a^b())))
List of 3
$ : symbol ^
$ : symbol a
$ : language b()
Чтобы применить это понимание к приоритету в вашем примере.
Какой последний оператор a^b()
?
Рассмотрим поэтапно
- заменить и оценить
a
- заменить и оценить
b
- оценить (результат шага)
2
без аргументов (это называется вызовом)
- заменить и оценить
^
- оценить
4
с аргументами 1
и 3
Таким образом, последний оператор — это значение с именем ^
.
Далее, какой последний оператор a[b]()
?
- заменить и оценить
a
- заменить и оценить
b
- заменить и оценить
[
- оценить (результат шага)
3
с аргументами (результат шага) 1
и (результат шага) 2
- оценить (результат шага)
4
В этом случае (результат шага) 4
имеет удобное имя a[b]
.
Таким образом, последний оператор является вызовом (оценка без аргументов) a[b]
.
Изменить: предостережение
Я упростил здесь реальную ситуацию, потому что из-за особенности R, в силу которой аргументы функции передаются как невычисленные пары (окружение, выражение) функциям (операторам) (а не по ссылке или по значению), в то время как 'commit' порядок примерно такой же, как указано выше, реальный порядок отправки на самом деле обратный - или даже пропускает шаги. Однако вам пока не нужно беспокоиться об этом.
person
Alex Brown
schedule
15.05.2014