[Rd] Unexpected behaviour when comparing (==) long quoted expressions
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Tue Jul 16 10:35:36 CEST 2019
>>>>> Daniel Chen
>>>>> on Fri, 12 Jul 2019 13:53:21 -0500 writes:
> Hi everyone:
> I’m one of the interns at RStudio this summer working on a project that
> helps teachers grade student code. I found an unexpected behaviour with
> the |==| operator when comparing |quote|d expressions.
> Example 1:
> |u <- quote(tidyr::gather(key = key, value = value,
> new_sp_m014:newrel_f65, na.rm = TRUE)) s <- quote(tidyr::gather(key =
> key, value = value, new_sp_m014:newrel_f65, na.rm = FALSE)) u == s #
> TRUE u <- quote(tidyr::gather(key = key, value = value, na.rm = TRUE)) s
> <- quote(tidyr::gather(key = key, value = value, na.rm = FALSE)) u == s
> # FALSE |
Unfortunately the above is almost unreadable, as you "forgot" to
click (in the lower right corner of your Gmail interface with
the three vertical dots) "plain text mode".
> Example 2:
> |u <-
> quote(f(x123456789012345678901234567890123456789012345678901234567890,
> 1)) s <-
> quote(f(x123456789012345678901234567890123456789012345678901234567890,
> 2)) u == s #> [1] TRUE |
this is even readable after html - de-html mangling
> Winston Chang pointed out in the help page for |==|:
> Language objects such as symbols and calls are deparsed to character
> strings before comparison.
> and in the source code that does the comparison [1] shows that It
> deparses each language object and then only extracts the first element
> from the resulting character vector:
> |SET_STRING_ELT(tmp, 0, (iS) ? PRINTNAME(x) : STRING_ELT(deparse1(x, 0,
> DEFAULTDEPARSE), 0)); |
> Is this a fix that needs to happen within the |==| documentation? or an
> actual bug with the operator?
This a good question.
Thank you, Daniel, for providing the link to the source code in
<R>/src/main/relop.c .
Looking at that and its context, I think we (R core) should
reconsider that implementation of '==' which indeed does about
the same thing as deparse {which also truncates at some point by
default; something very very reasonable for error messages, but
undesirable in other cases}.
But I think it's fair expectation that comparing calls ["language"]
with '==' should compare the full call's syntax even if that may
occasionally be very long.
Martin
> For more context the original issue we had is here:
> https://github.com/rstudio-education/grader/issues/28
> Workaround:
> You can get around this issue by using |all.equal| or |identical|
> |u <- quote(tidyr::gather(key = key, value = value,
> new_sp_m014:newrel_f65, na.rm = TRUE)) s <- quote(tidyr::gather(key =
> key, value = value, new_sp_m014:newrel_f65, na.rm = FALSE)) u == s #
> TRUE all.equal(u, s) # "target, current do not match when deparsed"
> identical(u, s) # FALSE |
> Thanks,
> Dan
> [1] https://github.com/wch/r-source/blob/e647f78cb85282263f88ea30c6337b77a30743d9/src/main/relop.c#L140-L155
More information about the R-devel
mailing list