Do we have any plans to enable list matching at an offset?
As a simple example, Lets say I want to check for the comment identifier in c at a specific offset. If I wanted to do that at the beginning of a List, I could just do:
when bytes is
['\\', '\\', ..] -> # we have a comment, do things.
When dealing with an offset, you lose matching. Instead you have to do:
when List.get bytes offset is
Ok '\\' ->
when List.get bytes (offset + 1) is
Ok '\\' ->
# we have a comment, do things.
I am not sure what the merged syntax would look like exactly. Maybe something like [ ..offset, '\\', '\\', .. ], but some form of merge syntax may make for much nicer matching if dealing with an offset. Any thoughts?
Is there any reason List.get returns only a single element? What if you could specify a number of values instead?
Maybe a List.getRange or something?
I forgot about List.subList
This works, maybe there is a nice syntax sugar which does something similar?
when List.sublist myList {start: 2, len: 2} is
['c','d', ..] -> Stdout.line "Yay"
_ -> Stdout.line "Nay"
My attempts at brainstorming some ideas
# Maybe we could add an offset fn which just shifts the list by N elements
when List.offset bytes 2 is
['c','d'] -> ..
# Or maybe re-use the infix shift operators for Lists?
when bytes << 2 is
['c','d'] -> ..
Hmm those solutions will all work but will allocate a new list. And then we immediately discard that new list after getting the elements. But we already had the contents in the original list, so that's a pity.
I think the only viable solution here is to use pattern matching. I thought we had something for pattern matching on lists a while ago. I think Ayaz implemented it. Maybe it doesn't cover this case.
sublist should use a slice right? and not allocate anything? am i missing something that means it doesn’t work here?
right, with seamless slices it seems like this should work without allocating
it may still bump the refcount of the list, but that should be it
:point_up:also if the prefix is statically known you can do something like [_, _, ‘//‘, ‘//‘, ..]
Oh I forgot about slices!
Seamless slice should work. Was just hoping to avoid the cost in a hot loop (even if relatively small). That is why I think a proper built-in syntax be nice. Also, if you have a list of recounted things, I'm pretty sure the performance would be terrible, but maybe that will change enough in the future to not be a concern.
Perhaps something like: [1, 2, .., 4: 5, .., 10]
Essentially the indexed element ("value 5 at index 4") terminates the sweep/skip, and must be used whenever there are elements between two skips, and an indexed element must always be preceded by a skip.
Negative indices could perhaps indicate distance from the end. These would need to appear after all positive indices if present.
If the last element has a positive index, it must also be one less than the actual length to match. If the last contiguous sequence of elements is indexed, similarly, that index plus the length of the sequence must match the overall list length. We could disallow start-of-list positive indices and end-of-list negative indices, since they prove nothing useful (they'd need to be 0 and -1 respectively to ever match).
At least to start with, the indices must be constant, and the compiler could use them to prove a minimum list length. If at runtime, the list is not at least that length, then the match will fail, e.g. if the positive indices (or elements that trail) would go past the end of the list, if negative indices fall before the start of the list, or if negative and positive indices would swap their relative order compared to the source.
We could also support runtime-variable indices, such as with [.., i: x, .., j: y, ..]. A runtime check would need to be performed to ensure that the earlier mentioned criteria permit at match (including that x and y don't end up swapping order).
Last updated: Jun 16 2026 at 16:19 UTC