Optional brackets around lambda expression (was: Expected distribution of lambda sizes)
Yuval Shavit
yshavit at akiban.com
Wed Jun 15 13:35:14 PDT 2011
What would happen with something like:
public interface Sam {
String doSomething(String arg);
}
public class User {
public void use(Sam sam) { System.out.println("saw a sam"); }
public void use(String string) { System.out.println("saw a string"); }
}
new User().use( #(x) x + "a string" );
In that context, which are we passing?
- lambda that takes a String, concatenates "a string" to it and returns
the result
- a string consisting of (lambda x -> x).toString() concatenated with "a
string"
This is just one simple and somewhat contrived example, but the point is
that without braces or something similar, it's not too hard to come up with
a situation where it's not clear where the lambda ends and the rest of the
expression begins.
On Wed, Jun 15, 2011 at 4:18 PM, Steven Simpson <ss at comp.lancs.ac.uk> wrote:
> 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