lambda expression parameters

Zhong Yu zhong.j.yu at gmail.com
Wed Dec 19 15:38:57 PST 2012


On Wed, Dec 19, 2012 at 3:43 PM, Howard Lovatt <howard.lovatt at gmail.com> wrote:
> First a disclosure. I personally always declare everything final by default, it suits my 'immutable' programming style.
>
> The problem I have is that currently I can't declare final and infer type, therefore I get stuck with mutable arguments and the following problems:
>
> 1. The issue I have with saying that FindBugs, IDE, etc. will find if I assign and don't use, is that if I assign and use it won't. For my programming style a multiple assign is almost certainly a bug and this bug won't be found.
>
> 2. If you are assigning to something you probably want to be careful about type. Therefore it makes sense for inference to play safe and make it final and require you to explicitly declare type if mutable.
>
> Therefore I would rather have arguments final by default and force you to specify if you want mutable.

If we do make them implicitly final, there's no incentive to provide a
non-final option - nobody has to have non-final method parameters.

> -- Howard.
>
> Sent from my iPad
>
> On 20/12/2012, at 4:17 AM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
>
>> 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