I’ve been thinking for some time to an alternate of match
which could cover both uses of match
and if let
, including if let
chains. I’ve saw a lot of discussion on how to improve if let
, but I think that they only exist because match
is too verbose, and requires two level of indentation. If match
was more lightweight, I do think all of those conversation would not be needed.
That being said I don’t think the gain is high enough to modify Rust in that direction, because even if the change can be completely automated, it would require every Rust project ever to be updated, and be even more disruptive than the introduction of the ?
operator. That’s why I’m not posting on IRLO, but here.
Anyway, what do you think of using a new contextual keyword with
/else with
which introduce alternative in a match
, and using else
for the diverging branch:
the enum `e`
enum E {
A,
B(i32),
C(i32),
}
let e: E = …;
exhaustive match
match e {
A => do_a(),
B(b) => do_b(b),
C(c) if c > 3 => do_big_c(c),
C(c) => do_small(c),
}
becomes
match e with A {
do_a();
} else with B(b) {
do_b(b);
} else with C(c) if c > 3 {
do_big_c(c);
} else with C(c) {
do_small_c(c);
}
partial match
if let A = e { do_a() };
if let B(b) = e { do_b() };
becomes
match e with A { do_a() } else {}
match e with B(b) { do_b(b) } else {}
partial match with divergent branch
(note: is divergent the right word?)
if let A = e {
do_a();
} else {
do_default();
}
becomes
match e with A
do_a();
} else {
do_default();
}
partial match with capture of the diverting branch
(IIRC something like this is currently being proposed but is not yet accepted)
if let Ok(foo) = some_fallible_function() {
do_foo(foo);
} else error (
report(error);
}
becomes
match some_fallible_function() with Ok(foo) {
do_foo(foo);
} else with error {
report(error);
}
chaining of partial match
(note: I forgot if it’s already accepted)
let f: E = …;
if let B(e_b) = e && let C(f_c) = f {
do_b_and_c(e_b, f_c);
}
becomes
match (e, f) with (B(e_b), C(f_c)) {
do_b_and_c(e_b, f_c);
} else {}
note: if order to have the exact same semantic, if f
in an expression in match (e, f)
, it must be lazily evaluated only if B(e_b)
is correctly matched.
Remarks:
match … with … { … } else {}
could also be spelledpartial match … with … { … }
but this requires the introduction of a new contextual keyword.match (e, f) with (B(e_b), C(f_c)) { do_b_and_c(e_b, f_c) } else {}
(the last example) could be spelledlazy match (e, f) with …
but it also requires a new contextual keyword.