Symbols

A symbol represents the name of an object like x, mtcars, or mean,
创建symbols的两种办法

  1. # capturing code that references an object with expr()
  2. expr(x)
  3. #> x
  4. # turning a string into a symbol with rlang::sym():
  5. sym("x")
  6. #> x

calls

Function position

The first element of the call object is the function position

当函数不存在于当前的环境,例如在一个package中,属于R6对象的方法,或者由函数工厂(闭包)创造出来的。这时候的function position会被其他的call 占用

  1. lobstr::ast(pkg::foo(1))
  2. #> █─█─`::`
  3. #> │ ├─pkg
  4. #> │ └─foo
  5. #> └─1
  6. lobstr::ast(obj$foo(1))
  7. #> █─█─`$`
  8. #> │ ├─obj
  9. #> │ └─foo
  10. #> └─1
  11. lobstr::ast(foo(1)(2))
  12. #> █─█─foo
  13. #> │ └─1
  14. #> └─2

image.png

Constructing

你可以自己使用 rlang::call2() 去构造自己的一个 function call :
规则:

  1. 第一个参数: function call的名字
  2. 剩余的参数是传递给这个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)

  1. Infix calls的函数也可以用类似的方法创建
  2. ```r
  3. call2("<-", expr(x), 10)
  4. #> 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
例如:

  1. geom_point() + geom_smooth()
  2. #does not yield the same plot as
  3. 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.

  1. lobstr::ast(2^2^3)
  2. #> █─`^`
  3. #> ├─2
  4. #> └─█─`^`
  5. #> ├─2
  6. #> └─3
  7. lobstr::ast(x <- y <- z)
  8. #> █─`<-`
  9. #> ├─x
  10. #> └─█─`<-`
  11. #> ├─y
  12. #> └─z

指数运算和赋值是从右边开始的

Parsing and deparsing

如果你想把一个储存在string中的code,parse出来,这时候你可以使用

  1. x1 <- "y <- x + 10"
  2. x1
  3. #> [1] "y <- x + 10"
  4. is.call(x1)
  5. #> [1] FALSE
  6. x2 <- rlang::parse_expr(x1)
  7. x2
  8. #> y <- x + 10
  9. is.call(x2)
  10. #> [1] TRUE

parse_expr只能返回一个表达式,如果你需要同时parsing多个表达式,可以使用parse_exprs()

  1. x3 <- "a <- 1; a + 1"
  2. rlang::parse_exprs(x3)
  3. #> [[1]]
  4. #> a <- 1
  5. #>
  6. #> [[2]]
  7. #> a + 1

The base equivalent to parse_exprs() is parse()
但是parse需要把string提供给text这个参数,最总他返回的是expression vector

  1. parse(text = x1)
  2. #> expression(y <- x + 10)
  3. as.list(parse(text = x1))
  4. #> [[1]]
  5. #> y <- x + 10

paring的对立面是deparing

  1. z <- expr(y <- x + 10)
  2. expr_text(z) #deparse
  3. #> [1] "y <- x + 10"

但parse和deparing不是完全对称相反的;paring产生的是AST,但是