language icon indicating copy to clipboard operation
language copied to clipboard

Should we allow `&` patterns as the outermost pattern in variable declarations and assignments?

Open munificent opened this issue 2 years ago • 1 comments

The patterns proposal restricts the grammar slightly for what patterns can appear as the outermost pattern in a variable declaration and pattern assignment:

outerPattern        ::= parenthesizedPattern
                      | listPattern
                      | mapPattern
                      | recordPattern
                      | extractorPattern

The outerPattern rule defines a subset of the patterns that are allowed as the outermost pattern in a declaration. Subsetting allows useful code like:

var [a, b] = [1, 2];                      // List.
var {1: a} = {1: 2};                      // Map.
var (a, b, x: x) = (1, 2, x: 3);          // Record.
var Point(x: x, y: y) = Point(1, 2);      // Extractor.

var [a, b] & c = [1, 2];

But excludes other kinds of patterns to prohibit weird code like:

// Not allowed:
var String str = 'redundant';     // Variable.
var str as String = 'weird';      // Cast.
var definitely! = maybe;          // Null-assert.

Allowing parentheses gives users an escape hatch if they really want to use an unusual pattern there.

This currently forbids & patterns. But one important use for those is to bind a value to a name while also destructuring it, as in:

switch (makePoint()) {
  case (var x, var y) & var point: print('Point $point has coordinates $x and $y.');
}

This is equally useful in pattern variable declarations and maybe assignments. Should we extend outerPattern to include & patterns too? If no, users can still get to it by parenthesizing:

var ((x, y) & point) = makePoint();

But the outer parentheses seem unnecessary. Should we allow omitting them?

munificent avatar Sep 13 '22 18:09 munificent

We could also omit the parentheses for p! and ! as T then. I think the leading var/final and trailing = is still enough to disambiguate what's going on. Then the declaration will just be ('var'|'final') andPattern '=' expression ';'. (The original var v = e; would be a special case of pattern declaration then.)

I'm leaning towards not allowing that. I'd even consider removing parenthesizedPattern from outerPattern, to restrict uses to only the destucturing. I'm not sure the extra power is necessary. (I could very easily be wrong, though.)

lrhn avatar Sep 14 '22 17:09 lrhn

I'm going to decide that the answer to this is "no". We can always add it later if it becomes desirable.

munificent avatar Jan 20 '23 01:01 munificent