On Tue, Sep 11, 2012 at 12:19 PM, Niko Matsakis <[email protected]> wrote:
> 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.

Hi Niko,

Thanks for your detailed response.  (It's funny, both you and Brian
apologized for the brevity of your responses, but I found that both
had just the right amount of detail.)


> ## 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*/ }
>     }

After conceding to a single-'let'-out-front tuple destructuring syntax
before, on the grounds of pragmatism with no apparent ill effects,
I can't really argue against the same thing here.  ;)

But I should emphasise that if such a tuple were allowed to contain
anything other than naked identifiers to be bound (i.e. things such as
literals, enums, etc.), then from my perspective that would neutralize
much of the benefit in introducing 'let' in the destructuring pattern.

Particularly in the case of enums or other "variable-like identifiers"
that look (to either a human or compiler) like variables to be bound,
but aren't:  Even if an omniscient programmer knew that 'foo' was an
enum defined elsewhere, there would no longer be a guarantee to the
non-omniscient reader that everything inside the tuple is a variable
to be bound.

I would also argue that such a single-'let'-out-front concession
should not be applied to struct patterns:  One of the key benefits
of introducing 'let' in struct patterns is to disambiguate variable
bindings from struct field names, which requires having the 'let'
directly in front of the variable binding.


> 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.

I understand.
Thanks for your patience and open-mindedness to discussing this
at this stage.


> ## 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),

Ah, thanks for that.  I knew the syntax in Python and Lisp, and I
looked up the syntax for Haskell and ML on Wikipedia, but I didn't
think to check Ruby or Smalltalk.

> 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.

It's possible that my preference for syntax like '(let x)' is evidence
that I'm a little too fond of Lisp.  ;)

Thanks again,
jb
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to