From: Joshua Cranmer on
On 10/18/2009 10:06 PM, Tomas Mikula wrote:
> I have searched this group for "abstract static methods" and found a
> couple of threads, but I think none of them was discussing the kind of
> semantics I am going to describe. As you might have guessed, I believe it
> would be useful :). I further believe it is fully complatible with the
> current language, but there might be caveats I have overlooked. I'm
> wonder if you would find it as useful as I do and if you see any problems
> with it. I know it is a long post and some parts may be difficult to
> understand. Therefore I will be thankful if you can read it all and think
> about it.

I saw a more detailed proposal at <http://kijaro.dev.java.net>, which
included a prototype implementation. The specification for said stuff is
linked here: <http://www.jroller.com/jadda/entry/meta_interfaces_revisited>.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
From: Andreas Leitgeb on
Tomas Mikula <tomas.mikula(a)gmail.com> wrote:
> I have searched this group for "abstract static methods" ...
> ... presence of no-arg constructor in a serializable class would be
> checked at compile-time rather than at run-time.

I think this is easily misunderstood. The newly possible compiletime
check would be for compiling the *concrete class* whose name you later
intend to specify dynamically at runtime. This does have some merit.

Still no compiletime check would of course be possible at the place
where you'd *use* that class dynamically, so nothing at all can be
helped about the reflection-part of this story.

There's still a slight "problem" with abstract static methods:
With respect to static members, *every* class is concrete.
Maybe you thought about static "create"-methods, as alternative
to enforced constructors?

From: Tomas Mikula on
On Mon, 19 Oct 2009 07:29:24 +0000, Andreas Leitgeb wrote:

> Tomas Mikula <tomas.mikula(a)gmail.com> wrote:
>> I have searched this group for "abstract static methods" ... ...
>> presence of no-arg constructor in a serializable class would be checked
>> at compile-time rather than at run-time.
>
> I think this is easily misunderstood. The newly possible compiletime
> check would be for compiling the *concrete class* whose name you later
> intend to specify dynamically at runtime. This does have some merit.
>
> Still no compiletime check would of course be possible at the place
> where you'd *use* that class dynamically, so nothing at all can be
> helped about the reflection-part of this story.

The idea here was to automate the reflection. Suppose a class is required
to have many static methods. Instead of checking if they are actually
present and have the correct signature manually, the method
Class.asImplementationOf(MyInterface.class) would do all the checking for
me.

> There's still a slight "problem" with abstract static methods: With
> respect to static members, *every* class is concrete. Maybe you thought
> about static "create"-methods, as alternative to enforced constructors?

If an abstract class MyClass does not have an implementation of a static
abstract method staticMethod() specified in its superclass/interface, it
can be detected in both the direct use and through reflection:

MyClass.staticMethod(); // this would be a compile-time error
Class.forName("MyClass").asImplementationOf(MyInterface.class);
// this would be a run-time error

My view is that with respect to abstract static members, not every class
would be concrete.
From: Tomas Mikula on
On Sun, 18 Oct 2009 19:58:43 -0700, Marcin Rzeźnicki wrote:

> On 19 Paź, 04:06, Tomas Mikula <tomas.mik...(a)gmail.com> wrote:
>> I have searched this group for "abstract static methods" and found a
>> couple of threads, but I think none of them was discussing the kind of
>> semantics I am going to describe. As you might have guessed, I believe
>> it would be useful :). I further believe it is fully complatible with
>> the current language, but there might be caveats I have overlooked. I'm
>> wonder if you would find it as useful as I do and if you see any
>> problems with it. I know it is a long post and some parts may be
>> difficult to understand. Therefore I will be thankful if you can read
>> it all and think about it.
>
> Hi,
> Interesting but I doubt it is going to be useful. First of all, because
> statics should remain non-inheritable, static abstract actually forces
> each subclass to implement its own definition - extreme nuisance in my
> opinion.

Yes (unless the subclass is abstract). I think in some cases it is
reasonable (as with the enforced no-arg constructor in Serializable, or
some other serialization static methods. For example, if I want to
deserialize an immutable object, I need to do it by a static method or a
special constructor, because the non-static readObject(...) method in
Java's serialization API is a mutator method. In my opinion it is
reasonable to enforce own implementation of a (de)serialization method).

> Example with generics can easily be substituted by some kind of
> "trait" parameter

Sorry, I don't know what you mean by "trait" parameter? Do you mean that
I would call the zero() method on some instance?
Like myDummyVector.zero()?

