First off, I echo Brian's "thank you" for both the kind words and the
well thought out e-mail. Here are some far less organized thoughts in
response.
## Patterns
I think the pattern syntax would have to be that `let` does not
(necessarily) immediately precede another binding, but rather another
pattern (and the same for `ref`, and perhaps `copy`). The meaning of
such a binding is that all naked identifiers inside become binders.
That way, you can write `let (x, y) = pair`. It also permits something
like:
match (x, (y, z)) {
(let a, let (b, c)) => { /*just for the purposes of example*/ }
}
I agree with Brian that the use of keywords like `ref` or `copy` in
bindings is inconsistent (and in fact argued against them for quite a
while) but I'm finding that in practice it's... tolerably nice.
In general, I have found it rather confusing in the past to deal with
identifiers and variant names that are not syntactically distinguished
(though the trailing dot that was here when I first got here didn't work
for me, easy to overlook and impossible to remember, not to mention kind
of... random). I think the move to CamelCase, combined with lint modes
for unused pattern bindings, basically solves this issue for me,
however. One thing that our current syntax *cannot *accommodate,
however, is references to constants like:
const magic_number: uint = 0xDEADBEEF;
match *x { (magic_number, let foo) => ... }
That would be nice, though it has not come up in practice very often.
Still, most languages require something like
match *x { (mn, foo) if mn == magic_number => ... }
and it's not the end of the world.
So I don't know. I think preceding with `let` has merit---it's verbose
but clear---but I am a bit reluctant to make such a far-reaching change
to our syntax. Still, it's worth discussing a bit more.
## Closure
Regarding the closure syntax, I personally am content with what we
have. It's been a long struggle finding something that we liked and I
am reluctant to change it, exotic or no. The use of vertical bars is
exotic but not without precedent (smalltalk, ruby), and I find that
foo.map(|x| x.something())
for vec.each |x| { ... }
do with_file("filename") |file_object| { ... }
all read really well, whereas various options
foo.map(&(let x) => x.something())
for vec.each &(let x) => { ... }
do with_file("filename") &(file_object) => { ... }
just... don't (not to my eyes, at least). Moreover, they seem only
slightly less exotic to me. Also, it's worth pointing out that no two
languages seem to have the same closure syntax, so I guess some
variation is to be expected.
Niko
On 9/10/12 2:27 PM, Patrick Walton wrote:
Hi,
This leads to this issue:
let (let x, let y) = (1, 2);
And it would be very difficult to parse something like this:
(let x, let y) = (1, 2);
Because the parser would have to do unbounded lookahead here to
determine whether we're in a pattern or not.
Patrick
_______________________________________________
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