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

2015-10-13 Thread Martin Maechler
> Duncan Murdoch 
> on Mon, 12 Oct 2015 19:31:11 -0400 writes:

> On 12/10/2015 9:51 AM, Ben Bolker wrote:
>> Duncan Murdoch  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@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2015-10-13 Thread William Dunlap
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  wrote:

> > Duncan Murdoch 
> > on Mon, 12 Oct 2015 19:31:11 -0400 writes:
>
> > On 12/10/2015 9:51 AM, Ben Bolker wrote:
> >> Duncan Murdoch  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@r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2015-10-13 Thread Martin Maechler

> William Dunlap 
> on Tue, 13 Oct 2015 09:12:34 -0700 writes:

> 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

Hmm...  of course, you have a very good point

So,  let me say
"Patches are welcome!"
 (If
   - they include changes to the *.Rd files  [e.g., with an option
  to remain back-bug-compatible]
   - are well tested, e.g., run   'make check-all' )


[Yes, I think I know why they probably won't come from you,
 Bill, unfortunately ..]

Martin


> Bill Dunlap
> TIBCO Software
> wdunlap tibco.com

> On Tue, Oct 13, 2015 at 8:39 AM, Martin Maechler  > wrote:

> > > Duncan Murdoch 
> > > on Mon, 12 Oct 2015 19:31:11 -0400 writes:
> >
> > > On 12/10/2015 9:51 AM, Ben Bolker wrote:
> > >> Duncan Murdoch  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@r-project.org mailing list
> > > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> > 

Re: [Rd] A where() functions that does what exists() does but return the environment when object lives?

2015-10-13 Thread Henrik Bengtsson
On Sat, Oct 10, 2015 at 1:24 AM, Uwe Ligges
 wrote:
> I'd start looking at getAnywhere().

Thanks Uwe, that does indeed provides "where" information.
Unfortunately, I don't see how it will allow me to search environments
similarly/in the same order as exists/get(..., envir, inherits=TRUE)
does it.  getAnywhere() will search everything in any order.  It's a
start though.

Cheers,

Henrik

>
> Best,
> Uwe
>
>
> On 10.10.2015 01:18, Henrik Bengtsson wrote:
>>
>> Hi,
>>
>> exists("foo", inherits=TRUE) check whether an object named "foo"
>> exists, and get("foo", inherits=TRUE) retrieves it.  I'm looking for a
>> similar function to exists() that returns the environment where the
>> object "foo" exists, iff at all.  If not found, NULL is returned.
>> Does that exist?
>>
>> EXAMPLE #1:
>>
>>> sample2 <- base::sample
>>> env <- where("sample2", inherits=TRUE)
>>> env
>>
>> 
>>
>> Note the difference to:
>>
>>> obj <- get("sample2", inherits=TRUE)
>>> environment(obj)
>>
>> 
>>
>>
>> EXAMPLE #2:
>>
>>> a <- 1
>>> foo <- function() { b <- 2; list(a=where("a", inherits=TRUE),
>>> b=where("b", inherits=TRUE)) }
>>> foo()
>>
>> $a
>> 
>> $b
>> 
>>
>>> foo()
>>
>> $a
>> 
>> $b
>> 
>>
>>
>> I do understand that I can implement such a function myself, but I
>> prefer not to.
>>
>> Thanks,
>>
>> Henrik
>>
>> __
>> R-devel@r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] A where() functions that does what exists() does but return the environment when object lives?

2015-10-13 Thread Hadley Wickham
Seems easy enough to write yourself:

where <- function(x, env = parent.frame()) {
if (identical(env, emptyenv()))
return(NULL)
if (exists(x, envir = env, inherits = FALSE))
return(env)
where(x, parent.env(env))
}

sample2 <- base::sample
where("sample2")
#> 
where("sample")
#> 
where("blah")
#> NULL

Hadley

On Fri, Oct 9, 2015 at 6:18 PM, Henrik Bengtsson
 wrote:
> Hi,
>
> exists("foo", inherits=TRUE) check whether an object named "foo"
> exists, and get("foo", inherits=TRUE) retrieves it.  I'm looking for a
> similar function to exists() that returns the environment where the
> object "foo" exists, iff at all.  If not found, NULL is returned.
> Does that exist?
>
> EXAMPLE #1:
>
>> sample2 <- base::sample
>> env <- where("sample2", inherits=TRUE)
>> env
> 
>
> Note the difference to:
>
>> obj <- get("sample2", inherits=TRUE)
>> environment(obj)
> 
>
>
> EXAMPLE #2:
>
>> a <- 1
>> foo <- function() { b <- 2; list(a=where("a", inherits=TRUE), b=where("b", 
>> inherits=TRUE)) }
>> foo()
> $a
> 
> $b
> 
>
>> foo()
> $a
> 
> $b
> 
>
>
> I do understand that I can implement such a function myself, but I
> prefer not to.
>
> Thanks,
>
> Henrik
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



