lambda expression parameters

Zhong Yu zhong.j.yu at gmail.com
Wed Dec 19 09:17:09 PST 2012


On Wed, Dec 19, 2012 at 10:04 AM, Ricky Clarkson
<ricky.clarkson at gmail.com> wrote:
> I'd just like to raise one potential case for making it implicitly final:
>
> Iterable<Boolean> list = someNumbers.map(x -> x = 5);
>
> (If it really returns a Stream, Streamable, CanBeStreamed or
> NotTonightDearImBusyStreaming, please give me some leeway.)
>
> The programmer is left wondering why the compiler says that map returns an
> Iterable<Integer> instead of an Iterable<Boolean>, and it's all because he
> used = instead of ==.  The programmer then wonders why Java didn't just give
> him a compile error when he assigned to the parameter, after all assigning
> to the parameter there is basically a no-op.

Static analyzers can catch that. For example in IntelliJ

    int f(int x) { return x++; }

will raise a noticeable warning: "The value changed at x++ is never used"

    int f(int x) { return x=5; }

will raise a less noticeable warning: "the value 5 assigned to x is never used"

I haven't tried lambda in IntelliJ 12, but hopefully the same analysis
exists; maybe it should be stronger and louder for lambda expressions.

Javac probably doesn't need to perform such analysis by default.

Zhong Yu


>
> On Wed, Dec 19, 2012 at 1:44 PM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
>>
>> On Tue, Dec 18, 2012 at 8:15 PM, Dan Smith <daniel.smith at oracle.com>
>> wrote:
>> > On Dec 18, 2012, at 5:43 PM, David Holmes <David.Holmes at oracle.com>
>> > wrote:
>> >
>> >> I don't grok the problem. If the parameter is not modified then it is
>> >> effectively final. Making parameters final is then only an
>> >> error-detection mechanism, and I don't see that is warranted in lambda
>> >> expressions. So I don't see "final by default" as warranted.
>> >>
>> >> Having to add back the inferred type to enable final to be added
>> >> doesn't
>> >> seem like a large burden.
>> >
>> > Yeah, I think I agree with David.  The times when it seems most useful
>> > to say "this parameter is final and I definitely don't want anyone changing
>> > it" are when you've got a large lambda body, and then it's really not so
>> > painful to give your parameters full declarations ('final String s').
>> >
>> > It's worth noting that 'final' parameters and local variables didn't
>> > exist in the original language and were only added to support the "captured
>> > variables must be final" rule when anonymous/local classes were added.  If
>> > "effectively final" were an option back then (don't know if it's something
>> > they thought about or not), I would bet we still wouldn't have 'final'
>> > parameters and local variables.  They're really a lot less useful than
>> > 'final' fields -- because all interaction is in a single thread and within a
>> > single block of code.
>>
>> Agreed, although most method parameters and many local variables are
>> conceptually final, people don't bother to mark them final.
>>
>> Making method parameters implicitly final is inconsistent with
>> existing practices; the benefit is dubious:
>>
>> If a programmer assigns a new value to a method parameter, and later
>> reads it, it is very likely intentional, there's no need for alarm
>> here.
>>
>> If a programmer assigns a new value to a method parameter, and never
>> reads it, it is probably a mistake; fortunately IDEs will raise a
>> warning for it.
>>
>> Zhong Yu
>>
>> >
>> >> On the other hand can't the compiler accept
>> >> parameter modifiers even if it infers the type?
>> >
>> > No, there are two syntax options: list of identifiers, or full method
>> > parameter list.  Less complex that way.
>> >
>> > —Dan
>> >
>>
>


More information about the lambda-dev mailing list