Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `{` a class?

Tags:

oop

r

I am interested in ways of modifying base functions with minimal code in R. I know the body function will return the body of any function. So I stored the output of body(basefoo) in a variable bar. Wanting to know more about how this works, I inspect the class of bar. which was "{". I thought that was a strange class. I looked for methods but methods(class="\\{") but it says there are no methods.

Is there a reason why the { class exists? How can one modify or interact with { objects?

like image 686
AdamO Avatar asked May 22 '18 17:05

AdamO


1 Answers

All R code is parsed into a tree before execution (see Expressions from Advanced R for more info). In order to have multiple expressions at any point in the tree, R needs to create a wrapper/container to hold those expressions. And that's basically what the { class represents. It defines a code block. It's a collection of expressions to be evaluated. Think if it like a function where each expression you want to evaluate is a parameter (at least that's how it's stored in the tree). And code blocks simply return the value returned by the last expression. Compare

as.list(quote({a; b}))
# [[1]]
# `{`
# [[2]]
# a
# [[3]]
# b
as.list(quote(c(a, b)))
# [[1]]
# c
# [[2]]
# a
# [[3]]
# b

See how they are turned into similar structures in R? The "function name" is first followed by the list of parameters. You can even call { like a regular function

`{`(a<-1, 5, a+2)
# [1] 3

(note how the last value is the only one returned). Also note that code blocks do not create their own scope so the variable a will be defined in the global environment if you run this at the console.

You can create an object of this type by just quoting a code block

class(xx <- quote({a; b}))
# [1] "{"
xx
# {
#     a
#     b
# }

or by building a call with quoted symbols

class(xx <- as.call(list(quote(`{`), quote(a), quote(b))))
# [1] "{"
xx
# {
#     a
#     b
# }

And it's not always the case the body of a function will be of { class. For example

x <- function(a) a+1
y <- function(a) {b <- sqrt(a); b+2}
class(body(x))
# [1] "call"
class(body(y))
# [1] "{"

because we wanted to run more than one statement in the y function we had to put those expressions in a code block. Since x is only calling one expression we didn't need to use { so it has a different class.

like image 198
MrFlick Avatar answered Nov 10 '22 12:11

MrFlick