A syntax option (function types versus arrays)

Reinier Zwitserloot reinier at zwitserloot.com
Tue Mar 2 17:09:18 PST 2010


Well, let's think about how people are going to format their lambdas.

Given fact: The vast majority of java programmers block-brace everything,
even trivial stuff. The following:

if (someCondition) return false;

is _far_ more rare compared to:

if (someCondition) {
    return false;
}

without making a judgement call on the intelligence or lack thereof of so
doggedly preferring braces, it seems rather obvious then that your average
java programmer writing a multi-statement closure is rather obviously going
to write it like so:

stringList.forEach(#(String x) {
    System.out.println(x);
    y.registerKey(x);
});

This also nicely solves the problem of a confusingly large amount of
semicolons if you tried to one-liner all of this; your code would end in
";});" which looks weird, to say the least.

However, if we go with your prefix-statements concept, you get:

stringList.forEach(#(String x) (
    System.out.println(x);
    y.registerKey(x);
    void
));

exactly how this is an improvement is a mystery to me.

The biggest issue I see with the status quo syntax is one-liners that return
void. You might want to prefer to write something like:

stringList.forEach(#(String x) {System.out.println(x)}); //note lack of
semi-colon after println.

or the same thing but with parens:

stringList.forEach(#(String x) (System.out.println(x)));

(though in this trivial case we're already seeing 3 closing parens, which
means in more complex cases it's going to look like LISP!)

either of which isn't, as far as I understand the status quo proposal,
legal, because System.out.println(x) cannot function as an expression here,
as returning "void" like this isn't allowed (and in java in general, "void"
is not really a type as such. Some other languages treat it as the bottom
type, java doesn't).

Not adequately solving every single last corner case is _NOT_, as far as I'm
concerned, a requirement for a java language feature to be added to the JLS,
but perhaps someone has a good idea on how to solve this. Nevertheless,
this:

stringList.forEach(#(String x) {
    System.out.println(x);
});

looks allright to me, and more to the point, given the proclivities of
throwing braces around everything amongst the java rank-and-file, it'll look
allright to them, even if it tends to look somewhat verbose to us lambda-dev
readers.

What you're essentially suggesting, and you should go all the way with it
lest java becomes too inconsistent, is a new language construct:

ExpressionGroup:
    '(' StatementsInGroup[opt] Expression ')'

StatementsInGroup:
    Statement ';' StatementsInGroup[opt]

in other words, if you allow that, then this should also be legal:

int x = (System.out.println("Hello, World!"); 5);


That's got all sorts of problems:

   - how are you even going to format this?
   - it treats the ';' as a separator, whereas everywhere else in java it
*ISNT* a separator, it's a suffix for a statement. I know from personal
experience that java's semi-colon policy is much easier to understand for
beginning students that Pascal's, which does treat its closer symbols as
separators most of the time, meaning, for example, that the last statement
doesn't need one. In java, the last statement in a block *DOES* need a
semi-colon, because it is *NOT* a separator. But in this expression group
concept, it *IS* a separator.
   - What's the problem this solves? You lose some complexity in the JLS
when defining closures, but you lose even more when you have to define a new
construct "void" (as an expression), probably you have to redefine "void"
itself as a legal type of an expression throughout the entire JLS instead of
a placeholder for method return types. Right now you can *NOT* write:
"return System.out.println("foo");" in a method that has 'void' as a return
type, so right now "void" is *NOT* a type, at least, not like other types
are. You'd have to change all of this for consistency. That's far more
effort to change in the JLS than you save.

Neal also suggested it for coin and it was shot down almost immediately.

--Reinier Zwitserloot



On Tue, Mar 2, 2010 at 8:49 AM, Peter Levart <peter.levart at marand.si> wrote:

> I think we don't need statement lambdas if we allow expression to be
> preceeded by statements (like in block expression of CfJ0.6b):
>
> Lambda:
>  '(' FormalParameters_opt '->' Statements_opt Expression ')'
>
> for void lambdas "void" keyword could be defined as expression of type
> void:
>
> (->void) lambda = (-> System.out.println("Hello!"); void);
>
>
> Regarding arrays of function types, this syntax:
>
> FunctionType:
>  '(' ParameterTypes_opt Throws_opt '->' ReturnType ')'
>
> is perfectly combinable with array type syntax.
>
> Peter
>
> On Tuesday 02 March 2010 03:18:30 Reinier Zwitserloot wrote:
> > In regards to:
> >
> > (String x -> 3)
> >
> > What is this going to look like when the body of the closure is not a
> single
> > expression but a block?
> >
> > --Reinier Zwitserloot
> >
>


More information about the lambda-dev mailing list