From 9913d216c7395061ea7f5b16e574d54f4ec84095 Mon Sep 17 00:00:00 2001 From: Anthony Sansone Date: Thu, 21 Mar 2024 13:36:05 -0500 Subject: [PATCH] Clarified parenthetical patterns (#5657) Fixes #5653 Based on your comment in the issue, I thought you would be the best to review @eernstg . --------- Co-authored-by: Erik Ernst --- .../language/lib/patterns/pattern_types.dart | 5 +++- src/content/language/pattern-types.md | 28 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/examples/language/lib/patterns/pattern_types.dart b/examples/language/lib/patterns/pattern_types.dart index bf6ce6e89a..91a3cfc244 100644 --- a/examples/language/lib/patterns/pattern_types.dart +++ b/examples/language/lib/patterns/pattern_types.dart @@ -264,8 +264,11 @@ void miscDeclAnalyzedButNotTested() { var token = switch (result) { // #docregion parens // ... + x || y => 'matches true', x || y && z => 'matches true', - (x || y) && z => 'matches false', + x || (y && z) => 'matches true', + // `x || y && z` is the same thing as `x || (y && z)`. + (x || y) && z => 'matches nothing', // ... // #enddocregion parens _ => throw FormatException('Invalid') diff --git a/src/content/language/pattern-types.md b/src/content/language/pattern-types.md index 25cd2277ff..f0bb321297 100644 --- a/src/content/language/pattern-types.md +++ b/src/content/language/pattern-types.md @@ -277,22 +277,36 @@ Like parenthesized expressions, parentheses in a pattern let you control [pattern precedence](#pattern-precedence) and insert a lower-precedence pattern where a higher precedence one is expected. -For example, imagine the boolean constants `x`, `y`, and `z` are -equal to `true`, `true`, and `false`, respectively: +For example, imagine the boolean constants `x`, `y`, and `z` +equal `true`, `true`, and `false`, respectively. +Though the following example resembles boolean expression evaulation, +the example matches patterns. ```dart // ... +x || y => 'matches true', x || y && z => 'matches true', -(x || y) && z => 'matches false', +x || (y && z) => 'matches true', +// `x || y && z` is the same thing as `x || (y && z)`. +(x || y) && z => 'matches nothing', // ... ``` -In the first case, the logical-and pattern `y && z` evaluates first because -logical-and patterns have higher precedence than logical-or. -In the next case, the logical-or pattern is parenthesized. It evaluates first, -which results in a different match. +Dart starts matching the pattern from left to right. +1. The first pattern matches `true` as `x` matches `true`. +1. The second pattern matches `true` as `x` matches `true`. +1. The third pattern matches `true` as `x` matches `true`. +1. The fourth pattern `(x || y) && z` has no match. + + * The `x` matches `true`, so Dart doesn't try to match `y`. + * Though `(x || y)` matches `true`, `z` doesn't match `true` + * Therefore, pattern `(x || y) && z` doesn't match `true`. + * The subpattern `(x || y)` doesn't match `false`, + so Dart doesn't try to match `z`. + * Therefore, pattern `(x || y) && z` doesn't match `false`. + * As a conclusion, `(x || y) && z` has no match. ## List