Menu

#16 relaxed mj rejects static abstract methods

open
nobody
None
5
2003-03-16
2003-03-12
Keunwoo Lee
No

Relaxed MJ rejects the following class:

public class X {
public static class Y{}
public static class Z{}

public abstract static void f(X _);
public static void f(X@Y _) {}
public static void f(X@Z _) {}
}

The error message:

X.java:5:11 error: Method "f" has an illegal
combination of modifiers: abstract cannot be
combined with private, static, final, native,
strictfp, or synchronized [JLS 8.4.3]

In ordinary Java, abstract static methods don't
make any sense.

In ordinary MJ, you can later fill in cases for such
methods, but you always need to provide the
default case. So, abstract static methods have a
natural dynamic interpretation, but are statically
illegal.

In RMJ, the static restriction on top-level abstract
external generic functions goes away. So,
abstract static methods should be legal, and
should be typechecked like abstract external
generic functions.

Discussion

  • Craig Chambers

    Craig Chambers - 2003-03-13

    Logged In: YES
    user_id=724721

    You say "In RMJ, the static restriction on top-level abstract
    external generic functions goes away." If you mean that a
    static method can be abstract in RMJ, then I've never
    intended this to be so. You could make a case that it
    should be allowed, but we'd have to think about it first.

    However, it is the case that RMJ intends to allow both
    internal and external methods to be abstract, even for
    concrete receiver classes. However, the current RMJ
    implementation does not yet support abstract internal
    methods of concrete receiver classes (because the mjc
    compiler hasn't been relaxed enough yet; the RMJ loader
    would handle it fine). This is one of the known limitations
    of the current RMJ implementation; see others in the
    relaxed/TODO file. Your test case is using internal
    methods, so it's not going to be allowed (yet),
    independently of the static keyword.

     
  • Keunwoo Lee

    Keunwoo Lee - 2003-03-13

    Logged In: YES
    user_id=26937

    Right, by "static restriction on top-level abstract
    external generic functions", I meant static in the
    sense of static typechecking, not the Java static
    keyword. In other words, MJ typechecking disallows
    abstract external generic functions, whereas RMJ
    does not.

    Since I consider MJ static methods to be the "moral
    equivalent" of external generic functions wrapped
    inside a namespace, I assumed that RMJ would
    support abstract static methods as well. I see no
    countervailing language design or translation
    strategy issues (the simplest translation strategy:
    generate a concrete static method that forwards the
    call to a specially named external gf).

    The language design issues are relatively simple:

    + How to typecheck abstract static methods? I claim
    any static method
    Class.Method(Arg1 a1, ..., ArgN aN)
    can be typechecked identically to an external generic
    function named
    Arg1.mangle$Class$Method(Arg2 a2, ..., ArgN aN)
    Note that this illuminates the fact that no-argument
    static methods cannot be abstract. This restriction
    makes sense since, the programmer could not
    provide any implementing cases.

    + How to declare overriding cases of static methods?
    I propose 2 mechanisms:

    (1) declare a static overriding case in a subclass:
    class A { abstract static void f(A a); }
    class B extends A { static void f(A@B b) {} }

    (2) mark an external overriding case with the "static"
    keyword; the "receiver" position should be named for
    the static method's introducing class:
    static void A.f(A@B b) {}

    Case (1) actually introduces a new kind of syntactic
    ambiguity---what if B introduces a new static method
    f(A), which is legal in Java?

    class B extends A {
    static void f(A a) {}
    static void f(A@B b) {} // what does this override?
    }

    In order to allow programmers to resolve this
    ambiguity, we can expand the syntax:

    static void A.f(A@B b) {} // what does this override?

    or simply require that programmers declare such
    overriding cases externally.

    Obviously, I don't need these features now. They're
    not really fundamental RMJ design issues either.
    But I've actually wanted to write static multimethods
    with abstract cases.

     
  • Craig Chambers

    Craig Chambers - 2003-03-14

    Logged In: YES
    user_id=724721

    Static methods are not inherited from one class to another,
    unlike top-level methods, so I don't think they're the same
    thing. At least not in regular Java or MJ. So I don't want
    to change that model and have static methods be inherited
    in RMJ. It's still fair to allow static methods (just like
    regular methods) to be abstract, if additional multimethods
    are provided in the same class to handle all the concrete
    subclasses that are known (and that will be loaded at
    run-time). But this is exactly the case of internal
    abstract methods that isn't handled yet by the RMJ compiler.

     
  • Craig Chambers

    Craig Chambers - 2003-03-16
    • status: open --> wont-fix
     
  • Craig Chambers

    Craig Chambers - 2003-03-16
    • labels: 473323 -->
    • milestone: 251539 -->
    • status: wont-fix --> open
     

Log in to post a comment.