Function types syntax
Peter Levart
peter.levart at marand.si
Tue Jan 26 07:53:17 PST 2010
On Tuesday 26 January 2010 14:52:55 Zdenek Tronicek wrote:
> I only try to show that better readability of your proposed syntax does
> not come from the changed order of return type and argument types, but is
> a consequence of parens added.
I don't agree. Proposed syntax *removes* (not adds) 2 parens compared to Alex's syntax in case of throws declarations:
#ReturnType(ParameterTypes)(throws ExceptionTypes)
vs.
#(ParameterTypes : ReturnType throws ExceptionTypes)
It *adds* one delimiter ':' between parameter types and a return type. It reuses the 'throws' keyword as a delimiter between return type and exception types. It rearranges 3 different parts of the function type: ParameterTypes, ReturnType and ExceptionTypes so that they are all enclosed between a single pair of '#(' and ')'. I think that "readability" when nesting comes from the fact that the syntax roughly resembles the syntax of a tupple. Tupples can be nested without syntax or visible ambiguity.
> And this is, hopefully, something, we
> agreed on.
I agree that order of different parts of function type doesn't affect readability. It's the usage of delimiters vs. parens that matters. The same readability, in case of nesting, could be achieved by maintaining Alex's proposed order:
#ReturnType(ParameterTypes)(throws ExceptionTypes)
vs.
#(ReturnType : ParameterTypes throws ExceptionTypes)
Maybe that's an alternative.
>
> As for the following syntax:
>
> > #(String: int) stringLength = #(String s: int length) label:{
> > if (s == null) { length =-1; break label; }
> > length = s.length();
> > };
>
> I do not understand where your enthusiasm comes from. I do not claim it
> cannot be used nor it is incorrect in some sense, but:
>
> 1) it uses a principle which is not common in Java (return value is in a
> variable),
That's true. A variable that is declared in the special place of a lambda header. I think this is not something that is mentally hard to grasp. Assignment syntax is a common way to transfer a value from one place to another and designating a special place for a variable declaration which's value becomes the return value of a lambda is something new, but not complicated.
> 2) it uses the break statement in a novel way,
Uncommon perhaps, but it is a part of today's Java. Try this snippet of code:
label:
{
System.out.println("Hello!");
if (true)
break label;
System.out.println("Not printed");
}
It's valid Java.
> 3) it is not transparent (a consequence of 1) and 2)).
That's something I don't agree. 1. Assigning to a variable is a transparent feature, 2. Labeled break is also a transparent feature.
Not allowing a feature in a context that exploits transparency does not make it non-transparent if it is only used for local handling.
I'm not proposing features be allowed to exploit transparency (non-local return/break/continue, usage of 'this' that refers to the instance of innermost enclosing class). I'm advocating that these features be prevented from exploiting transparency in 1st version (for JDK7). The non-transparent features of anonymous inner classes (local return, local treatment of 'this') are likewise also prevented and can partially be replaced with features that don't break transparency:
local return -> assignment + labeled break
local 'this' -> no direct replacement, but only usable for recursive invocation and/or when lambdas are converted to SAM classes which is troublesome.
Recursive invocation can be achieved by assigning a lambda to a final variable and referring to that variable from lambda's body (this can be allowed since the value of such variable is not used for evaluating lambda expression - it's just captured). Converting lambdas to SAM classes (not SAM interfaces) so that super-class members are accessible is very troublesome anyway so anonymous inner instance creation expression of SAM classes should not be migrated to lambda expressions anyway.
With this approach, the 1st version (JDK7) which prevents exploiting transparency with mentioned features and also prevents non-transparent features can be used to migrate all those anonymous inner SAM interface creation expressions out there to lambda expressions. Any local return or non-transparent 'this' will then be flagged by the compiler as invalid. Local returns can be replaced with labeled breaks, non-transparent 'this' references with references to final variables lambda was assigned to, likewise the recursive invocations and migration is done!
2 or 3 or 5 years later if/when JDK8 is released, people will learn to use lambdas and might want some more. Transparency of existing features can finally be allowed without breaking backwards compatibility. Everybody is happy.
>
> Z.
> --
> Zdenek Tronicek
> FIT CTU in Prague
>
Regards, Peter
More information about the lambda-dev
mailing list