Hi Brian,
Thanks so much for your detailed reply.

On Tue, Sep 11, 2012 at 6:43 AM, Brian Anderson <bander...@mozilla.com> wrote:
> I'll mention that both the pattern matching and closure syntaxes are very
> cramped, with a lot of competing requirements.

Yes, I can imagine.  In particular, I imagine that being relatively
terse is one them, given that pattern matching and closures will be
frequently-used parts of the language.  I was mindful of the number
of typed characters in what I was proposing.

However, it's precisely due to the importance of these language
features (which was apparent to me as I read the Tutorial) that I
think these features should be non-scary (to newcomers) and non-
error-prone (to less-experienced programmers).


> I think that most people will see this as too verbose, but I am sort of
> warming to this and the reason is `ref`. Currently, patterns implicitly bind
> by reference, but in the future they will create a copy, and to bind a
> reference you will need to write `ref`, as in `(0f, ref y) =>`. This is the
> only place that `ref` exists in the language. Saying that a binding is
> always introduced using either `let` or `ref` at least makes `ref` not stand
> out as bad. Of course, to be consistent with the goal of always using `let`,
> we would probably have to use `let ref` and then we're sort of back in the
> same spot.

Ah, this is very interesting, thanks for this.  I've been thinking
about pointers and references in Rust quite a bit recently, to ensure
I have a clear understanding of '&' in particular, especially as I've
digested the points made in the recent "weirdness of strings" thread:
 https://mail.mozilla.org/pipermail/rust-dev/2012-September/002315.html

After a bit of thought about this 'ref' keyword, and the 'let ref'
issue you point out, it would seem completely reasonable to me for
Rust to have mutually-exclusive 'let' and 'ref' keywords, just as
there is a separate 'const' keyword.  So it would be 'ref y', not
'let ref y'.

'ref' could potentially be defined generally (i.e., able to be used
outside pattern matching) as "introduce a binding that simply acts as
an alias to an existing storage unit on the stack", in contrast to
'let' as "introduce a binding and allocate a new storage unit on the
stack and copy the r-value".

This 'ref' keyword would also seem to me to be a better fit than 'let'
for the named parameters of closures.  (Initially, I thought 'let'
would be more appropriate, since a non-stack closure might outlive
the current stack.  But on further thought, I realised that any other
local variables referenced inside the closure are not specifically
"re-let", but are instead copied implicitly based upon the type of
the closure.  So it would be reasonable to use 'ref' for the named
parameters and copy them implicitly too if the type of the closure
specifies it.)


> OK, so how do let bindings work under this scheme? Here's current syntax:
>
>   let (foo, bar) = baz();
>
> Any irrefutable pattern can go after 'let'. So does that become:
>
>   let (let foo, let bar) = baz();
>
> Just writing `(let foo, let bar)`, allowing patterns to begin statements, is
> probably unparseable.

Since tuple destructuring occurs as a stand-alone statement outside of
a pattern matching construct, it would seem quite reasonable to me
for the lang spec to simply define that in this particular situation,
the syntax is:
    let (foo, bar) = baz;

If the inevitable question-asking idealists such as myself ask why
the syntax isn't the slightly more-consistent:
    (let foo, let bar) = baz;
, I think it would be quite reasonable to say "because it's a
stand-alone statement, so that wouldn't parse, so instead we do it
this way".  In such a situation, I'd accept that as an answer.

The presence of a 'let' keyword to indicate new variable bindings
would keep me happy; and of course no-one who's actually planning on
typing this every day would insist upon additional 'let' keywords
inside the tuple when there's already a 'let' keyword immediately
in front.

I think it's worth pre-emptively clarifying the distinction in my mind
between this tuple destructuring situation vs the partially-literal
destructuring pattern and the struct destructuring pattern.

I would argue there's no need to target specific variables in the
tuple destructuring (using immediately-preceding 'let'/'ref' keywords)
because all the variables in the tuple are being bound and there are
no other identifiers or tokens in there.

To me, this contrasts with a partially-literal destructuring pattern
(where only some of the tuple members are variables that are being
bound, while other tuple members are literals or enums) and a struct
destructuring pattern (in which the 'let'/'ref' keyword needs to be
precisely located, to differentiate the newly-bound variable name
from the struct field name).


> I would want to still have the option if inferring the storage for the
> closure, like `do foo.each (let n) => {`.

I wouldn't have any objections to this.  As I mentioned in my reply
to Kevin, I included the '&' because I was reproducing the examples
as closely as possible.  I have no specific argument for or against
the use of the '&'.

> I do think the 'let's here make the syntax not that aesthetically pleasing.
> Also the parens for closure syntax make this harder for eyeballs to parse.

I actually find the parentheses easier to eyeball-parse as "inside vs
outside the parameter list" than the directionless pipe sigils.

>   do foo.each(bar) (let baz) => {
>
> The argument lists look pretty similar.
>
> Also:
>
>   do foo.each() () => {
>   do foo.each () => {
>
> Weirdness.

I haven't seen any examples in the Tutorial or Reference Manual where
'each' is a method rather than a stand-alone function.  Would you have
any pointers to docs that I could read about this?

In particular, what are 'foo' and 'bar' in the above example?


Thanks again for your very detailed reply.  Sorry for sending you
even more to read from me now.  :)

jb
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to