> or suitable simple design pattern (for example
> Factory), or even with classic sub-typing (zero vector needs not know
> its dimension, it can simply 'answer' with neutral element of the ring
> on which it is constructed for each and every component query),

Allowing operations between a concrete vector and this general zero
vector would require to also allow operations between 2D and 3D vetors -
the original type safety would disappear.

> no big
> win here either (eliminating type erasure is extremely welcome but for
> other reasons). One big advantage of inheritance is, in my opinion, that
> it enables you to compose more specialized classes from generic ones, it
> is easy to imagine algebraic ordering relation between types based on
> inheritance. Your version of statics breaks this assumption without
> promise of any reward in exchange.

I don't see how it breaks this relation between classes. Also now it is
possible to hide supertype's static methods by own implementation. I
would only add that in some cases this hiding would be required.
From: Marcin Rzeźnicki on
On 19 Paź, 13:08, Tomas Mikula <tomas.mik...(a)gmail.com> wrote:
> On Sun, 18 Oct 2009 19:58:43 -0700, Marcin Rzeźnicki wrote:
> > On 19 Paź, 04:06, Tomas Mikula <tomas.mik...(a)gmail.com> wrote:
> >> I have searched this group for "abstract static methods" and found a
> >> couple of threads, but I think none of them was discussing the kind of
> >> semantics I am going to describe. As you might have guessed, I believe
> >> it would be useful :). I further believe it is fully complatible with
> >> the current language, but there might be caveats I have overlooked. I'm
> >> wonder if you would find it as useful as I do and if you see any
> >> problems with it. I know it is a long post and some parts may be
> >> difficult to understand. Therefore I will be thankful if you can read
> >> it all and think about it.
>
> > Hi,
> > Interesting but I doubt it is going to be useful. First of all, because
> > statics should remain non-inheritable, static abstract actually forces
> > each subclass to implement its own definition - extreme nuisance in my
> > opinion.
>
> Yes (unless the subclass is abstract). I think in some cases it is
> reasonable (as with the enforced no-arg constructor in Serializable, or
> some other serialization static methods. For example, if I want to
> deserialize an immutable object, I need to do it by a static method or a
> special constructor, because the non-static readObject(...) method in
> Java's serialization API is a mutator method. In my opinion it is
> reasonable to enforce own implementation of a (de)serialization method).
>

Hi, possibly it is reasonable, but what is wrong with how it is done
today (readObject/writeObject) which you are not required to implement
if default behavior suffices?

> > Example with generics can easily be substituted by some kind of
> > "trait" parameter
>
> Sorry, I don't know what you mean by "trait" parameter? Do you mean that
> I would call the zero() method on some instance?
> Like myDummyVector.zero()?
>

I borrowed the terminology from C++. More or less, you add type
parameter (let's say <Zero extends ZeroVector>) which has a method
like getZeroVector() (strictly speaking ZeroVector has this method).
Actual type parameter provides concrete implementation.

> > or suitable simple design pattern (for example
> > Factory), or even with classic sub-typing (zero vector needs not know
> > its dimension, it can simply 'answer' with neutral element of the ring
> > on which it is constructed for each and every component query),
>
> Allowing operations between a concrete vector and this general zero
> vector would require to also allow operations between 2D and 3D vetors -
> the original type safety would disappear.
>

I don't get it, could you provide an example?

> >  no big
> > win here either (eliminating type erasure is extremely welcome but for
> > other reasons). One big advantage of inheritance is, in my opinion, that
> > it enables you to compose more specialized classes from generic ones, it
> > is easy to imagine algebraic ordering relation between types based on
> > inheritance. Your version of statics breaks this assumption without
> > promise of any reward in exchange.
>
> I don't see how it breaks this relation between classes. Also now it is
> possible to hide supertype's static methods by own implementation. I
> would only add that in some cases this hiding would be required.

I was not very clear, it was late when I was writing :-) I guess what
I was trying to say was that you can impose ordering based on
specialization (as opposed to parent-child relationship). Each class
in an inheritance chain either extends or redefines partially its
ancestor (I am using 'or' as logical or). Therefore each class is
either more specialized (if redefinition occurs and it accepts
stronger contract, as in Rectangle->Square) or equally specialized (if
extension occurs and all redefinitions do not change contract - I
treat extension as an interface extension so that class can be used
_additionally_ in different context). Your proposal forces implementor
to provide implementation for non-inheritable method, so it really
can't take any benefit from redefinitions up the chain. Therefore all
concrete classes are at most equally specialized as their context of
usage is determined by a static method. So it does not play well with
most "inheritance patterns". That's how I see it.