[rust-dev] bikeshed on closure syntax

Niko Matsakis niko at alum.mit.edu
Tue Apr 17 16:01:35 PDT 2012


Apologies in advance.

An outbreak of Syntax Fever has struck the Mountain View offices today.  
One of the results was a total bikeshed proposal for a streamlined 
closure syntax.  The idea is like this:

1. Closure expressions can be written `x -> expr` or `(x, y) -> expr`.  
This requires arbitrary lookahead to disambiguate from tuples.  But it's 
relatively simple to write the code for it: you basically scan forward 
to find the matching parenthesis and then check the next token to see 
whether it is "->".

2. You may omit the last argument of a function that expects a closure 
using a syntax like the following:

     vec.iter: x { ... }

The general structure is ": args blk".  In BNF-like form, this looks like:

     Arguments := ID | "(" Argument0, ... ArgumentN ")"
     Argument := IrrefutablePattern
     Field := Expr "." ID
     Call := Expr "(" ... ")"
     TailCall := (Field | Call) ":" Arguments "{" ... "}"
     ClosureExpr := Arguments "->" Expr

Here are some examples:

     spawn: { ... }
     for vec.each: x { ... }
     let xs = xs.filter(x -> x.isEven());
     let ys = xs.map(x -> x * 2).filter(x -> x.isEven());
     let ys = xs.map: x {
         ...
         some_thing_complex(x)
     };

In all cases we would infer the @ vs ~ vs & as we do today.

I am not sure whether (x, y) -> x.isEven(y) is lightweight enough to 
replace _.isEven(_) in my heart, but it certainly looks better than {|x, 
y| x.isEven(y)}.



Niko


More information about the Rust-dev mailing list