Stream: ideas

Topic: Pattern match multiple values


view this post on Zulip Luke Boswell (Dec 09 2023 at 08:00):

I just accidentally wrote something, and I am wondering if it would be useful syntax. Could it be possible to support comma separated values and pattern match on them, just as if they were in a tuple?

# What I wrote -- not valid syntax
when old, maybePrev is
    [], _ -> new

# What I meant to write -- valid syntax
when (old, maybePrev) is
    ([], _) -> new

view this post on Zulip Johan Lövgren (Dec 09 2023 at 08:16):

I like it! Very readable

view this post on Zulip Agus Zubiaga (Dec 09 2023 at 12:53):

This could have the perf benefit of not allocating the tuple. Although, that seems something it could do anyway when it finds a tuple literal used with when.

view this post on Zulip Kilian Vounckx (Dec 09 2023 at 13:39):

In ocaml this would work as well, because tuples can be created without parentheses. There you can think of the comma as an operator for creating tuples with its own preference and associativity. I don't think we should go full ocaml here, but in cases like pattern matching I think it can be nice

view this post on Zulip Anton (Dec 10 2023 at 11:29):

I like it in the branch but I would keep the parenthesis in when (old, maybePrev) is.
If you try to parse when old, maybePrev is like it is a normal sentence you separate it into when old and maybePrev is. I think it's nice to have the tuple clearly indicated there, especially when you add function calls with space separated arguments after the when.

view this post on Zulip Richard Feldman (Dec 10 2023 at 11:58):

I think this would run into some of the problems discussed in https://roc.zulipchat.com/#narrow/stream/304641-ideas/topic/tuples.20for.20function.20arguments

for example, now pattern matching works subtly differently in these two cases:

        a, b, c ->
        \a, b, c ->

in the first case, it now means a tuple, whereas in the second case it means function arguments

view this post on Zulip Kevin Gillette (Dec 11 2023 at 15:38):

I'm interested in the deeper distinction, but I could use more information to grok this properly... Is the concern that, if we were to accept this into the grammar, then:

  1. As soon as the -> token is encountered, there'd be a parse ambiguity?
  2. We'd be blurring the lines between arguments and tuples, and thus confuse learners who would expect that tuples could be specified without parens in all other contexts (and correspondingly mis-infer that all un-[bracketed] comma separated token sequences are thus tuples)?
  3. Something else?

If it's about learner confusion, rather than making the OP sample implicitly a match on tuples, what if we made clear that, just as a function accepts multiple arguments (and that they don't form a tuple), a match accepts multiple expressions (and that they also don't form a tuple). The distinction would be potentially be formal/academic, bc iiuc, wrapping the expression list in parens (or brackets) would semantically yield the same behavior, and potentially would be optimized into the same machine code.

view this post on Zulip Kevin Gillette (Dec 11 2023 at 15:42):

Alternatively, what if we just formally made function arguments an unnamed, unparenthesized tuple? I'm sure this has been discussed at length and need not be discussed here, but if it were workable, then it would be a different resolution to the confusion/inconsistency.

view this post on Zulip Eli Dowling (Dec 13 2023 at 22:45):

@Kevin Gillette I was going to say the exact same thing, I think there is a nice consistency between comma separated function args and comma separated match args. Neither are tuples and thus prevent unnecessary allocation.

view this post on Zulip Brendan Hansknecht (Dec 13 2023 at 22:49):

I think the issue is that destructuring is allowed inside of function args.

So I could have a something like:

fn : (U8, U8, U8), U8 -> ...
fn = \(a, b, c), d ->

If we allow for the pattern matching syntax to include direct values as if they were tuples, you suddenly have to be able to parse:

fn : (U8, U8, U8), U8 -> ...
fn = \a, b, c, d ->

This is much less clear for the parser. We could theoretically special case this part of pattern matching just to the top level of when ... is, but currently a lot of that is shared implementation and features. That is at least my understanding.

view this post on Zulip Kevin Gillette (Dec 13 2023 at 22:53):

ah

view this post on Zulip Kevin Gillette (Dec 13 2023 at 22:56):

technically wouldn't this be unambiguous though? iiuc, a top-level comma is not allowed in either the when condition or any of the match cases?

view this post on Zulip Brendan Hansknecht (Dec 13 2023 at 23:01):

I think it is unambiguous, just a question of consistent support of pattern matching and if certain versions add a lot of cases that we would prefer didn't exist...but yeah, I think that is small and it would be easy to special case this just for top level of a statement in a when is

view this post on Zulip Kevin Gillette (Dec 13 2023 at 23:05):

certain versions?


Last updated: Jun 16 2026 at 16:19 UTC