Niko (cc'ing rust-dev)-

I know about (1), and I can appreciate (2).

I had dismissed (1) because it did not seem like a huge burden to add the extra 
line binding `s = some_func_call()` immediately preceding `match s { ... }`; 
that's why I classified this case as "not-particularly useful."

Likewise, for (2) one could try to adopt something like "occurrence types" [^1] 
to get the effect you want even for code of the form `s = some_func_call(); 
match s { ... }`

But you might see more value than I do in keeping the scope of `s` strictly 
contained to the single match-clause, versus overloading a (non-`=`) 
operator/keyword to denote binding.  I have no counter-argument for that.

----

As another variant on my proposal: we could just disallow top-level =-binding 
for `let` alone, but leave top-level =-binding for `match`.  That's a little 
ugly, but still preferable to me over abusing other keywords.  Would that suit 
you, as a language user?

Cheers,
-Felix

[^1] http://www.ccs.neu.edu/racket/pubs/popl08-thf.pdf
     The Design and Implementation of Typed Scheme 
     POPL 2008 : Tobin-Hochstadt, Felleisen
    
----- Original Message -----
From: "Niko Matsakis" <n...@alum.mit.edu>
To: "Felix S. Klock II" <pnkfe...@mozilla.com>
Cc: "Patrick Walton" <pwal...@mozilla.com>, "rus >> \"rust-dev@mozilla.org\"" 
<rust-dev@mozilla.org>
Sent: Friday, May 3, 2013 8:32:16 PM
Subject: Re: [rust-dev] RFC: Pattern matching binding operator

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
> >Rust-dev@mozilla.org
> >https://mail.mozilla.org/listinfo/rust-dev
> 
> 
> -- 
> irc: pnkfelix on irc.mozilla.org
> email: {fklock, pnkfelix}@mozilla.org
> 
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to