Part F - Question

Srikanth S Adayapalam srikanth_sankaran at in.ibm.com
Mon Dec 9 21:10:27 PST 2013


> From: Dan Smith <daniel.smith at oracle.com>
> Subject: Re: Part F - Question
> 
> Yes, there's a spec/implementation discrepancy right now.  We're 
> discussing internally how we'd like to handle this.  (Any comments 
> here are welcome, too, of course.)

OK, Here is some input:

The present definition of value/void compatibility matches that of
"regular" or "vanilla" methods. That has its merits as far as language
regularity/consistency goes, but can be a tad too pedantic when carried
over to lambdas: I wonder if things get much simplified for compiler 
implementers [*] if we choose to adopt a pragmatic definition that would 
not amount IMO to any loss of useful functionality:

So the suggestion:

For lambda's with expression body - no change is required.
For lambda's with block bodies - what would it mean if the definition
is tweaked to say:

For the purposes of applicability checks *only*
    - A block bodied lambda is void compatible if every return in its
body lacks an expression (or there are no return statements in its body)
    - A block bodied lambda is value compatible if every return in its
body is of the form "return expression"
    - A block bodied lambda is also value compatible if the last statement
in its body is a throw statement.

I see two ramifications of such a change:

1. Lambda's of the form:

       (x) -> { if (x > 10) return x; }

would be seen to be value compatible for the purposes of potential 
applicability 
checks instead of being declared as being neither value nor void 
compatible per the
present rules. So, what ? This is a distinction without a difference - 
This is a 
broken lambda and by declaring it as value compatible for potential 
applicability 
checks, we are simply but surely deferring the error reporting to a later 
stage. 
(It could even result in better error messages in some cases based on an 
implementation) 

2. A lambda of the form: 

() -> { while (true); }

would not be seen to be value compatible.

Again, it appears to be that there is no major loss of functionality due 
to this.

In general, there is value (sorry for overloading the term :)) to 
deducing/treating
methods that don't complete normally as being value compatible (assuming 
otherwise
they are well formed), as this supports a bunch of use cases such as

    - "abstract virtual methods" in a concrete class. You often don't want 
to introduce
a new abstract method in a concrete class because that would burden the 
entire hierarchy
while the new method could be pertinent only to a few parts of the 
hierarchy. So provide
an implementation that just throws an exception to shut up the compiler.

    - Invalid inputs: A switch case statement may handle variety of valid 
inputs and
the ultimate statement in the method could be a throw for invalid values.

    - while (true) server loops.

I think the special allowance to treat a lambda as being value compatible 
if its last statement
throws an exception would cover these cases adequately.

The present definition makes (as the spec calls out) value-void 
compatibility a non-structural
property - necessarily calling for control/data flow analysis to be 
performed to determine the
shape. It is not clear to me that the benefits outweigh the cost to an 
implementation. With the
suggested changes even a basic AST visitor would suffice. 

(As an aside: (non-compiler) tool builders have some interesting 
challenges here too: Compiler
have it easy - they see a broken program and they reject it. Right now I 
am working on providing
code completion support for type elided parameters - the lambda is being 
written "just now",
the programmer is requesting code assistant support to write the lambda - 
now if a tool builder
implements the spec rigorously and holds a lambda as being not value 
compatible because the
return statement has not been yet written, the method invocation may never 
be resolved and the
elided types will never be inferred.) 


[*] We have solved this problem in the Eclipse compiler.

Thanks!
Srikanth 


More information about the lambda-spec-observers mailing list