abstract static methods (again)

T

Tom Anderson

But I admit that my familiarity with frameworks of this kind is
slight. Perhaps they're just not suited for classes whose instances
lack obvious defaults. (Maybe they're only good for singletons?)

They have a mechanism for configuring objects as well as creating them. I
use one which for each object you want to create, there's a property file,
which looks like:

$class=com.sosman.strawman.Comedian
joke=A compiler, a linker, and an editor walk into a bar ...

Which is translated by the reflective machinery into calls like:

Class cl = Class.forName("com.sosman.strawman.Comedian");
Object obj = cl.newInstance();
cl.getMethod("setJoke", String.class).invoke(obj, "A compiler, a linker, and an editor walk into a bar ...");

With some more stuff to deal with properties that aren't strings. It's not
pretty, but it quite often works.

It might be better if the framework tried to find a constructor which
would take the specified parameters, but it's not obvious how you'd do
that. However, i don't see how Tomas's proposal would help.

tom
 
T

Tom Anderson

Now I present two examples where it would be useful.

(1) Eliminate or reduce the use of reflection in serialization frameworks.

This example isn't actually about your proposal, it's about ...
a new magic class Implementation<T>

.... so i'm going to ignore it.
(2) The second use case is with generics, but would require reified
generics (which I hope will appear in some future version of Java).

Suppose you have an abstract class Vector which represents a vector in a
vector space (don't confuse with java.util.Vector) and a few
implementations, like Vector2D and Vector3D. [...] Now let's have a
generic class that will use vectors and do operations on them, but
doesn't really care about their actual dimension. So it will work with
abstract type Vector. But for some operations it may be necessary to
obtain the zero vector, without explicitely knowing the actual type of
vector.

This is a good use case. But i suspect it can be done with java as it
stands now - rather than reified generics, you factor out a Type Object,
as the patternists call it. Vectors can tell you their type object, and
the type object can give you a zero.

Like this, for instance:

http://urchin.earth.li/~twic/Code/MutuallyRecursiveGenerics/Vector.java

Now, i should say that that is some fairly bonkers generics (in fact, i
think i can now claim Double Wizard status at generics). It took me a good
while to get the types straight, and even now, the declarations are of a
mind-searing eldritch uncanniness verging on the Lovecraftian.

But what we need to fix this is some more concise generics syntax, not
some semantically befuddled new kind of method inheritance. I can't say
exactly what, though.

tom
 
T

Tom Anderson

Thanks for the entertaining example, but I think it's beside the point.
This type of argument "it's bad for this exemplary usecase, so it must
be bad for all usecases" is obviously flawed. (or was a joke, itself)

On second thought: If the Entertainers were designed to be dynamically
loaded by name, then Comedians just wouldn't have any chance of a individual
default joke. They could offer their Joke- constructor, but unless they
also offered a no-args one, they just wouldn't ever be successfully engaged.

This whole topic is inspired by dynamic loading of classes. Otherwise, there
wouldn't really be any use for dictating constructors at all. Dynamic loading
of classes seems to me of increasing importance with all those AppServers,
J2EE, ... Demanding the default-constructor (or even with a specific set
of arguments) for those classes imposes no new restriction, just formalizes
the restrictions that were already imposed by documentation and use.

This problem was solved in the golden age of the Patternists. The solution
is that you don't load Entertainers, you load EntertainerAgencies.

public interface EntertainerAgency {
public Entertainer hire();
}

String agencyName = loadFromWherever();
EntertainerAgency agency = (EntertainerAgency)Class.forName(agencyName).newInstance();
Entertainer e = agency.hire();

The question of some putative Entertainer constructor goes away. You do
have the question of the EntertainerAgency constructor, but this is much
less pressing. If it really worries you, use a EntertainerAgencyFactory.

Before you ask, yes, it's factories all the way down. Until you reach the
turtles.

tom
 
T

Tom Anderson

Indeed nice, but what would be the extra effort to create e.g. a
@StringArgConstructor annotation and its processing? And then also
a @StringStringArgConstructor and a @StringMyFooIntArgConstructor, ...

Or maybe just a @DefinedConstructor annotation that takes an array of
classes as a parameter.

tom
 
T

Tomas Mikula

They have a mechanism for configuring objects as well as creating them.
I use one which for each object you want to create, there's a property
file, which looks like:

$class=com.sosman.strawman.Comedian
joke=A compiler, a linker, and an editor walk into a bar ...

Which is translated by the reflective machinery into calls like:

Class cl = Class.forName("com.sosman.strawman.Comedian"); Object obj =
cl.newInstance();
cl.getMethod("setJoke", String.class).invoke(obj, "A compiler, a
linker, and an editor walk into a bar ...");

With some more stuff to deal with properties that aren't strings. It's
not pretty, but it quite often works.

It might be better if the framework tried to find a constructor which
would take the specified parameters, but it's not obvious how you'd do
that. However, i don't see how Tomas's proposal would help.

The use of my proposal here would be to enforce a constructor or a static
creator method that would create an initialized object from
ObjectInputStream/JAXBElement/javolution.xml.XMLFormat.InputElement
/...
 
A

Arved Sandstrom

Tom said:
Or maybe just a @DefinedConstructor annotation that takes an array of
classes as a parameter.

tom
That's the way I would do it - I managed to get an example of such
working after some anguish (I am not _that_ familiar with the annotation
processing APIs). To use the example provided in my cite, you can pick
off the AnnotationMirror for the Element annotated with
@DefinedConstructor, and use that (to wit, getElementValues()) to
retrieve the classes that you've put into a parameter of the
annotation...this just gets passed down the chain to the visitor. And
down in the visitor, the actual parameters to the ctor are available
via getParameterTypes() on the ExecutableElement.

I find the APIs a bit painful, and maybe others do as well. But on the
plus side, you only need to define a utility annotations processor once,
and then supply it (and others) in a JAR for javac to use. Something
like a @DefinedConstructor annotation _is_ going to cover a lot of
cases, so it's worth the effort, IMHO.

AHS
 
T

Tomas Mikula

Formal arguments have to be invariant with respect to overriding in
Java, you simply created method overload which will be used when
compiler is sure that runtime type of argument will be Vector2D. You
will still have to provide 'generic' add method.

No. Notice how add() is declared in Vector:
public V add(V v);
It works on type V.
When Vector2D is declared as
Vector2D extends Vector<Vector2D>,
Vector2D is substituted for V. So Vector2D's add() method is only
required to work on Vector2D instances. If Vector2D was declared as
Vector2D<V extends Vector<V>> extends Vector<V>,
then Vector2D would have to implement the add() method that takes any
subclass of Vector and returns the same subclass of Vector as it takes.
Your example does not
help either (or I cannot see how it would) because you will not be able
to dispatch on v's actual type unless you change how invokestatic works.

I'm not sure if I understand, but in the implementation of Vector2D V is
bound to Vector2D at compile time.
Yeah, right, but consider what happens when someone implements multiple
interfaces, or when inheritance tree changes, or when someone inherits
multiple interfaces with conflicting statics and so on.

Right now I can't think of any problems different from those with non-
static methods.
This example is
basically hand-crafted implementation of virtual dispatch :)

...

Well, ok, but it does not change anything. Still you have to re-
implement invokevirtual by hand all the time :)

Well, if you want to extend the behavior of a non-static method, you
still have to call the inherited method by hand (super.someMethod()) and
then do your specific work. This is no different from my example. The
only real disadvantage is when you want to inherit the method as is. Yes,
this is not possible with my proposal and you have to call the
superclass's method by hand. Though my proposal was targeted at uses
where you want to provide own implementation in each class. But I'm
finally getting what you are trying to say - that this feature might
encourage design that will later turn out as wrong. Yes, there might be
this danger, as is with many other features.
or omit it so then you impose different context. Namely, pretend to
be able to read remote files while you are not. And one more
question:
//client code
Stream s = new AudioVideStream(..);
read10Bytes(s);
public byte[] read10Bytes(Stream s) { if (!Stream.isReadable(file))
//how would you dispatch it? There is no way I suppose

This would be a compile-time error, since isReadable() is abstract in
Stream.

This is really bad :) Then actually your statics will be usable only
when you know exact type you want to work with.

And with generics and with dynamic loading.
 
A

Arved Sandstrom

Tom Anderson wrote:
[ SNIP ]
Now, i should say that that is some fairly bonkers generics (in fact, i
think i can now claim Double Wizard status at generics). It took me a
good while to get the types straight, and even now, the declarations are
of a mind-searing eldritch uncanniness verging on the Lovecraftian.
[ SNIP ]

I'll have to use that theme at a code review:

"This tenebrous source, wrought of a minion of Azathoth, must be
consigned to the subterranean depths ere this codebase suffers the fate
of all software that embraces the ultimate mindless chaos."

AHS
 
T

Tomas Mikula

Now I present two examples where it would be useful.

(1) Eliminate or reduce the use of reflection in serialization
frameworks.

This example isn't actually about your proposal, it's about ...
a new magic class Implementation<T>

... so i'm going to ignore it.
(2) The second use case is with generics, but would require reified
generics (which I hope will appear in some future version of Java).

Suppose you have an abstract class Vector which represents a vector in
a vector space (don't confuse with java.util.Vector) and a few
implementations, like Vector2D and Vector3D. [...] Now let's have a
generic class that will use vectors and do operations on them, but
doesn't really care about their actual dimension. So it will work with
abstract type Vector. But for some operations it may be necessary to
obtain the zero vector, without explicitely knowing the actual type of
vector.

This is a good use case. But i suspect it can be done with java as it
stands now - rather than reified generics, you factor out a Type Object,
as the patternists call it. Vectors can tell you their type object, and
the type object can give you a zero.

Like this, for instance:

http://urchin.earth.li/~twic/Code/MutuallyRecursiveGenerics/Vector.java

The VectorKind should also have two type parameters to get rid of
compiler warnings and to map Vectors to VectorKinds one-to-one:

abstract class
VectorKind<V extends Vector<V,K>, K extends VectorKind<V,K>>

Anyway, this is not of any help for me, because you are obtaining the
VectorKind instance from an instance of Vector. If there is always an
instance of Vector at hand, I can obtain the zero directly from that
instance (just move the abstract zero() method you declared in VectorKind
to Vector). The problem is that there is not always an instance at hand
and it is cumbersome to artificially pass one. The result is that the
readability of code suffers a lot, because it contains the workarounds,
not the actual work.
 
T

Tom Anderson

The VectorKind should also have two type parameters to get rid of
compiler warnings and to map Vectors to VectorKinds one-to-one:

abstract class
VectorKind<V extends Vector<V,K>, K extends VectorKind<V,K>>

It compiled without warnings for me - but then i'm on 1.5.
Anyway, this is not of any help for me, because you are obtaining the
VectorKind instance from an instance of Vector. If there is always an
instance of Vector at hand, I can obtain the zero directly from that
instance (just move the abstract zero() method you declared in
VectorKind to Vector). The problem is that there is not always an
instance at hand and it is cumbersome to artificially pass one.

What are you planning to do with this zero if you don't have any Vector
instances? I don't really buy your scenario.

tom
 
M

Marcin Rzeźnicki

No. Notice how add() is declared in Vector:
public V add(V v);
It works on type V.
When Vector2D is declared as
Vector2D extends Vector<Vector2D>,
Vector2D is substituted for V. So Vector2D's add() method is only
required to work on Vector2D instances. If Vector2D was declared as
Vector2D<V extends Vector<V>> extends Vector<V>,
then Vector2D would have to implement the add() method that takes any
subclass of Vector and returns the same subclass of Vector as it takes.

Sorry, I did not notice - compiler probably is bound to generate
bridge method which makes cast to Vector2D
I'm not sure if I understand, but in the implementation of Vector2D V is
bound to Vector2D at compile time.

But I am free to pass an instance of any conforming type.
Right now I can't think of any problems different from those with non-
static methods.

Except that super calls are dispatched by VM with no help needed from
a programmer.
Well, if you want to extend the behavior of a non-static method, you
still have to call the inherited method by hand (super.someMethod()) and
then do your specific work. This is no different from my example. The
only real disadvantage is when you want to inherit the method as is. Yes,
this is not possible with my proposal and you have to call the
superclass's method by hand. Though my proposal was targeted at uses
where you want to provide own implementation in each class. But I'm
finally getting what you are trying to say - that this feature might
encourage design that will later turn out as wrong. Yes, there might be
this danger, as is with many other features.

Right, but the difference is that super calls are not subject to
'human' errors (what happens if inheritance chain has been updated?
you have to manually review all subclasses and repair static calls)
or omit it so then you impose different context. Namely, pretend to
be able to read remote files while you are not. And one more
question:
//client code
Stream s = new AudioVideStream(..);
read10Bytes(s);
public byte[] read10Bytes(Stream s) { if (!Stream.isReadable(file))
//how would you dispatch it? There is no way I suppose
}
This would be a compile-time error, since isReadable() is abstract in
Stream.
This is really bad :) Then actually your statics will be usable only
when you know exact type you want to work with.

And with generics and with dynamic loading.

Still, you have to redefine static method so that it is _usable_ for
every type, but _used_ only when exact type is of special interest
which encourages too strict typing. Ok, probably now I understand
fully your concept. I'd uphold my opinion that this is not so good.
Here is a quick rundown why I think so:
1. Problem it solves can be solved in other ways, without any need for
special syntax/semantics/language or VM changes (like Vector)
2. It is not clear how it would/should behave even for problems it is
supposed to solve
(code: public <T extends Foo> void doSth(T t) { T.staticFromFoo(); }
public class Bar extends Foo { public static void staticFromFoo()
{...};}
what should it bind to? If Foo, what if it is passed a Bar instance in
runtime?)
3. It encourages bad code smell, that is: coding with the most
specific type instead of coding with interfaces
4. It solves relatively infrequent problems
5. It is error prone - developers will have to study all subclasses to
spot what should be changed after any superclass has changed
6. It makes developers implement this static heritage over and over,
even when it is not needed

Please clarify if I am wrong somewhere.
 
D

Daniel Pitts

Tomas said:
Tomas said:
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.
 
T

Tomas Mikula

It compiled without warnings for me - but then i'm on 1.5.

I haven't tried to compile it, but I suppose that the compiler should
issue a warning on line
What are you planning to do with this zero if you don't have any Vector
instances? I don't really buy your scenario.

Consider you want to implement a method that takes a collection of
vectors and returns their sum. Simple, eh? If I can call static methods
on type parameters, it will look like this:

public V sum(Collection<V> coll){
V s = V.zero();
for(V v: coll)
s = s.add(v);
return s;
}

However, we cannot call V.zero(). What will you return if coll is an
empty collection?
 
M

Marcin Rzeźnicki

Consider you want to implement a method that takes a collection of
vectors and returns their sum. Simple, eh? If I can call static methods
on type parameters, it will look like this:

public V sum(Collection<V> coll){
    V s = V.zero();
    for(V v: coll)
        s = s.add(v);
    return s;

}

However, we cannot call V.zero(). What will you return if coll is an
empty collection?

But what is so wrong with passing neutral element to the method and
implement it like foldl? For me it is quite natural
 
T

Tomas Mikula

Sorry, I did not notice - compiler probably is bound to generate bridge
method which makes cast to Vector2D

But I am free to pass an instance of any conforming type.

I don't think so. At least not without the compiler warning about
unchecked casting. If you have
Vector2D v;
you can only pass Vector2D instances to v.add(...). If you have
V v;
where V is actually Vector2D, you can only pass V instances to
v.add(...). But V is actually Vector2D, so it is OK.
Except that super calls are dispatched by VM with no help needed from a
programmer.

The thing is that prohibiting inheritance is a feature here, not a
drawback. This is because inherited behavior is most likely to be wrong.
(as with Vector.zero() or Serializable.readObject() (if readObject was a
static method returning the read object)). If this is not the case, then
it would probably not be the best choice to use this feature.
Right, but the difference is that super calls are not subject to 'human'
errors (what happens if inheritance chain has been updated? you have to
manually review all subclasses and repair static calls)

This is not a new problem. You have the same problem with current static
methods, if you call a static method of a superclass. It might be useful
to have some static analog of the 'super.instanceMethod()' construct,
regardless of my proposal.
or omit it so then you impose different context. Namely, pretend
to be able to read remote files while you are not. And one more
question:
//client code
Stream s = new AudioVideStream(..);
read10Bytes(s);
public byte[] read10Bytes(Stream s) { if
(!Stream.isReadable(file)) //how would you dispatch it? There is
no way I suppose

This would be a compile-time error, since isReadable() is abstract
in Stream.
This is really bad :) Then actually your statics will be usable only
when you know exact type you want to work with.

And with generics and with dynamic loading.

Still, you have to redefine static method so that it is _usable_ for
every type, but _used_ only when exact type is of special interest which
encourages too strict typing.

Again not sure what exactly you meant. In the example of AudioVideoCodec
I provided, the isReadable() method was only required to work with
AudioFiles.
Ok, probably now I understand fully your
concept. I'd uphold my opinion that this is not so good. Here is a quick
rundown why I think so: 1. Problem it solves can be solved in other
ways, without any need for special syntax/semantics/language or VM
changes (like Vector)

Each problem can be solved in other ways. You could argue that we don't
need generics, because every problem can be solved without them. The
question is how concise and readable the solution is. Unnatural hacks are
IMO very bad for code readability.
2. It is not clear how it would/should behave even
for problems it is supposed to solve
(code: public <T extends Foo> void doSth(T t) { T.staticFromFoo(); }
public class Bar extends Foo { public static void staticFromFoo()
{...};}
what should it bind to? If Foo, what if it is passed a Bar instance in
runtime?)

It should bind to whatever type T represents. That is why reified
generics are necessary. The bytecode of doSth() would contain the
information that the staticFromFoo() method of T is called, where T will
be specified at runtime (though I suspect that this could be optimized at
link-time).
3. It encourages bad code smell, that is: coding with the most specific
type instead of coding with interfaces

How? Did we have an example of this? If yes, I probably missed it.
4. It solves relatively infrequent problems

The problem with serialization frameworks is infrequent. I suspect that
the other problem with generics may be quite frequent.
5. It is error prone - developers will have to study
all subclasses to spot what should be changed after any superclass has
changed

I don't see any special relation of this problem to the proposed feature.
It is always bad if you depend on the implementation of the superclass
rather than on the interface only. This feature does not encourage you in
any way to depend on the superclass. If you are referring to the problem
of calling superclass methods on superclass's class literal
(MySuperClass.staticMethod()), I already argued that this is not a new
problem.
6. It makes developers implement this static heritage over and
over, even when it is not needed

It is designed for cases when it _is_ needed. I admit that someone could
be tempted to use it inappropriately. But almost anything can be misused.
 
T

Tomas Mikula

But what is so wrong with passing neutral element to the method and
implement it like foldl? For me it is quite natural

Isn't so bad, but not quite natural for me (ok, this is subjective). I
want a method that takes a collection and returns its sum. Instead, I
will have a method that takes a collection and an element and returns
that element plus the sum of the collection. If I was reading this code
after someone else, I would wonder why they have written it like this,
because I would not see the problem at the first sight.

What if the method that calls sum() doesn't have an instance at hand
either? Then I have to propagate this instance-passing up the call
hierarchy.
 
T

Tomas Mikula

Tomas said:
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();
 
M

Marcin Rzeźnicki

I don't think so. At least not without the compiler warning about
unchecked casting. If you have
Vector2D v;
you can only pass Vector2D instances to v.add(...). If you have
V v;
where V is actually Vector2D, you can only pass V instances to
v.add(...). But V is actually Vector2D, so it is OK.

OK, let's discuss this below when we are talking about reification
The thing is that prohibiting inheritance is a feature here, not a
drawback. This is because inherited behavior is most likely to be wrong.
(as with Vector.zero() or Serializable.readObject() (if readObject was a
static method returning the read object)). If this is not the case, then
it would probably not be the best choice to use this feature.

But still we have to dispatch correctly, that's the biggest problem in
my eyes with this feature ,regardless of whether we restrict
inheritance or not.
This is not a new problem. You have the same problem with current static
methods, if you call a static method of a superclass. It might be useful
to have some static analog of the 'super.instanceMethod()' construct,
regardless of my proposal.

OK, agreed (but somehow I don't feel it still, only I do not have
counter arguments :) )
Again not sure what exactly you meant. In the example of AudioVideoCodec
I provided, the isReadable() method was only required to work with
AudioFiles.

