Optional brackets around lambda expression (was: Expected distribution of lambda sizes)

Steven Simpson ss at comp.lancs.ac.uk
Wed Jun 15 13:18:00 PDT 2011


On 13/06/11 21:10, Pavel Minaev wrote:
> Statement lambdas would typically be thus wrapped, yes (coincidentally, it's
> also why I'd prefer to have a separate form for expression lambdas which
> does not include the {} so as to be visually distinct from statement
> blocks).

Yes, I think I'd appreciate that visual distinction too.  Is it possible
to have an unambiguous expression syntax not requiring any form of
brackets around either the whole lambda or its body?:

  #() 3
  #() 3 + 4
  #(x) x + 1
  #(x, y) x + y

When used like this, they will likely be in argument lists, so they are
naturally delimited by commas and the list-terminating bracket, and need
no brackets of their own.  IOW, #() would have quite a low precedence,
and any brackets put around it would be part of existing syntax (e.g.
for normal expressions and argument lists).

If you had one lambda in the body of another, it will likely have to be
inside an enclosed call, whose brackets will naturally delimit it:

  #(a) a + process(#(b) b * b) + 10

If it wasn't so embedded, you could always put normal expression
brackets around it:

  #(a) a + (#(b) b * b).invoke(a)

(And that's a little contrived.  And possibly quite difficult to
type-infer…?)

I don't think you could drop the parameter-list brackets too, as that
would make parsing much more complex (e.g. #a + a).  Looking at that
more positively, it would keep lambda syntax and appearance obviously
distinct from method literals.  ("#(" => Bam!  I'm a lambda!)  The
presence of braces would then further distinguish lambda expressions
from lambda statements.

In summary, we require brackets around neither the lambda expression nor
its body.  We are then forced to used some around the parameter list,
but take advantage of this as the constant discriminant of lambda vs
method literal.

Applied to some other expressions seen on the list lately:

   list.filter( #(t) t.length() > 3 )
       .map( #(t) t.barCount )
       .max();

   students.filter(#(s) s!=null && "Smith".equals(s.getName()))

   List men = personList.filter(#(p) p.isMale());

   List<Double> adjustedPrices =
      prices.map(#(price) price + getShipping());

Cheers,

Steven



More information about the lambda-dev mailing list