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

Reply via email to