On 11/03/2023 11:57 a.m., Ivan Krylov wrote:
On Sat, 11 Mar 2023 11:11:06 -0500
Duncan Murdoch <murdoch.dun...@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

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

Reply via email to