Reputation: 2269
I came across this example in Advanced R by Hadley. My question is after defining the function, j(1) outputs the inner function definition as supposed to what j(1)() is outputting? Intuitively, I think j(1) should output [1] 1 2
Could anyone explain what's going on actually? What's the difference between j(1) and j(1)() ?
> j <- function(x) {
+ y <- 2
+ function() {
+ c(x,y)
+ }
+ }
> k <- j(1)
> k()
[1] 1 2
> j(1)
function() {
c(x,y)
}
<environment: 0x7fa184353bf8>
> j()
function() {
c(x,y)
}
<environment: 0x7fa18b5ad0d0>
> j(1)()
[1] 1 2
Upvotes: 2
Views: 705
Reputation: 99331
tl;dr In R, the return value of a function can also be a function. That's the case here. j(1)
returns a function, whereas j(1)()
returns a numeric vector.
The difference between j(1)
and j(1)()
is that j(1)
outputs a function because that's the last value in the definition of j
. Functions return their last expression (or the value found in a relevant return()
call), which in this case is also a function. j(1)()
is calling the last value of j
, which is the function returned from it. It does not take an argument, so the empty parentheses ()
is the argument list for j(1)
It might become a bit more clear if we have a closer look at j
and some of its properties.
j <- function(x) {
y <- 2
function() {
c(x, y)
}
}
The difference between the calls becomes quite apparent when we look at their classes.
class(j(1))
# [1] "function"
class(j(1)())
# [1] "numeric"
When you defined j
, 2 is hard-coded into its return function as the second value of the vector returned from that function. We can see the precise return value of a call to j(1)
with
library(pryr)
unenclose(j(1))
# function ()
# {
# c(1, 2)
# }
So a call to j(1)()
(or k()
) will deliver the vector c(1, 2)
. Similarly, if we call j(5)
, the return value of j(5)()
is c(5, 2)
unenclose(j(5))
# function ()
# {
# c(5, 2)
# }
Hope that helps.
Credit to @Khashaa for mentioning the unenclose()
function (comment deleted).
Upvotes: 7