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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With