On 9/5/19 6:14 PM, fo...@univ-mlv.fr wrote:


------------------------------------------------------------------------

    *De: *"Brian Goetz" <brian.go...@oracle.com>
    *À: *"Tagir Valeev" <amae...@gmail.com>, "Remi Forax"
    <fo...@univ-mlv.fr>
    *Cc: *"amber-spec-experts" <amber-spec-experts@openjdk.java.net>
    *Envoyé: *Jeudi 5 Septembre 2019 23:26:34
    *Objet: *Re: Draft JLS spec for records



        I don't think so. A compact constructor (or require
        initializer, as you propose) could be not the only
        constructor. An instance initializer is convenient because
        it's added to every constructor, regardless of whether it's
        compact or not. So the new thing doesn't supersede the
        instance initializer and I see no good reason to explicitly
        disable it.


    Vicente offered another reason why we might want to prohibit the
    instance initializer, if only out of expediency; it complicates
    the analysis of which fields are DA on all paths through the
    constructor (and therefore, do not need to be automatically
    initialized.)  If you have a record:

        record Foo(int i) {
            { this.i = 0; }
        }

    then the canonical constructor has to see that `i` is always
    initialized by the static init, and therefore should be not
    initialized.  Worse, if we have:

        record Foo(int i) {
            { if (tuesday) this.i = 0; }
        }

    then we have to issue a compilation error, since we have fields
    that are neither DA nor DU at the end of the initializer.

    None of this is impossible to do, of course; it's just not clear
    whether it's worth it, given the limited utility of instance
    initializers in records (because we've already banned instance
    fields.)


If we want to fix that with an the analysis, it will have to work on user-written code mixed with generated code,
it doesn't seem to be a good idea.

right I was thinking about the case:

record R(int i, int j) {
    public R {  // compact constructor
        if (i < 0) {
            this.i = -i;
        } else {
            this.j = j;
        }
    }
}

which doesn't have instance initializer blocks. The thing is where to draw between cases where the compiler will just issue an error and cases in which it will generate the missing initializations. In this particular case the compiler will have to be very clever and generate:

public R {  // compact constructor
        if (i < 0) {
            this.i = -i;
            this.j = j;  // automatic code
        } else {
            this.i = i; // automatic code
            this.j = j;
        }
    }

we can do it, it will be complex though, but do we want to do it? Where to draw the line?

Thanks,
Vicente

so it's Ok to not support instance initializers in record.

Rémi





Reply via email to