Function types syntax
Peter Levart
peter.levart at marand.si
Tue Jan 26 05:17:10 PST 2010
On Tuesday 26 January 2010 11:15:48 Zdenek Tronicek wrote:
> Peter Levart napsal(a):
> > 2nd order example from above repeated here for comparison:
> >
> > ##int(String)(throws IOException)(String)(throws SQLException)
> >
> > with proposed syntax:
> >
> > #(String: #(String: int throws IOException) throws SQLException)
> >
>
> I think that more important than different syntax are parens in your syntax:
>
> #(#int(String)(throws IOException)) (String)(throws SQLException)
>
> vs.
>
> #String: #String: int throws IOException throws SQLException
>
1. '(' Type ')' in current Java syntax can not be interpreted as Type (it's a cast), so optionally enclosing a Type in parens to visibly disambiguate is not valid syntax (currently). Even if it was, yet another pair of parens (10 totally for above example vs. 4 for my proposed syntax) is not a big plus.
2. If a syntax specifies a mandatory character, it can not be taken away, so removing parens from my proposed syntax is not a fair way to compare it's readability to another syntax - it's not the same syntax.
But yes, I agree that parens placement is crucial for readability. If the whole construct is effectively "enclosed" between '#(' and ')' then nesting is explicitly visible.
> >
> > LambdaExpression:
> > '#' '(' FormalParametersList_opt ResultParameter_opt ')' Block
> >
> > ResultParameter:
> > ':' FormalParameter
> >
> >
> > Examples:
> >
> > #(:void) printHello = #() { System.out.println("Hello!"); };
> >
> > #(String: void) printName = #(String name) { System.out.println(name); };
> >
> > #(String: int throws ParseException) parseInt = #(String s: int i) {
> > i = DecimalFormat.getIntegerInstance().parse(s).intValue();
> > };
> >
> > #(int, int: int) add = #(int a, int b: int c) { c = a+b; };
> >
> >
> > Notice that "no return statements were harmed in this presentation" ;-)
> >
> > And using this syntax they don't have to be harmed, ever. If "Block" is
> > prefixed with a label:
> >
> > LambdaExpression:
> > '#' '(' FormalParametersList_opt ResultParameter_opt ')' Label_opt Block
> >
> > Label:
> > ':' Identifier
Pardon.
Label:
Identifier ':'
> >
> > Then "return" from lambda becomes a familiar "break label". For 1st JDK7
> > release, non-local returns/breaks/continues could be disallowed
And, my I add, using 'this' keyword in lambda body should be disallowed too.
> > but the
> > path to future transparent lambda would stay open...
> >
>
> Do you mean to return from closure as soon as you assign to the result
> parameter?
No, god forbid, no! This would be a surprise.
The rules are simple. Result parameter has to be definitely assigned before the end of the block or...
> If yes, it is not transparent. If no, how do you want to return
> early?
...or before each "break label" statement.
For example:
#(String: int) stringLength = #(String s: int length) label:{
if (s == null) { length =-1; break label; }
length = s.length();
};
A variant of this was proposed by John Rose on closures-dev mailing list (and I think it was crosposted to lambda-dev too). Another variation of this is the following syntax:
LambdaExpression:
'#' '(' FormalParametersList_opt ResultVariableDeclaration_opt ')' Label_opt Block
ResultVariableDeclaration:
':' VariableModifiers Type VariableDeclarator
Label:
Identifier ':'
...so the above example could then be rewritten as:
#(String: int) stringLength = #(String s: int length=-1) label:{
if (s == null) break label;
length = s.length();
};
>
> Z.
>
Regards, Peter
More information about the lambda-dev
mailing list