Symbols
A symbol represents the name of an object like x, mtcars, or mean,
创建symbols的两种办法
# capturing code that references an object with expr()
expr(x)
#> x
# turning a string into a symbol with rlang::sym():
sym("x")
#> x
calls
Function position
The first element of the call object is the function position
当函数不存在于当前的环境,例如在一个package中,属于R6对象的方法,或者由函数工厂(闭包)创造出来的。这时候的function position会被其他的call 占用
lobstr::ast(pkg::foo(1))
#> █─█─`::`
#> │ ├─pkg
#> │ └─foo
#> └─1
lobstr::ast(obj$foo(1))
#> █─█─`$`
#> │ ├─obj
#> │ └─foo
#> └─1
lobstr::ast(foo(1)(2))
#> █─█─foo
#> │ └─1
#> └─2
Constructing
你可以自己使用 rlang::call2() 去构造自己的一个 function call :
规则:
- 第一个参数: function call的名字
- 剩余的参数是传递给这个call的
```r
call2(“mean”, x = expr(x), na.rm = TRUE)
> mean(x = x, na.rm = TRUE)
这里的x = expr(x), 如果使用的是x = x
call2(“mean”, x = x, na.rm = TRUE)> Error in call2(“mean”, x = x, na.rm = TRUE) : object ‘x’ not found
call2(expr(base::mean), x = expr(x), na.rm = TRUE)
> base::mean(x = x, na.rm = TRUE)
Infix calls的函数也可以用类似的方法创建
```r
call2("<-", expr(x), 10)
#> x <- 10
summary
str() | typeof() | |
---|---|---|
Scalar constant | logi/int/num/chr | logical/integer/double/character |
Symbol | symbol | symbol |
Call object | language | language |
Pairlist | Dotted pair list | pairlist |
Expression vector | expression() | expression |
Parsing and grammar
从一个string的格式变成一个expression的格式,这个过程叫parsing。这个过程遵循一定的规则,这个规则叫做grammar。
Operator precedence
Infix functions,有一套自己的operator precedence的方法去解决算数运算顺序的问题
Associativity
相加性:
使用同样的infix function可能带来第二个模糊点
addition is associative,但是一个S3类型确是—— non-associative way
例如:
geom_point() + geom_smooth()
#does not yield the same plot as
geom_smooth() + geom_point()
In R, most operators are left-associative, i.e. the operations on the left are evaluated first. There are two exceptions: exponentiation and assignment.
lobstr::ast(2^2^3)
#> █─`^`
#> ├─2
#> └─█─`^`
#> ├─2
#> └─3
lobstr::ast(x <- y <- z)
#> █─`<-`
#> ├─x
#> └─█─`<-`
#> ├─y
#> └─z
指数运算和赋值是从右边开始的
Parsing and deparsing
如果你想把一个储存在string中的code,parse出来,这时候你可以使用
x1 <- "y <- x + 10"
x1
#> [1] "y <- x + 10"
is.call(x1)
#> [1] FALSE
x2 <- rlang::parse_expr(x1)
x2
#> y <- x + 10
is.call(x2)
#> [1] TRUE
parse_expr只能返回一个表达式,如果你需要同时parsing多个表达式,可以使用parse_exprs()
x3 <- "a <- 1; a + 1"
rlang::parse_exprs(x3)
#> [[1]]
#> a <- 1
#>
#> [[2]]
#> a + 1
The base equivalent to parse_exprs() is parse()
但是parse需要把string提供给text这个参数,最总他返回的是expression vector
parse(text = x1)
#> expression(y <- x + 10)
as.list(parse(text = x1))
#> [[1]]
#> y <- x + 10
paring的对立面是deparing
z <- expr(y <- x + 10)
expr_text(z) #deparse
#> [1] "y <- x + 10"
但parse和deparing不是完全对称相反的;paring产生的是AST,但是