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