On May 10, 2018, at 9:42 AM, Remi Forax <fo...@univ-mlv.fr> wrote: > > You can try to bridge inside the implementation, i.e. you have one method, so > one signature, with an indy in it (indy let you access to the class metadata > and the runtime view) that can decide to which implementations (implemented > as side static methods) you want to delegate. I've already done this in case > you have one method in Java that match multiple methods in a dynamic > language. (I did not write too)
Yes, this is something the proposal buys us (by having L-only). The JVM sets up bridges internally, at runtime (or AOT time), using full knowledge of types. (At least, as they are loaded.) The easiest thing is to assign *one* calling sequence per v-table slot, based on the preferences of the first class allocating the slot. That can fail under obscure circumstances when one v-table slot is constrained by two supers (1 or 2 interfaces), which is rare but possible. For single inheritance, everything works. I'd like to explore, making MI-induced conflicts a CLC failure, under the theory that they won't happen in practice. CLCs, after all, exist to prevent divergence of opinions about the classfile of a named type, and the point of contention is a v-table slot. So this is natural to try as a rider on the CLC rules. (Note that failures only come when, out of two supers in a MI situation, one fails to be recompiled with knowledge of values. E.e., a third-party interface using LocalDate fails to recompile, and fourth-party code does recompile but implements the third-party interface *and* also implements a core interface that also mentions the same descriptor. Sounds rare to me.) If, after experimentation, we realize that we don't want to tolerate a failure in those corner cases (of legacy APIs mixed in just right) then jump forward to Brian's suggestion, which is simply making up multiple internal/invisible bridges. They only have to be built for default methods, AFAICS. Since they are a pain and source of bugs, I don't want to do them in our earlier explorations. Dan could rejoin here (following Remi's method but in reverse) that adding the Q-types doesn't change this story much: The JVM can treat Q-types and L-types as interchangeable, *except* when v-table calling sequences are assigned by the JVM, and when things get flattened. The thing I like about ValueTypes that Q-types don't give me is that it restrains clever bytecode generators from creating nullable versions of Q-types *for the long haul*. How about this for a proposal: We do Q-less L-world for now, forcing language compilers to make the val-vs-ref decision consistently *for each whole classfiles* and by implication *as globally as possible*, and save for later a new descriptor bit which says "this thing is nullable" (if a value) and/or "this thing is not nullable" (if a ref). Such descriptors would give us emotional types. They are not needed (and a distraction) to give us value types. — John