Right, but is there a way to know it at runtime? Method takes
Each problem can be solved in other ways. You could argue that we don't
need generics, because every problem can be solved without them. The
question is how concise and readable the solution is. Unnatural hacks are
IMO very bad for code readability.

As with the sum example, I do not feel it is unnatural. But that is
obviously matter of taste.
It should bind to whatever type T represents. That is why reified
generics are necessary. The bytecode of doSth() would contain the
information that the staticFromFoo() method of T is called, where T will
be specified at runtime (though I suspect that this could be optimized at
link-time).

You need more than reification. As far as we are concerned about
bytecode, there is currently no way to express what you said. Probably
you need modified version of invokestatic which takes class as an
operand (currently it is constant from CP)
How? Did we have an example of this? If yes, I probably missed it.

Well, I can tell you when you answer my question about how
AudioVideoStream statics can be used (or called by some dispatch
mechanism) in context where more generic Stream is used.
The problem with serialization frameworks is infrequent. I suspect that
the other problem with generics may be quite frequent.

But solvable, it is just matter of how unnatural we think it is.
I don't see any special relation of this problem to the proposed feature.
It is always bad if you depend on the implementation of the superclass
rather than on the interface only. This feature does not encourage you in
any way to depend on the superclass. If you are referring to the problem
of calling superclass methods on superclass's class literal
(MySuperClass.staticMethod()), I already argued that this is not a new
problem.

