Generic Blues


S

Stefan Ram

This is too messed up, nobody can help me:

[javac] de\dclj\ram\type\tuple\ComparableLocatableTuple0.java:36:
method addrac in interface Placeable<T#2> cannot be applied to given types
[javac] components[ position ].addrac( this, position ); }
[javac] ^
[javac] required: Comparable<T#1>,int
[javac] found: ComparableLocatableTuple0<T#1>,int
[javac] where T#1,T#2 are type-variables:
[javac] T#1 extends Comparable<T#1>,Locatable<T#1> declared in class ComparableLocatableTuple0
[javac] T#2 extends Object declared in interface Placeable

I want this line to compile. If you somehow already know,
what I need to do now, please let me know. Otherwise, I try
to provide more details:

The type of »components[ position ]« is T (in this scope),
which is given as:

< T extends java.lang.Comparable< T >& de.dclj.ram.system.locator.Locatable< T >>

The type of »this« is ComparableLocatableTuple0:

package de.dclj.ram.type.tuple;
public class ComparableLocatableTuple0
< T extends java.lang.Comparable< T >& de.dclj.ram.system.locator.Locatable< T >>
implements de.dclj.ram.type.tuple.ComparableLocatableTuple< T >
{ ... }

More about some types used or mentioned:

package de.dclj.ram.system.locator;
public interface Locatable< T >
extends
de.dclj.ram.system.locator.Findable,
de.dclj.ram.system.locator.Placeable< T >{}

package de.dclj.ram.type.tuple;
public interface ComparableLocatableTuple< T >
extends de.dclj.ram.type.tuple.ComparableTuple< T >,
de.dclj.ram.system.locator.Locatable< T >{}

package de.dclj.ram.type.tuple;
public interface ComparableTuple< T extends java.lang.Comparable< T >>
extends java.lang.Comparable<de.dclj.ram.type.tuple.ComparableTuple< T >>,
de.dclj.ram.type.tuple.Tuple

package de.dclj.ram.system.locator;
public interface Placeable< T >
{ void addrac( java.lang.Comparable< T >container, int position ); }

(Please let me know, what else you need to do.
Should I try to extract a SSCCE from my project?)

So, »this« is of a subtype of

java.lang.Comparable<de.dclj.ram.type.tuple.ComparableTuple< T >>

and the compiler wants

Comparable<T#1>

? The compiler cannot unify the type »T#1« with
de.dclj.ram.type.tuple.ComparableTuple< T >?
Possibly, due to different bounds for these T?

But the type of »this« actually extends

de.dclj.ram.type.tuple.ComparableTuple< T >

! (Albeit possibly with »T« being in another scope and
thus having another meaning.)

I feel as if I am not smart enough for this stuff. Or I was
too much in a rush to add type parameters everywhere, so
that I did not properly document what my type parameters
actually are intended to convey.

The compiler is Java 1.7, version 7.0.0.107.

<javac
source='1.7'
target='1.7'
deprecation='on'
debug='on'
optimize='off'<compilerarg line='-Xlint '/>
<compilerarg line='-Xlint:-unchecked '/>
<compilerarg line='-Xlint:-serial '/>
<compilerarg line='-Xmaxerrs 1 -Xmaxwarns 2147483647'/>
</javac>
 
Ad

Advertisements

S

Stefan Ram

Maybe, there was too much information in my recent post.

I have tried to prepare this boiled-down version:

I have the following conflict:

required: Comparable<T>
found: ComparableLocatableTuple<T>

where

ComparableLocatableTuple< T > extends Comparable< ComparableTuple< T >>

. So it seems that the compiler needs (1)

Comparable< T >

but gets (2)

Comparable< ComparableTuple< T >>

. And I thought that it might be able to unify the »T« of (1)
with the »ComparableTuple< T >« of (2). But to do this, it needs
to know that the T of (1) indeed is a ComparableTuple< T >,
which is what I need to check now.
 
A

Andreas Leitgeb

Stefan Ram said:
I have the following conflict:
required: Comparable<T>
found: ComparableLocatableTuple<T>
ComparableLocatableTuple< T > extends Comparable< ComparableTuple< T >>

In absence of a spec (maybe it was in the original thread that I didn't
see) I don't know what role ComparableTuple is to play, as it is not
a super-interface of ComparableLocatableTuple. Maybe it is just an
inadvertent leftover from simplification...

This may be one of those situations where a bit more of the code
would be helpful (for you, as you would get better answers then).
An SSCCE where the "C" doesn't imply it to be *successfully*
compileable. If the compiler reproduces your error, that's fine.
. And I thought that it might be able to unify the »T« of (1)
with the »ComparableTuple< T >« of (2). But to do this, it needs
to know that the T of (1) indeed is a ComparableTuple< T >,
which is what I need to check now.

Perhaps you just need some <? extends ...>s, but it's hard to tell.
 
S

Stefan Ram

Andreas Leitgeb said:
Perhaps you just need some <? extends ...>s, but it's hard to tell.

Possibly.

In some low-level class, I happen to extend
java.lang.Comparable<T>, which happens to use T in
compareTo(T o).

Now, I started to parameterize my low-level class with this
»T«, thus passing it on to higher-level classes, which now
also are parameterized with T, even though soon the meaning
of this »T« is lost as it is passed upwards from class to
class.

I now think that instead at some point, I should use »?«
instead of »T«, to cut off this chain from class to class.

Possibly, I might lose some static type safety this way, but
I might simplify the code to the point where I can
understand it again.
 
L

Lew

Possibly.

