The precedence of a function call is constant
R is very very much like lisp, under the hood.
It has SEXPs like lisp; an SEXP is a tuple (list) where the first element ([[1]]
) of the tuple is the operator, and the remaining elements (which are commonly themselves other SEXPs) are the arguments to the operator.
When you write
paste("a",1 + 2)
R understands
(`paste`,"a",(`+`, 1, 2))
When you run substitute, you are getting the SEXPs (although they pretty-print like R code), and the first element of the (outermost) SEXP is the last operator which will be applied in the expression - i.e. the lowest precedence.
As you probably know, you can view the parts of the expression using something like:
> str(as.list(quote(a^b())))
List of 3
$ : symbol ^
$ : symbol a
$ : language b()
To apply this understanding to precedence in your example.
What is the last operator of a^b()
?
Let's consider it stepwise
- substitute and evaluate
a
- substitute and evaluate
b
- evaluate (result of step)
2
with no arguments (this is known as a call)
- substitute and evaluate
^
- evaluate
4
with arguments 1
and 3
So the last operator is the value named ^
Next, what is the last operator of a[b]()
?
- substitute and evaluate
a
- substitute and evaluate
b
- substitute and evaluate
[
- evaluate (result of step)
3
with arguments (result of step) 1
and (result of step) 2
- evaluate (result of step)
4
In this case (result of step) 4
has the convenient name a[b]
.
The last operator is therefore a call (evaluation with no arguments) to a[b]
.
Edit: Caveat
I have simplified the real situation here, because owing to a peculiarity of R, whereby function arguments are passed as unevaluated (environment, expression) pairs to functions (operators), (rather than by reference or by value), while the 'commit' order is roughly the same as the above, the real dispatch order is actually the reverse - or even misses out steps. However, you don't need to worry about that yet.
[[1]]
since that was not really in the expression. Do you agree? – Chaffee