[Rd] identical(..., ignore.environment=TRUE)

Martin Maechler maechler at stat.math.ethz.ch
Tue Oct 13 17:39:35 CEST 2015


>>>>> Duncan Murdoch <murdoch.duncan at gmail.com>
>>>>>     on Mon, 12 Oct 2015 19:31:11 -0400 writes:

    > On 12/10/2015 9:51 AM, Ben Bolker wrote:
    >> Duncan Murdoch <murdoch.duncan <at> gmail.com> writes:
    >> 
    BB> 
    >>>>> 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?
    >>>>> 
    >> 
    >> [snip]
    >> 
    >>>>> 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.
    >>>> 
    >> 
    >> [snip]
    >> 
    >> Thanks for the clarification about closures
    >> vs. functions.
    >> 
    >> [snip]
    >> 
    >> You're right that the srcref attributes are different;
    >> although their bodies are the same, they have their own
    >> environments that differ.  For me, this makes the
    >> intended use of ignore.environment= even more puzzling;
    >> given that environments are not ignored recursively
    >> (that's not exactly what I mean -- I mean ignoring all
    >> environments of components of an object), I have trouble
    >> understanding the use case for ignore.environnment ...
    >> maybe it was developed before srcrefs existed?

    > I think it simply means "ignore.environment.of.closures",
    > as the description says, but that's too long to be a
    > convenient arg name.

    > Closures have three parts: the formals, the body and the
    > environment.  (Actually, 4 parts: like almost all R
    > objects, they may also have attributes.)

    > That arg just says to ignore the environment part when
    > comparing closures.  It doesn't say to ignore environments
    > in general.

For another beat on a dead horse, @ Ben:

You could either use  options(keep.source = FALSE) in your
enviroment such that your functions should not have any 'srcref'
attributes anymore,

or probably more sensible, use

all.equal(f1, f2) rather than identical(f1, f2, ..)

which I think should really do what you want
[even though it ends up using string comparison after deparse(.)
 .. about which one can debate... but I don't think we'd want to
 change  all.equal.language()  at this point in time].

Martin


    >> 
    >> In the R code base it's used in checkConflicts (to see if
    >> a function is re-exported) and in getAnywhere ...
    >> 

    > I'd say those uses are slightly bogus.  You should
    > generally remember that closures have 3 (or 4) parts, and
    > not go around comparing only two (or 3) of them.

    > Duncan Murdoch

    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list