[prev in list] [next in list] [prev in thread] [next in thread]
List: openjdk-lambda-spec-observers
Subject: Re: Minor wording issue around effectively final definition
From: Dan Smith <daniel.smith () oracle ! com>
Date: 2013-02-12 22:41:09
Message-ID: 0F4995BE-8898-4027-970C-4E22BBB4493B () oracle ! com
[Download RAW message or body]
Thanks for the feedback, Neal.
Note that the constraint about DA/DU is about the point of assignment, not the point \
of capture.
Here, the only assignment to 'i' occurs when it is (!DA)&&DU; and at the only use of \
'i', it is DA:
int i;
i = 2;
if (false) {
Runnable r = () -> { int j = i; };
}
So everything's okay.
The (!DA)&&DU restriction was introduced to handle situations like this:
int i;
i = 2;
if (false) {
i = 3;
Runnable r = () -> { int j = i; };
}
Here, 'i' is DU wherever it is assigned to; but if we were to declare 'i' 'final', \
there would be an error at the point of the second assignment, per JLS 7 6.5.6.1, \
precisely because it is also DA. That's bad, because we want "effectively final" to \
mean "could have been declared final".
(The treatment of final variables in situations like this was unclear previously, so \
this is a spec change (bug #4721499). I don't think it has made its way into the \
javac code yet. Ultimately, the goal will be to make the spec for "final", the spec \
for "effectively final", and the implementation all be in sync.)
Now, back to your original example:
if (false) {
int i;
i = 2; // i is both definitely assigned and definitely unassigned here
Runnable r = () -> { int j = i; }; // error: i not effectively final
}
Here, again, 'i' is both DA&&DU at the assignment, so if it were to be declared \
'final', there would be an error -- you can't assign to a DA final variable. So 'i' \
shouldn't be effectively final.
But maybe that just pushes the criticism back to the rules about final variables. It \
is somewhat surprising that this would be illegal:
if (false) {
int i;
i = 2; // i is DA, represents a "value", can't be assigned to (per 6.5.6.1)
}
I'll investigate that further.
—Dan
On Feb 12, 2013, at 9:46 AM, Neal Gafter <neal@gafter.com> wrote:
> Sorry, the example should have been
>
> int i;
> i = 2;
> if (false) {
> // i is both definitely assigned and definitely unassigned here
> Runnable r = () => { int j = i; }; // error: i not effectively final
> }
>
> Cheers,
> Neal
>
> On Mon, Feb 11, 2013 at 4:36 PM, Neal Gafter <neal@gafter.com> wrote:
> Here is one example that does not work right according to the spec:
>
> if (false) {
> int i;
> i = 2; // i is both definitely assigned and definitely unassigned here
> Runnable r = () => { int j = i; }; // error: i not effectively final
> }
>
> One way to fix this section of the spec is to remove the words "and not definitely \
> assigned" twice where they appear in the definition of effectively final.
> On Mon, Feb 11, 2013 at 10:53 AM, Dan Smith <daniel.smith@oracle.com> wrote:
> On Feb 11, 2013, at 7:00 AM, Srikanth S Adayapalam <srikanth_sankaran@in.ibm.com> \
> wrote:
> > Hello !
> >
> > 0.6.1 (4.12.4) reads:
> >
> > A local variable or a method, constructor, lambda, or exception parameter is \
> > effectively final if it is not final but it never occurs as the left hand operand \
> > of an assignment operator (15.26) or as the operand of an increment or decrement \
> > operator (15.14, 15.15). [jsr335-4.12.4-10]
>
> > In addition, a local variable whose declaration lacks an initializer is \
> > effectively final if all of the following are true: [jsr335-4.12.4-20]
> > • It is not final. [jsr335-4.12.4-20-A]
> > • Whenever it occurs as the left-hand operand of an assignment operator, it is \
> > definitely unassigned and not definitely assigned before the assignment (that is, \
> > it is definitely unassigned and not definitely assigned after the right-hand \
> > operand of the assignment) (16).
> > I think the first sentence meant to say, never occurs as the left hand operand of \
> > a *compound* assignment operator.
>
> The intent is to cover both compound and simple assignments.
>
> The first sentence says that if you never assign to a variable, it's effectively \
> final.
> The second sentence says that if you _do_ assign to a variable, it may still be \
> effectively final if the assignment is the _first_ assignment.
> Note that there's a restriction, separate from "effectively final," that a variable \
> must be definitely assigned wherever it is referenced, including in a compound \
> assignment.
> I think the complexities you're worried about are bundled up inside the definitions \
> of "definitely unassigned" and "definitely assigned". But if you're unsure, feel \
> free to share a concrete example of something you don't think will work right.
> —Dan
>
>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic