You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Allow parenthesized match patterns in string/sequence/iter captures
In unambiguous capture positions (head-tail, init-last, head-last splits),
captures can now be parenthesized match patterns like view patterns or
equality checks, e.g. `(int -> n) + "G" = "8G"`. Search split positions
(two captures) still require bare variable names.
Closes#882
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bar_or_pattern ::= pattern ("|" pattern)* # match any
1199
1199
1200
+
capture ::= NAME | "(" pattern ")" # in unambiguous capture positions
1201
+
1200
1202
base_pattern ::= (
1201
1203
"(" pattern ")" # parentheses
1202
1204
| "None" | "True" | "False" # constants
@@ -1230,29 +1232,29 @@ base_pattern ::= (
1230
1232
| [( # sequence splits
1231
1233
"(" patterns ")"
1232
1234
| "[" patterns "]"
1233
-
) "+"] NAME ["+" (
1235
+
) "+"] capture ["+" (
1234
1236
"(" patterns ")" # this match must be the same
1235
1237
| "[" patterns "]" # construct as the first match
1236
-
)] ["+" NAME ["+" (
1237
-
"(" patterns ")" # and same here
1238
+
)] ["+" NAME ["+" ( # search splits require NAME
1239
+
"(" patterns ")" # must be same as first match
1238
1240
| "[" patterns "]"
1239
1241
)]]
1240
1242
| [( # iterable splits
1241
1243
"(" patterns ")"
1242
1244
| "[" patterns "]"
1243
1245
| "(|" patterns "|)"
1244
-
) "::"] NAME ["::" (
1246
+
) "::"] capture ["::" (
1245
1247
"(" patterns ")"
1246
1248
| "[" patterns "]"
1247
1249
| "(|" patterns "|)"
1248
-
)] [ "::" NAME [
1250
+
)] [ "::" NAME [ # search splits require NAME
1249
1251
"(" patterns ")"
1250
1252
| "[" patterns "]"
1251
1253
| "(|" patterns "|)"
1252
1254
]]
1253
-
| [STRING "+"] NAME # complex string matching
1255
+
| [STRING "+"] capture # complex string matching
1254
1256
["+" STRING]
1255
-
["+" NAME ["+" STRING]]
1257
+
["+" NAME ["+" STRING]] # search splits require NAME
1256
1258
)
1257
1259
```
1258
1260
@@ -1287,13 +1289,13 @@ base_pattern ::= (
1287
1289
- Sequence Destructuring:
1288
1290
- Lists (`[<patterns>]`), Tuples (`(<patterns>)`): will only match a sequence (`collections.abc.Sequence`) of the same length, and will check the contents against `<patterns>` (Coconut automatically registers `numpy` arrays and `collections.deque` objects as sequences).
1289
1291
- Lazy lists (`(|<patterns>|)`): same as list or tuple matching, but checks for an Iterable (`collections.abc.Iterable`) instead of a Sequence.
1290
-
- Head-Tail Splits (`<list/tuple> + <var>` or `(<patterns>, *<var>)`): will match the beginning of the sequence against the `<list/tuple>`/`<patterns>`, then bind the rest to `<var>`, and make it the type of the construct used.
1291
-
- Init-Last Splits (`<var> + <list/tuple>` or `(*<var>, <patterns>)`): exactly the same as head-tail splits, but on the end instead of the beginning of the sequence.
1292
-
- Head-Last Splits (`<list/tuple> + <var> + <list/tuple>` or `(<patterns>, *<var>, <patterns>)`): the combination of a head-tail and an init-last split.
1293
-
- Search Splits (`<var1> + <list/tuple> + <var2>` or `(*<var1>, <patterns>, *<var2>)`): searches for the first occurrence of the `<list/tuple>`/`<patterns>` in the sequence, then puts everything before into `<var1>` and everything after into `<var2>`.
1292
+
- Head-Tail Splits (`<list/tuple> + <capture>` or `(<patterns>, *<var>)`): will match the beginning of the sequence against the `<list/tuple>`/`<patterns>`, then bind the rest to `<capture>`, and make it the type of the construct used. `<capture>` can be a variable name or a parenthesized match pattern (e.g. `(int -> x)`).
1293
+
- Init-Last Splits (`<capture> + <list/tuple>` or `(*<var>, <patterns>)`): exactly the same as head-tail splits, but on the end instead of the beginning of the sequence.
1294
+
- Head-Last Splits (`<list/tuple> + <capture> + <list/tuple>` or `(<patterns>, *<var>, <patterns>)`): the combination of a head-tail and an init-last split.
1295
+
- Search Splits (`<var1> + <list/tuple> + <var2>` or `(*<var1>, <patterns>, *<var2>)`): searches for the first occurrence of the `<list/tuple>`/`<patterns>` in the sequence, then puts everything before into `<var1>` and everything after into `<var2>`. Search split captures must be variable names, not parenthesized patterns.
1294
1296
- Head-Last Search Splits (`<list/tuple> + <var> + <list/tuple> + <var> + <list/tuple>` or `(<patterns>, *<var>, <patterns>, *<var>, <patterns>)`): the combination of a head-tail split and a search split.
1295
-
- Iterable Splits (`<list/tuple/lazy list> :: <var> :: <list/tuple/lazy list> :: <var> :: <list/tuple/lazy list>`): same as other sequence destructuring, but works on any iterable (`collections.abc.Iterable`), including infinite iterators (note that if an iterator is matched against it will be modified unless it is [`reiterable`](#reiterable)).
1296
-
- Complex String Matching (`<string> + <var> + <string> + <var> + <string>`): string matching supports the same destructuring options as above.
1297
+
- Iterable Splits (`<list/tuple/lazy list> :: <capture> :: <list/tuple/lazy list> :: <var> :: <list/tuple/lazy list>`): same as other sequence destructuring, but works on any iterable (`collections.abc.Iterable`), including infinite iterators (note that if an iterator is matched against it will be modified unless it is [`reiterable`](#reiterable)).
1298
+
- Complex String Matching (`<string> + <capture> + <string> + <var> + <string>`): string matching supports the same destructuring options as above. In unambiguous positions (single capture), `<capture>` can be a variable name or a parenthesized match pattern (e.g. `(int -> n) + "px"`).
1297
1299
1298
1300
_Note: Like [iterator slicing](#iterator-slicing), iterator and lazy list matching make no guarantee that the original iterator matched against be preserved (to preserve the iterator, use Coconut's [`reiterable`](#reiterable) built-in)._
0 commit comments