It seems odd/inconvenient to me that the "ignore.environment" argument of identical() only applies to closures (which I read as 'functions' -- someone can enlighten me about the technical differences between functions and closures if they like -- see below for consequences of my confusion). This is certainly not a bug, it's clearly documented, but it seems like a design flaw. It would certainly be convenient to be able to ignore differences in environments when comparing complex objects with lots of deeply nested formula and terms objects with environments ... Can anyone suggest a reason for this design? Example:> f1 <- formula() > f2 <- formula() > environment(f2) <- new.env() > identical(f1,f2)[1] FALSE> identical(f1,f2,ignore.environment=TRUE)[1] FALSE Actually, maybe I don't understand how this is supposed to work since I thought this would be TRUE:> f1 <- function() {} > f2 <- function() {} > environment(f1) <- new.env() > environment(f2) <- new.env() > identical(f1,f2,ignore.environment=TRUE) ## FALSEMaybe the problem *is* that I don't know the difference between a function and a closure ... ? Ben Bolker
On 11/10/2015 8:05 PM, Ben Bolker wrote:> > It seems odd/inconvenient to me that the "ignore.environment" argument > of identical() only applies to closures (which I read as 'functions' -- > someone can enlighten me about the technical differences between > functions and closures if they like -- see below for consequences of my > confusion). This is certainly not a bug, it's clearly documented, but > it seems like a design flaw. It would certainly be convenient to be > able to ignore differences in environments when comparing complex > objects with lots of deeply nested formula and terms objects with > environments ... > > Can anyone suggest a reason for this design? > > Example: > >> f1 <- formula() >> f2 <- formula() >> environment(f2) <- new.env() >> identical(f1,f2) > [1] FALSE >> identical(f1,f2,ignore.environment=TRUE) > [1] FALSE > > Actually, maybe I don't understand how this is supposed to work since I > thought this would be TRUE: > >> f1 <- function() {} >> f2 <- function() {} >> environment(f1) <- new.env() >> environment(f2) <- new.env() >> identical(f1,f2,ignore.environment=TRUE) ## FALSEThose two functions likely have different srcref attributes. If you created f2 using f2 <- f1, you'd get your expected result.> > Maybe the problem *is* that I don't know the difference between a > function and a closure ... ?In R, there is no difference. All functions are closures. Some people only use "closure" for functions returned as the value of other functions. That may be correct usage in other languages, but not in R. Duncan Murdoch
On 11/10/2015 10:36 PM, Duncan Murdoch wrote:> On 11/10/2015 8:05 PM, Ben Bolker wrote: >> >> It seems odd/inconvenient to me that the "ignore.environment" argument >> of identical() only applies to closures (which I read as 'functions' -- >> someone can enlighten me about the technical differences between >> functions and closures if they like -- see below for consequences of my >> confusion). This is certainly not a bug, it's clearly documented, but >> it seems like a design flaw. It would certainly be convenient to be >> able to ignore differences in environments when comparing complex >> objects with lots of deeply nested formula and terms objects with >> environments ... >> >> Can anyone suggest a reason for this design? >> >> Example: >> >>> f1 <- formula() >>> f2 <- formula() >>> environment(f2) <- new.env() >>> identical(f1,f2) >> [1] FALSE >>> identical(f1,f2,ignore.environment=TRUE) >> [1] FALSE >> >> Actually, maybe I don't understand how this is supposed to work since I >> thought this would be TRUE: >> >>> f1 <- function() {} >>> f2 <- function() {} >>> environment(f1) <- new.env() >>> environment(f2) <- new.env() >>> identical(f1,f2,ignore.environment=TRUE) ## FALSE > > Those two functions likely have different srcref attributes. If you > created f2 using f2 <- f1, you'd get your expected result. > >> >> Maybe the problem *is* that I don't know the difference between a >> function and a closure ... ? > > In R, there is no difference. All functions are closures. > > Some people only use "closure" for functions returned as the value of > other functions. That may be correct usage in other languages, but not > in R.Sorry, I meant all user functions are closures. There are other kinds of function in R called "primitives" (e.g. c(), many low level math functions, the functions that implement flow control, etc.). Duncan Murdoch