From murdoch@dunc@n @end|ng |rom gm@||@com  Sat Mar 11 14:37:24 2023
From: murdoch@dunc@n @end|ng |rom gm@||@com (Duncan Murdoch)
Date: Sat, 11 Mar 2023 08:37:24 -0500
Subject: [Rd] Multiple Assignment built into the R Interpreter?
In-Reply-To: <CAOsNuxBZX87P3-CSv7aX9ZzV_0TDDmX_rwz5RVg2Jv1a1Df9EA@mail.gmail.com>
References: <CAOsNuxBZX87P3-CSv7aX9ZzV_0TDDmX_rwz5RVg2Jv1a1Df9EA@mail.gmail.com>
Message-ID: <015b3842-3ef4-7395-402c-6469295685d4@gmail.com>

I think the standard way to do this in R is given by list2env(), as 
described in a couple of answers on the SO page you linked.

The syntax you proposed would be likely to be confusing in complex 
expressions, e.g.

   f(A, C, Q, R = init_matrices(X, Y, Z))

would obviously not work but wouldn't trigger a syntax error, and

   f((A, C, Q, R = init_matrices(X, Y, Z)))

could work, but looks too much like the previous one.  So I think R 
would want Javascript-like

   [A, C, Q, R] <- init_matrices(X, Y, Z)

instead.  But then the question would come up about how to handle the 
RHS.  Does the function have to return a list?  What if the length of 
the list is not 4?  Or is it just guaranteed to be equivalent to

   temp <- init_matrices(X, Y, Z)
   A <- temp[[1]]
   C <- temp[[2]]
   Q <- temp[[3]]
   R <- temp[[4]]

which would work for other vector types besides lists?

BTW, here's a little hack that almost works:

`vals<-` <- function(x, ..., value) {
    others <- substitute(list(...))
    if (length(others) > 1)
      for (i in seq_along(others)[-1])
        assign(as.character(others[[i]]), value[[i]], envir = 
parent.frame())
    value[[1]]
}

You call it as

  vals(a, b, c) <- 1:3

and it assigns 1 to a, 2 to b, and 3 to c.  It doesn't quite do what you 
want because it requires that a exists already, but b and c don't have to.

Duncan Murdoch

On 11/03/2023 4:04 a.m., Sebastian Martin Krantz wrote:
> Dear R Core,
> 
> working on my dynamic factor modelling package, which requires several
> subroutines to create and update several system matrices, I come back to
> the issue of being annoyed by R not supporting multiple assignment out of
> the box like Matlab, Python and julia. e.g. something like
> 
> A, C, Q, R = init_matrices(X, Y, Z)
> 
> would be a great addition to the language. I know there are several
> workarounds such as the %<-% operator in the zeallot package or my own %=%
> operator in collapse, but these don't work well for package development as
> R CMD Check warns about missing global bindings for the created variables,
> e.g. I would have to use
> 
> A <- C <- Q <- R <- NULL
> .c(A, C, Q, R) %=% init_matrices(X, Y, Z)
> 
> in a package, which is simply annoying. Of course the standard way of
> 
> init <- init_matrices(X, Y, Z)
>   A <- init$A; C <- init$C; Q <- init$Q; R <- init$R
> rm(init)
> 
> is also super cumbersome compared to Python or Julia. Another reason is of
> course performance, even my %=% operator written in C has a non-negligible
> performance cost for very tight loops, compared to a solution at the
> interpretor level or in a primitive function such as `=`.
> 
> So my conclusion at this point is that it is just significantly easier to
> implement such codes in Julia, in addition to the greater performance it
> offers. There are obvious reasons why I am still coding in R and C, thanks
> to the robust API and great ecosystem of packages, but adding this could be
> a presumably low-hanging fruit to make my life a bit easier. Several issues
> for this have been filed on Stackoverflow, the most popular one (
> https://stackoverflow.com/questions/7519790/assign-multiple-new-variables-on-lhs-in-a-single-line)
> has been viewed 77 thousand times.
> 
> But maybe this has already been discussed here and already decided against.
> In that case, a way to browse R-devel archives to find out would be nice.
> 
> Best regards,
> 
> Sebastian
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Multiple Assignment built into the R Interpreter?
Duncan Murdoch