Yes, that's what I was referring to. So we can skip this point.
It is designed for cases when it _is_ needed. I admit that someone could
be tempted to use it inappropriately. But almost anything can be misused.

Right, ok, agreed.
So, everything boils down to dispatching, right? Do you have any
ideas?
What do you think about interface methods in .NET?
 
T

Tomas Mikula

Still, you have to redefine static method so that it is _usable_ for
Right, but is there a way to know it at runtime?

I think there isn't. But it is not a problem if you don't pass a raw
type. If you pass a raw type, you get a compiler warning and probably get
a ClassCastException(?) at runtime.
Method takes
Stream<File> parameter and a file and wants to check whether isReadable
(file) holds. I wonder, maybe it is all about how to dispatch.

If a method takes Stream<File>, then it will not accept
Stream<AudioFile>. Stream<AudioFile> is not a subclass of Stream<File>.
If it took Stream<? extends File>, then it would accept Stream<AudioFile>
s. But then the compiler won't allow you to call s.isReadable(f) in this
method (whatever type f has; provided that isReadable is declared to work
on the type parameter F). We can only pass a File to AudioFile.isReadable
() if isReadable was declared to accept File (no generics involved). Then
the implementation would have to check that the file is actually an
AudioFile. But we are already far away from the concept of abstract
static methods.
As with the sum example, I do not feel it is unnatural. But that is
obviously matter of taste.

