[rust-dev] bikeshed on closure syntax

Graydon Hoare graydon at mozilla.com
Tue Apr 17 16:57:44 PDT 2012


On 12-04-17 04:01 PM, Niko Matsakis wrote:
> Apologies in advance.

Ha! Apologies in return, then, as at least the first bit I'm kinda sour
on. The rest I'm just confused over.

> This requires arbitrary lookahead to disambiguate from tuples.

This bit in particular. Really really don't want to cross the bridge to
arbitrary lookahead in the grammar.

> 2. You may omit the last argument of a function that expects a closure
> using a syntax like the following:
> 
>     vec.iter: x { ... }

Ok. I think I can see where you're going with this -- now that I'm
reading it as a _replacement_ for the existing block syntax -- but
looking it over I think I don't get it and/or prefer what we've got:

  - It doesn't seem any shorter:

     foo {|x| ... }     and
     foo: x { ... }

    are equally long.

  - Earlier today (in meeting) we discussed adopting the pattern =>
    expr form in alts. If you're going to have any kind of "pat
    arrow expr" form for lambdas, I think it should be the same
    arrow as used in alt's "pat arrow expr".

  - I can imagine a "\ pat => expr" or "fn: pat => expr" form, but
    in all honesty I find the "{|pat| expr}" form easier to read.
    Because of the braces. For two reasons:

    1. the binder scope is structurally visible, beginning and ending.

    2. they transition smoothly to multiline blocks when the expression
       inevitably grows more complex or line-wraps due to indentation.

> Here are some examples:

I'm writing "how it's written now" examples beneath, strictly for
aesthetic sense. I find the current form has grown on me and I quite
like it now. But it's also notable to me that the size doesn't change:

>     spawn: { ... }

      surely this has to be "spawn(): { ... }"

>     for vec.each: x { ... }

      for vec.each {|x| ... }

>     let xs = xs.filter(x -> x.isEven());

      let xs = xs.filter {|x| x.isEven()};

>     let ys = xs.map(x -> x * 2).filter(x -> x.isEven());

      let ys = xs.map {|x| x * 2}.filter {|x| x.isEven()};

I guess I'm having a hard time seeing the motive. Is it a preference for
parens over braces? We could probably support (|pat| expr) as a lambda
just as well as {|pat| expr} -- parser can see the transition point to
pattern grammar -- though it loses the "transitions to multi-line
easily" aspect I mention in point #2 above..

-Graydon


More information about the Rust-dev mailing list