[Rd] Multiple Assignment built into the R Interpreter?
Duncan Murdoch
murdoch@dunc@n @end|ng |rom gm@||@com
Sat Mar 11 19:38:42 CET 2023
On 11/03/2023 11:57 a.m., Ivan Krylov wrote:
> On Sat, 11 Mar 2023 11:11:06 -0500
> Duncan Murdoch <murdoch.duncan using gmail.com> wrote:
>
>> That's clear, but your proposal violates a very basic property of the
>> language, i.e. that all statements are expressions and have a value.
>
> How about reframing this feature request from multiple assignment
> (which does go contrary to "everything has only one value, even if it's
> sometimes invisible(NULL)") to "structured binding" / "destructuring
> assignment" [*], which takes this single single value returned by the
> expression and subsets it subject to certain rules? It may be easier to
> make a decision on the semantics for destructuring assignment (e.g.
> languages which have this feature typically allow throwing unneeded
> parts of the return value away), and it doesn't seem to break as much
> of the rest of the language if implemented.
>
> I see you've already mentioned it ("JavaScript-like"). I think it would
> fulfil Sebastian's requirements too, as long as it is considered "true
> assignment" by the rest of the language.
>
> The hard part is to propose the actual grammar of the new feature (in
> terms of src/main/gram.y, preferably without introducing conflicts) and
> its semantics (including the corner cases, some of which you have
> already mentioned). I'm not sure I'm up to the task.
>
If I were doing it, here's what I'd propose:
'[' formlist ']' LEFT_ASSIGN expr
'[' formlist ']' EQ_ASSIGN expr
expr RIGHT_ASSIGN '[' formlist ']'
where `formlist` has the syntax of the formals list for a function
definition. This would have the following semantics:
{
*tmp* <- expr
# For arguments with no "default" expression,
argname1 <- *tmp*[[1]]
argname2 <- *tmp*[[2]]
...
# For arguments with a default listed
argname3 <- with(*tmp*, default3)
}
The value of the whole thing would therefore be (invisibly) the value of
the last item in the assignment.
Two examples:
[A, B, C] <- expr # assign the first three elements of expr to A,
B, and C
[A, B, C = a + b] <- expr # assign the first two elements of expr
# to A and B,
# assign with(expr, a + b) to C.
Unfortunately, I don't think this could be done entirely by transforming
the expression (which is the way |> was done), and that makes it a lot
harder to write and to reason about. E.g. what does this do?
A <- 0
[A, B = A + 10] <- list(1, A = 2)
According to the recipe above, I think it sets A to 1 and B to 12, but
maybe a user would expect B to be 10 or 11. And according to that
recipe this is an error:
[A, B = A + 10] <- c(1, A = 2)
which probably isn't what a user would expect, given that this is fine:
[A, B] <- c(1, 2)
Duncan Murdoch
More information about the R-devel
mailing list