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.> > 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
>>>>> 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
MM> but I don't think we'd want to MM> change all.equal.language() at this point in time Although it would be nice if all.equal looked at least at attributes of formulas so we did not get results like > form <- y ~ x1 %in% x2 > all.equal(form, terms(form)) [1] TRUE > all.equal(terms(y~x1+x2+Error(x3/x2), specials="Error"), terms(y~x1+x2+Error(x3/x2))) [1] TRUE Bill Dunlap TIBCO Software wdunlap tibco.com On Tue, Oct 13, 2015 at 8:39 AM, Martin Maechler <maechler at stat.math.ethz.ch> wrote:> >>>>> 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 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]