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