On Sun, 27 Aug 2023, Duncan Murdoch wrote:

I think there isn't a way to make this work other than calling `is.na<-` explicitly:

 x <- b$`is.na<-`(x, TRUE)


Replacement functions are not intended to be called directly. Calling
a replacement function directly may produce an error, or may just do
the wrong thing in terms of mutation.

It seems like a reasonable suggestion to make

 b$is.na(x) <- TRUE

work as long as b is an environment.


I do not think it is a reasonable suggestion. The reasons a::b and
a:::b were made to work is that many users read these as a single
symbol, not a call to a binary operator. So supporting this helped to
reduce confusion.

Allowing $<- to "work" on environments was probably a mistake since
environments behave differently with respect to
duplication. Disallowing it entirely may be too disruptive at this
point, but disallowing it in complex assignment expressions may be
necessary to prevent mutations that should not happen. (There are open
bug reports that boil down to this.)

In any case, complicating the complex assignment code, which is
already barely maintainable, would be a very bad idea.

Best,

luke

If you wanted it to work when b was a list, it would be more problematic because of partial name matching. E.g. suppose b was a list containing functions partial(), partial<-(), and part<-(), and I call

 b$part(x) <- 1

what would be called?

Duncan Murdoch

On 27/08/2023 10:59 a.m., Konrad Rudolph wrote:
Hello all,

I am wondering whether it’s at all possible to call a replacement function
in a custom environment. From my experiments this appears not to be the
case, and I am wondering whether that restriction is intentional.

To wit, the following works:

x = 1
base::is.na(x) = TRUE

However, the following fails:

x = 1
b = baseenv()
b$is.na(x) = TRUE

The error message is "invalid function in complex assignment". Grepping the
R code for this error message reveals that this behaviour seems to be
hard-coded in function `applydefine` in src/main/eval.c: the function
explicitly checks for `::` and :::` and permits those assignments, but has
no equivalent treatment for `$`.

Am I overlooking something to make this work? And if not — unless there’s a
concrete reason against it, could it be considered to add support for this
syntax, i.e. for calling a replacement function by `$`-subsetting the
defining environment, as shown above?

Cheers,
Konrad


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


--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
   Actuarial Science
241 Schaeffer Hall                  email:   luke-tier...@uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to