In some low-level class, I happen to extend
java.lang.Comparable<T>, which happens to use T in
compareTo(T o).

Now, I started to parameterize my low-level class with this
»T«, thus passing it on to higher-level classes, which now
also are parameterized with T, even though soon the meaning
of this »T« is lost as it is passed upwards from class to
class.

I now think that instead at some point, I should use »?«
instead of »T«, to cut off this chain from class to class.

Possibly, I might lose some static type safety this way, but
I might simplify the code to the point where I can
understand it again.

I can usually puzzle out generics issues but I need an SSCCE.
 
Ad

Advertisements

D

Daniele Futtorovic

I can usually puzzle out generics issues but I need an SSCCE.

Ditto, although that may be due to me being drunk.
If you could trim it down to a couple of interfaces and a main method,
that'd be lovely.
OTOH, that'd probably give you the anwser already.
 
D

Daniel Pitts

Maybe, there was too much information in my recent post.

I have tried to prepare this boiled-down version:

I have the following conflict:

required: Comparable<T>
found: ComparableLocatableTuple<T>

where

ComparableLocatableTuple< T> extends Comparable< ComparableTuple< T>>

. So it seems that the compiler needs (1)

Comparable< T>

but gets (2)

Comparable< ComparableTuple< T>>

. And I thought that it might be able to unify the »T« of (1)
with the »ComparableTuple< T>« of (2). But to do this, it needs
to know that the T of (1) indeed is a ComparableTuple< T>,
which is what I need to check now.

Perhaps you need

public interface ComparableLocalTuple<T extends ComparableLocalTuple<T>>
extends Comparble<T>
 
S

Stefan Ram

Daniel Pitts said:
Perhaps you need
public interface ComparableLocalTuple<T extends ComparableLocalTuple<T>>

That might well be possible. Now I already have made a change in another
direction, but I will keep this in mind!
 
S

Stefan Ram

This is too messed up, nobody can help me:

Months ago, I added the 1.7 compiler option »-Xlint «
and then forgot about it.

Recently, I wanted to get my project to compile
(without warnings, that is). I got loads of warnings
»warning: [rawtypes] found raw type: ...« and felt
obliged to deal with all of them in a hurry, adding
type parameters everywhere, often not really thinking
carefully about the meaning of each type parameter.

The solution is to remove »-Xlint« for now. I can enable it
later, when I have more time to deal with those warnings.
 
L

Lew

Stefan said:
Months ago, I added the 1.7 compiler option »-Xlint «
and then forgot about it.

Recently, I wanted to get my project to compile
(without warnings, that is). I got loads of warnings
»warning: [rawtypes] found raw type: ...« and felt
obliged to deal with all of them in a hurry, adding
type parameters everywhere, often not really thinking
carefully about the meaning of each type parameter.

The solution is to remove »-Xlint« for now. I can enable it
later, when I have more time to deal with those warnings.

That's good advice. Generics resolve after an investment in type analysis and
design. For workaday programming and getting features out the door, less
type-safe ways get you going. You can do it incrementally, and keep it simple
by not asserting too much.
 
Ad

Advertisements

D

Daniele Futtorovic

Stefan said:
Months ago, I added the 1.7 compiler option »-Xlint « and then
forgot about it.

Recently, I wanted to get my project to compile (without warnings,
that is). I got loads of warnings »warning: [rawtypes] found raw
type: ...« and felt obliged to deal with all of them in a hurry,
adding type parameters everywhere, often not really thinking
carefully about the meaning of each type parameter.

The solution is to remove »-Xlint« for now. I can enable it later,
when I have more time to deal with those warnings.

That's good advice. Generics resolve after an investment in type
analysis and design. For workaday programming and getting features
out the door, less type-safe ways get you going. You can do it
incrementally, and keep it simple by not asserting too much.

Later refactoring to add generics will take you at least twice as long
as including them while you write the thing.

Generics, if you're going to use them, ought to be part of your
modelisation. I can see no rationale then for not including them as
early as in the first draft.
 
Ad

Advertisements

L

Lew

Stefan said:
Months ago, I added the 1.7 compiler option »-Xlint « and then
forgot about it.
Recently, I wanted to get my project to compile (without warnings,
that is). I got loads of warnings »warning: [rawtypes] found raw
type: ...« and felt obliged to deal with all of them in a hurry,
adding type parameters everywhere, often not really thinking
carefully about the meaning of each type parameter.
The solution is to remove »-Xlint« for now. I can enable it later,
when I have more time to deal with those warnings.
That's good advice. Generics resolve after an investment in type
analysis and design. For workaday programming and getting features
out the door, less type-safe ways get you going. You can do it
incrementally, and keep it simple by not asserting too much.

Later refactoring to add generics will take you at least twice as long
as including them while you write the thing.

That's a refutation of a practice that I do not endorse in the first
place.
Generics, if you're going to use them, ought to be part of your
modelisation. I can see no rationale then for not including them as
early as in the first draft.

Let me be clear. I do not recommend adding generics after the fact.

I did recommend a stepwise approach to the complexity of the generic
assertions. Normally the simple assertions get you as far as you need
to go and you can stop there. It will not usually be necessary to get
fancy.

However, you have made me stop and think, and I retract the claim I
actually did make. Do the generics analysis as far as you need to up
front. It's still true that you should usually stick to simple
assertions, but I no longer suggest that you should necessarily go
beyond that in later iterations.

It remains true that there is a fair investment to get your generics
assertions correct. I'm just saying now that you should spend that
effort at the beginning.

Thanks for the feedback, Daniele.
 

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

Top