-- 
http://had.co.nz/

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] A where() functions that does what exists() does but return the environment when object lives?

2015-10-13 Thread Hadley Wickham
On Tue, Oct 13, 2015 at 4:43 PM, Hadley Wickham  wrote:
> Seems easy enough to write yourself:
>
> where <- function(x, env = parent.frame()) {
> if (identical(env, emptyenv()))
> return(NULL)
> if (exists(x, envir = env, inherits = FALSE))
> return(env)
> where(x, parent.env(env))
> }
>
> sample2 <- base::sample
> where("sample2")
> #> 

And that returns a random environment because I ran it with
reprex::reprex().  In interactive use it will return 

Hadley

-- 
http://had.co.nz/

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] A where() functions that does what exists() does but return the environment when object lives?

2015-10-13 Thread Uwe Ligges



On 13.10.2015 22:39, Henrik Bengtsson wrote:

On Sat, Oct 10, 2015 at 1:24 AM, Uwe Ligges
 wrote:

I'd start looking at getAnywhere().


Thanks Uwe, that does indeed provides "where" information.
Unfortunately, I don't see how it will allow me to search environments
similarly/in the same order as exists/get(..., envir, inherits=TRUE)
does it.  getAnywhere() will search everything in any order.  It's a
start though.


Ah, in the same order Then you probably need to write some code, but 
sources of the existing functions should allow for a good start, I believe.


Good luck,
Uwe



Cheers,

Henrik



Best,
Uwe


On 10.10.2015 01:18, Henrik Bengtsson wrote:


Hi,

exists("foo", inherits=TRUE) check whether an object named "foo"
exists, and get("foo", inherits=TRUE) retrieves it.  I'm looking for a
similar function to exists() that returns the environment where the
object "foo" exists, iff at all.  If not found, NULL is returned.
Does that exist?

EXAMPLE #1:


sample2 <- base::sample
env <- where("sample2", inherits=TRUE)
env




Note the difference to:


obj <- get("sample2", inherits=TRUE)
environment(obj)





EXAMPLE #2:


a <- 1
foo <- function() { b <- 2; list(a=where("a", inherits=TRUE),
b=where("b", inherits=TRUE)) }
foo()


$a

$b



foo()


$a

$b



I do understand that I can implement such a function myself, but I
prefer not to.

Thanks,

Henrik

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] A where() functions that does what exists() does but return the environment when object lives?

2015-10-13 Thread Henrik Bengtsson
Thanks Uwe and thanks Hadley.  I ended up implementing:

## Emulates R internal findVar1mode() function
## https://svn.r-project.org/R/trunk/src/main/envir.c
where <- function(x, where=-1, envir=if (missing(frame)) { if (where <
0) parent.frame(-where) else as.environment(where) } else
sys.frame(frame), frame, mode="any", inherits=TRUE) {
  tt <- 1
  ## Validate arguments
  stopifnot(is.environment(envir))
  stopifnot(is.character(mode), length(mode) == 1L)
  inherits <- as.logical(inherits)
  stopifnot(inherits %in% c(FALSE, TRUE))

  ## Search
  while (!identical(envir, emptyenv())) {
if (exists(x, envir=envir, mode=mode, inherits=FALSE)) return(envir)
if (!inherits) return(NULL)
envir <- parent.env(envir)
  }

  NULL
}

Here where() provides the same arguments as exists() and get().  It
turns out one needs to tweak the default value for 'envir' argument in
order work the same.

One could argue that where() should always return an environment, i.e.
it should return emptyenv() instead of NULL if the object was not
found.  On the other hand, it's easier to test for is.null(env) than
identical(env, emptyenv()).

/Henrik


On Tue, Oct 13, 2015 at 2:44 PM, Hadley Wickham  wrote:
> On Tue, Oct 13, 2015 at 4:43 PM, Hadley Wickham  wrote:
>> Seems easy enough to write yourself:
>>
>> where <- function(x, env = parent.frame()) {
>> if (identical(env, emptyenv()))
>> return(NULL)
>> if (exists(x, envir = env, inherits = FALSE))
>> return(env)
>> where(x, parent.env(env))
>> }
>>
>> sample2 <- base::sample
>> where("sample2")
>> #> 
>
> And that returns a random environment because I ran it with
> reprex::reprex().  In interactive use it will return  R_GlobalEnv>
>
> Hadley
>
> --
> http://had.co.nz/

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel