From: rossum on
On 20 Oct 2009 14:10:56 GMT, Andreas Leitgeb
<avl(a)gamma.logic.tuwien.ac.at> wrote:

>I'm not familiar with that idiom, but an uncrossed "t" is hardly a "t",
>but rather an "l" (well, depending on the font, perhaps). With that,
>the question of enforcing c'tors is even less "compelling" than making a
>"t" a real "t".
"Dotting all the i's and crossing all the t's" is an idiom for making
sure that all the small details are correct.

rossum

From: Andreas Leitgeb on
rossum <rossum48(a)coldmail.com> wrote:
><avl(a)gamma.logic.tuwien.ac.at> wrote:
>> I'm not familiar with that idiom, but an uncrossed "t" is hardly a "t",
>> but rather an "l" (well, depending on the font, perhaps). With that,
>> the question of enforcing c'tors is even less "compelling" than making a
>> "t" a real "t".

> "Dotting all the i's and crossing all the t's" is an idiom for making
> sure that all the small details are correct.

Thanks!
From: Daniel Pitts on
Tomas Mikula wrote:
> On Mon, 19 Oct 2009 16:22:56 -0700, Daniel Pitts wrote:
>
>> Tomas Mikula wrote:
>>> On Sun, 18 Oct 2009 19:19:55 -0700, Peter Duniho wrote:
>>>
>>>> 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 :). [...]
>>>> You aren't the first. However, in C++, C#, Java, and languages like
>>>> them, you simply are never going to have methods that are both virtual
>>>> and static. And since abstract implies virtual, that rules out
>>>> abstract static methods too.
>>> I'm not talking about virtual static methods. In this case, abstract
>>> would not imply virtual. My second use case could most probably be
>>> accomplished in C++ by Concepts (though Concepts didn't make it to C+
>>> +0x). In fact, it is achievable with current C++ templates, only
>>> without compile time checking --- it is possible to call
>>> T::staticMethod() where T is a template parameter.
>> C++ Template programming provides compile-time polymorphism. In Java,
>> you don't have Templates, so there is no similar approach.
>>
>> If you think you need a "static" method to be overidden, then you really
>> need to have a non-static method, on a polymorphic object.
>
> I rather think that sometimes I need to enforce that the static method
> _will_ be overridden in every subclass. Non-static methods do not enforce
> overriding, because they inherit the implementation from superclass. Note
> that I don't want that the following example outputs "B", as was proposed
> in some other discussions about abstract static methods.
>
> class A {
> static void f(){ System.out.println("A"); }
> }
>
> class B extends A {
> static void f(){ System.out.println("B"); }
> }
>
> A a = new B();
> a.f();

Why do you want to enforce a static method to exist in children? I can
think of no good reason for it.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Tomas Mikula on
On Tue, 20 Oct 2009 14:07:22 +0000, Andreas Leitgeb wrote:

> Tomas Mikula <tomas.mikula(a)gmail.com> wrote:
>>> > The idea here was to automate the reflection.
>>> Sorry, that is a non-starter.
>
>>> If you don't know the class at compiletime, then neither does the
>>> compiler, so there's nothing the compiler could possibly do for you
>>> beyond what it already does, namely write bytecode to have the JVM
>>> check it all at runtime.
>
>> In my original post I noted that the use of Class's newly introduced
>> method
>> <T> Implementation<T> asImplementationOf(Class<T> clazz);
>> would have the restriction that the type T is known at compile time.
>
> The syntax you use suggests, that the result of that function would be
> some object (yes, an instance, a bit like the Class-Objects), that
> offers methods to call the dynamically loaded class' static methods...
>
> class MyBase {
> static abstract void foo();
> }
> class MyImpl extends MyBase {
> static void foo() { System.out.println("Called me"); }
> }
> use:
> Implementation<MyBase> impl = Class.forName("MyImpl").
> asImplementationOf(MyBase.class);
> impl.foo(); // prints "Called me".
> Implementation<MyBase> implFail = Class.forName("MyBase").
> asImplementationOf(MyBase.class);
> // the preceding line throws error, because MyBase doesn't //
> *implement* the abstract method foo().
>
> Is that your intention?

Yes.

> If yes, please read on; If no, the rest of my posting may be moot.
>
>> In this case, the compiler can generate the bytecode to check if the
>> 'this' class implements T.
>
> I think, that whenever such a hierarchy of static methods is wanted, an
> alternative solution with virtual (i.e. non-static) methods is easily
> available with (if at all) only small cosmetic "up to taste" drawbacks.
>
>> - it requires to get an unnecessary instance (not so bad yet); -
>> getting this instance requires reflection
> Reflection already starts at Class.forName(...) and if I understood
> correctly, you didn't intend to replace that call.

Correct.

>
>> - using reflection for getting an instance requires conventions
>> which cannot be checked at runtime (such as the presence of some
>> particular (e.g. no-arg) constructor)
>
> Of course it *can* be checked *at runtime*!

Sorry, I meant compile time. But they still can't be checked _elegantly_
at runtime.

> See Class.newInstance().
> If that throws an Exception, then there obviously was some problem in
> the attempt to call the no-args constructor of the class. This simple
> line:
> MyBase mb = (MyBase)Class.forName("MyImpl").newInstance();
> already checks *at runtime*, that
> - the named class is loadable
> - the named class has a no-args c'tor - the no-args c'tor succeeded
> (did not throw an exception itself) - the thusly construed instance is
> castable to "MyBase".

I was aware of this simple and only example where the convention can be
checked at runtime quite concisely. What if I want to use another
constructor and, say, two static methods. Things get a little messy.

>> Furthermore, if I forget to override pseudoStatic() or realStatic() in
>> a subclass, I will get the realStatic() from superclass, which is not
>> what I want.
>
> If you forgot to override pseudoStatic(), then the derived class will
> not even compile (assuming it is not declared as abstract, itself). For
> non-static methods, all those mechanisms are already well worked out.

It will compile. Consider
abstract class A {
public abstract void pseudoStatic();
}

class B extends A {
public static void realStatic(){...}
public void pseudoStatic(){ realStatic(); }
}

class C extends B {
// If I forget to override pseudoStatic, I get the one from B.
// If I provide pseudoStatic, but not realStatic,
// I get realStatic from B.
}

So I really need to provide them both, but the compiler doesn't force me
to do so. I could make the realStatic private to reduce the danger to
half, but then I wouldn't be able to call it the classic way C.realStatic
().

> Overriding realStatic() is not an issue, as you just wouldn't define it
> in the base class, and so the call to realStatic() in the overridden
> pseudoStatic() would fail at compile time, until you either add a
> realStatic() method, or just did something else in the (enforcedly
> existing) implementation of pseudoStatic().

The same applies here.

>
>>> I don't think, that calling static methods on dynamically
>>> named classes is worth such deep changes as you seem to have in mind
>>> for this task.
>> The good thing about it is that the changes are not real changes, just
>> extensions. So far I think they are all backward compatible with
>> current specification. No old code would be broken if these extensions
>> are introduced.
>
> I do not even doubt that.
> It's just that these extensions add much too much fuss and doesn't seem
> to gain a substantial advantage in return.

Okay, thank you for the opinion. I still find the concept of enforced
static methods/constructors and the ability to call them on generic type
parameters very useful. But I may be biased towards my recent needs. I
would of course not insist on the syntax/API proposed here. It was just
the first idea that seemed quite consistent.
From: Tomas Mikula on
On Tue, 20 Oct 2009 12:12:31 -0700, Daniel Pitts wrote:
>
> Why do you want to enforce a static method to exist in children? I can
> think of no good reason for it.

And I also want to enforce constructors. I provided two use-cases.

1. serialization frameworks. It is already required that a Serializable
class has a no-arg constructor. But this is not required at compile time.
Other variant is to require some particular constructor or a creator
static method, such as MyClass.readObject(ObjectInputStream) (though this
method is non-static and not mandatory in Serializable).

2. For calling static methods on generics. My example was
abstract class Vector<V extends Vector<V>>{
/** returns a zero vector */
public abstract static V zero();
}

Then somewhere else I would like to use code as this:

MyClass<V implements Vector<V>> { // 'implements' is not valid here now
...
V v = V.zero(); // not possible now
...
}