If I find a bigger example where it won't be just the matter of taste, I
will post it here.
You need more than reification. As far as we are concerned about
bytecode, there is currently no way to express what you said.

I know nothing about bytecode. I just supposed that when there are
reified generics, there will be enough information to dispatch it
correctly.
Probably
you need modified version of invokestatic which takes class as an
operand (currently it is constant from CP)

Yes. And I suspected that if the generic class is used with just a few
different parameters at runtime, one specialized copy of the generic
class, in which static methods would be invoked as usual, could be made
for each type parameter. A similar process is called template
instantiation in C++, but it is done as code generation at compile time.
Well, I can tell you when you answer my question about how
AudioVideoStream statics can be used (or called by some dispatch
mechanism) in context where more generic Stream is used.

But solvable, it is just matter of how unnatural we think it is.

Yes. I will have to come up with a more elaborate example :)
Yes, that's what I was referring to. So we can skip this point.


Right, ok, agreed.
So, everything boils down to dispatching, right? Do you have any ideas?
What do you think about interface methods in .NET?

I haven't done any coding in .NET, so I can't tell :(
 
A

Andreas Leitgeb

Eric Sosman said:
I'm not sure why the second sentence follows from the first

The Framework designed for dynamically engaging Entertainers just hasn't
the slightest idea, that some of the Entertainers require special cons-
tructors, and even if it enumerated the constructors, it wouldn't have
any idea what a Joke is in the first place.
And if you know enough to be able to supply a Joke to a post-construction
setter, why couldn't you just as well hand it to a Constructor's
newInstance() method?

The post-construction setter (or rather the property being set) has a name,
for which a Joke(actually String) can be configured in some engaging contract
(xml). Otoh., the arguments to a constructor are nameless in bytecode.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top