Open deakjahn opened 1 year ago
It's not unavoidable, but it gets harder to parse when the thing inside the pattern can be either a destructuring or a an assignable expression. Currently the only assignable expressions allowed are plain identifiers, and only ones referring to local variables.
Nothing prevents allowing more assignable selectors, like:
(foo.x, elements[0], z /* non-local variable in scope */) = (1, 2, 3);
We just need to be absolutely sure we can parse it correctly, and that it's also readable by humans.
Allowing any selector means allowing any expression to start the position, because:
(expression.foo,) = (1,);
allows any expression (which has a type which has a foo
setter), so it opens up a large can of worms to allow general assignable expressions.
As a first step, the "plain identifiers" restriction would seem acceptable to me but not only to local variables. Straight fields, in my opinion, might be needed in this place very often.
Even that restriction can get weird because you could still be invoking a setter method or initializing a late
field. It's probably tractable and I can see us enabling this at some point. The initial version of the proposal did. But it does get sort of complex which is why we don't currently allow it.
As a first step, the "plain identifiers" restriction would seem acceptable to me but not only to local variables. Straight fields, in my opinion, might be needed in this place very often.
Totally agree. My use case was about assigning values to instance variables.
I just ran into this today in a review. I wanted to suggest that a serialized set of async tasks could use the record .wait
extension, but I can't do it when some of the assignments are to class fields.
Yeah, it's a reasonable extension, we just have to work through all of the consequences around late
and lazy statics.
Also, if we allow irrefutable pattern assignment expressions to assign to fields, then users might also expect patterns in field and top-level declarations, like:
class C {
final (int x, int y);
}
Then we have to figure out how that interacts with late
and initializer lists.
Trying to decompose a record to class fields gives the error "Only local variables can be assigned in pattern assignments". Is this unavoidable? Couldn't it be solved so that we can assign to class fields as well?