Final defenders
Rémi Forax
forax at univ-mlv.fr
Tue Aug 7 11:39:47 PDT 2012
On 08/07/2012 07:53 PM, Bob Lee wrote:
> I'd strongly prefer enabling private instance methods from the get-go. If
> we don't, users will make methods public that shouldn't be. If we allow
> private static methods only, I'll have to pass "this" in explicitly, and my
> code will look like Python.
>
> Bob
Hi Bob,
private methods is a *big* change in the way the interface works because
a class inside the interface should be able to call it. From the
compiler point of view,
this means to introduce a method which is package visible and package
visible methods
like protected ones are like hell to implement for the VM.
Rémi
>
> On Tue, Aug 7, 2012 at 8:18 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
>
>> Just to head off the obvious follow-on questions:
>> - What about private methods in interfaces: entirely feasible, but not
>> targeted at 8
>> - What about protected methods: possibly trickier than private methods,
>> not targeted at 8
>> - What about package-private methods: feasible, would require additional
>> syntax (e.g., "package" modifier)
>> - What about static methods: being considered by the EG
>>
>> On Aug 7, 2012, at 7:34 AM, Aleksey Shipilev wrote:
>>
>>> Hi,
>>>
>>> TRAITS! Now, while Brian is gasping with exertion, I'll continue. While
>>> studying the it2-bootstrap branch code, I have come across using
>>> defenders in trait-like fashion:
>>>
>>> public interface StatefulOp<T, U, V> {
>>> public boolean isStateful() default {
>>> return true;
>>> }
>>> }
>>>
>>> In this case, the defender is not particularly the fallback default, but
>>> really an enforced implementation. However, lacking language support for
>>> these cases, I can do:
>>>
>>> public class MyRogueOp implements StatefulOp {
>>> public boolean isStateful() {
>>> return false; // eat that!
>>> }
>>> }
>>>
>>> ...and the defender rules will count my concrete implementation as
>>> legitimate one. This makes relying on isStateful() quite a bad idea in
>>> the library.
>>>
>>> That makes me thinking if we need to embrace it, and realize that some
>>> of the defenders are really final. My suggestion is simple: let's mark
>>> the final defenders "final"!
>>>
>>> In simplest form:
>>>
>>> public interface StatefulOp<T, U, V> {
>>> public final boolean isStateful() default {
>>> return true;
>>> }
>>> }
>>>
>>> "final" is not allowed in interfaces by the current rules, so we can use
>>> this loophole to introduce a new meaning. However, this feels wrong to
>>> provide the default implementation, and instantly forbid the extension.
>>> So, maybe this is better:
>>>
>>> public interface StatefulOp<T, U, V> {
>>> public boolean isStateful() final {
>>> return true;
>>> }
>>> }
>>>
>>> This should be more complicated to implement in compiler, but it clearly
>>> mandates the method body is the final implementation.
>>>
>>> This is not completely enforceable in the compile time, and so it
>>> complicates the method dispatch a bit. We need to check if there is any
>>> superclass final defender in the hierarchy, that can piggyback on the
>>> defender selection we have now. Also, two colliding defenders, no matter
>>> if the pairs are default/final, default/default, or final/final should
>>> render the same error as default/default collision now.
>>>
>>> Additional concern is the evolution. We need to explore two things:
>>> 1. Can we add "final" to the defender on the existing interface?
>>> 2. Can we remove "final" from the defender on the existing interface?
>>>
>>> The answer to both seems to be "yes", because the same class of bugs we
>>> have already with abstract classes and visibility rules, also
>>> unenforceable with separate compilation. We can still do compile-time
>>> checks so that code compiled at once would never throw a linkage error.
>>>
>>> Thoughts?
>>>
>>> -Aleksey.
>>>
>>
>>
More information about the lambda-dev
mailing list