From winstonchang1 at gmail.com  Wed Oct 29 21:58:46 2014
From: winstonchang1 at gmail.com (Winston Chang)
Date: Wed, 29 Oct 2014 15:58:46 -0500
Subject: [Rd] Unexpected behavior of identical() with language objects
In-Reply-To: <CABdHhvGtKp4-J6G--aJ1+Y-rNbugOtW0kzjuevvm_EdQTANnJw@mail.gmail.com>
References: <CAFOpNVGxxqH0uYjouj6rG9b9LdbigQQbNDWgvS8NxhYnn61F8A@mail.gmail.com>
	<CAPPM_gQJFLHPs__OwVyNuftkWz2X7+sn_LwRzfpgrT6qdg37nw@mail.gmail.com>
	<CABdHhvGtKp4-J6G--aJ1+Y-rNbugOtW0kzjuevvm_EdQTANnJw@mail.gmail.com>
Message-ID: <CAFOpNVEnue7m5yViF6PzQ7jixZgykTZ+-h3+BxSm0Xz5JWtECw@mail.gmail.com>

Ah, I was using identical() to compare two function bodies. It returns
FALSE even when you remove srcrefs from the body:

f1 <- function(x) {
  if (TRUE) { x }
}
f2 <- function(x) {
  if (TRUE) { x }
}
f1b <- body(f1)
f2b <- body(f2)
attributes(f1b) <- NULL
attributes(f2b) <- NULL

# The bodies look the same with str()
str(f1b)
#  language {  if (TRUE) {; x; } }
str(f2b)
#  language {  if (TRUE) {; x; } }

identical(f1b, f2b)
# FALSE



What I didn't realize was that the curly brace inside the body also
independently captures srcrefs, but this isn't printed with str(f1b).
However, str() on a more targeted part of the object reveals them:
str(f1b[[2]][[3]])
# length 2 {  x }
#  - attr(*, "srcref")=List of 2
#   ..$ :Class 'srcref'  atomic [1:8] 2 13 2 13 13 13 2 2
#   .. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile'
<environment: 0x452b2c0>
#   ..$ :Class 'srcref'  atomic [1:8] 2 15 2 15 15 15 2 2
#   .. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile'
<environment: 0x452b2c0>
#  - attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment:
0x452b2c0>
#  - attr(*, "wholeSrcref")=Class 'srcref'  atomic [1:8] 1 0 2 17 0 17 1 2
#   .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile'
<environment: 0x452b2c0>

-Winston

On Wed, Oct 29, 2014 at 3:46 PM, Hadley Wickham <h.wickham at gmail.com> wrote:
>>> Is this expected behavior? I can't seem to find anything in the help
>>> for identical that relates to this.
>>>
>> It's not in ?identical, but ?Paren gives you some pointers.
>> str(quote((a))) and str(quote({a})) are also informative.
>
> Yes, looks like srcrefs are to blame:
>
> x <- quote({ a })
> y <- quote({ a })
>
> identical(x, y)
> # [1] FALSE
>
> attr(x, "srcref") <- NULL
> attr(x, "srcfile") <- NULL
> attr(x, "wholeSrcref") <- NULL
>
> attr(y, "srcref") <- NULL
> attr(y, "srcfile") <- NULL
> attr(y, "wholeSrcref") <- NULL
> identical(x, y)
> # [1] TRUE
>
> Maybe identical() needs an ignore.srcref option? Normally when
> comparing expressions or functions, you want to compare the code, not
> it's textual representation.
>
> Hadley
>
> --
> http://had.co.nz/



[Rd] Unexpected behavior of identical() with language objects
Winston Chang