It is legitimately useful to have bindings at the top-level of
patterns in match statements. Here are two examples. I'm not so sure
about `let` bindings, but I guess that reason (1) could still apply.
(1) Today, it's sometimes nice when matching against an rvalue,
where you want to both take the value as a whole and extract
some little piece:
match some_func_call() {
s @ Foo(Bar(z, _), _) => { ... }
...
}
(2) In the future, if we support enum refinement types---as I hope to
do post-Rust-1.0---then bindings could be used as follows:
match opt {
s @ Some(_) => { /* type of `s` is Option[Some] */ }
...
}
Not helpful, I know.
Niko
On Fri, May 03, 2013 at 12:12:31PM +0200, Felix S. Klock II wrote:
> Patrick (cc'ing rust-dev)-
>
> Between the two options Patrick presented, my vote is for
> bifurcating the grammar into irrefutable and refutable variants. I
> like having one operator to denote binding (even if it also
> sometimes means mutation).
>
> However, my (potentially-wrong) intuition is that the problem
> Patrick describes is stemming from a not-particularly useful special
> case of pattern binding.
>
> In particular, I wonder whether the problem could be resolved by not
> allowing a binding `=` at the topmost level of the pattern.
>
> I mentioned this on IRC last night, but it was late and I'm not
> convinced I explained myself properly.
>
> More concretely, what I'm suggesting is the following:
>
> What we now write as:
>
> fn main() {
> enum Foo { A((int, int)), B((&'static str, &'static str)) };
> fn visit (x:Foo) {
> match x {
> i @ A(j@(k,l)) => io::println(fmt!("an A %? %? %? %?",
> i, j, k, l)),
> m @ B(n@(o,p)) => io::println(fmt!("a B %? %? %? %?",
> m, n, o, p))
> }
> }
>
> visit(A((1,2)));
> visit(B(("three", "four")));
> }
>
> would become illegal. In particular, the bindings for `i` and `m`
> would be disallowed. But the other bindings would continue to be
> allowed, and we would switch to the `=` operator for binding,
> yieldign:
>
> fn main() {
> enum Foo { A((int, int)), B((&'static str, &'static str)) };
> fn visit (x:Foo) {
> match x {
> A(j=(k,l)) => io::println(fmt!("an A %? %? %? %?", x, j,
> k, l)),
> B(n=(o,p)) => io::println(fmt!("a B %? %? %? %?", x, n, o, p))
> }
> }
>
> visit(A((1,2)));
> visit(B(("three", "four")));
> }
>
>
> patrick: Does this get rid of the problem, since the `=`'s could
> only occur beneath pattern structure? Or does it leave the grammar
> just as ugly as bifurcating it with irrefutable and refutable
> variants? (Although at least now, even though the grammar is a
> little more complex, it at least might be *consistent* across both
> let and match.)
>
> Cheers,
> -Felix
>
> On 03/05/2013 03:12, Patrick Walton wrote:
> >Hi everyone,
> >
> >There's consensus that `@` (imported from Haskell) is a bad
> >binding operator for patterns, because it leads to the
> >confusing-looking `@@` in, for example:
> >
> > struct Foo {
> > field: int
> > }
> >
> > ...
> >
> > match foo {
> > foo@@Foo { field: x } => ...
> > }
> >
> >However, there is not consensus as to what to change it to.
> >Suggestions are `=` and `as`.
> >
> >The problem with `=` is that, if implemented naively, it makes our
> >grammar ambiguous:
> >
> > let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit)
> > // or are x and y bound to 3?
> >
> >The easiest way to fix this problem is to forbid `=` in
> >irrefutable patterns, such as those introduced by `let`. However,
> >this bifurcates the pattern grammar into the irrefutable-pattern
> >grammar and the refutable-pattern grammar, with some
> >conceptually-ugly overlap.
> >
> >The alternative is `as`, like OCaml. However, this conflicts with
> >`as` in the expression grammar. A subset of the expression grammar
> >is part of the pattern grammar in order to permit matching against
> >constants. Removing `as` expressions from the subset of expression
> >productions permitted in patterns would mean that this would no
> >longer do what you expect:
> >
> > match 22.0f32 / 7.0f32 {
> > math::PI as f32 => println("Good grief!"),
> > _ => {}
> > }
> >
> >So both `=` and `as` have drawbacks.
> >
> >I don't really have any preference at all; I just need to know
> >what to implement. Opinions?
> >
> >Patrick
> >_______________________________________________
> >Rust-dev mailing list
> >[email protected]
> >https://mail.mozilla.org/listinfo/rust-dev
>
>
> --
> irc: pnkfelix on irc.mozilla.org
> email: {fklock, pnkfelix}@mozilla.org
>
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev