Generifying outer.this

S

Safalra

I'm currently in the process of 'generifying' my old functional list
classes before putting them on my website (in case someone wants to use
inefficient functional-style lists instead of efficient
imperative-style lists...). Everything has worked well, except for one
line. The 'truncate' method of my LazyList class creates an Iterator
using an inner class. The inner class accesses its outer class instance
through LazyList.this (in order to take the 'tail' repeatedly), but the
compiler gives this bizarre error message:

safalra\functional\LazyList.java:213: incompatible types
found : safalra.functional.LazyList<T>
required: safalra.functional.LazyList<T>

If I change the inner class variable in which I'm storing the remainder
of the list (which is initially the outer class instance) to type
LazyList (rather than LazyList<T>) the compiler doesn't object to the
assignment, but then of course the 'tail' is no longer of type
LazyList<T>.

For the moment I'm working around this by passing 'this' as a parameter
to the constructor of the inner class, but this is distinctly
inelegant. Does anybody know what is causing this problem?
 
O

Oliver Wong

Safalra said:
I'm currently in the process of 'generifying' my old functional list
classes before putting them on my website (in case someone wants to use
inefficient functional-style lists instead of efficient
imperative-style lists...). Everything has worked well, except for one
line. The 'truncate' method of my LazyList class creates an Iterator
using an inner class. The inner class accesses its outer class instance
through LazyList.this (in order to take the 'tail' repeatedly), but the
compiler gives this bizarre error message:

safalra\functional\LazyList.java:213: incompatible types
found : safalra.functional.LazyList<T>
required: safalra.functional.LazyList<T>

If I change the inner class variable in which I'm storing the remainder
of the list (which is initially the outer class instance) to type
LazyList (rather than LazyList<T>) the compiler doesn't object to the
assignment, but then of course the 'tail' is no longer of type
LazyList<T>.

Post an SSCCE (http://www.physci.org/codes/sscce.jsp).

- Oliver
 
S

Safalra

Oliver said:
Safalra said:
[snip unclear explanation]

Post an SSCCE (http://www.physci.org/codes/sscce.jsp).

A useful link - I must remember it for use in the HTML newsgroups. (And
remember not to be so hypocritical...)

Right, here's a minimal equivalent of the code (I think), with all the
references to external classes, methods, and constructors removed:

public class LazyList<T>{
private class TruncatedIterator<T>{
//private LazyList list;
private LazyList<T> list;
public TruncatedIterator(LazyList<T> instance){
//list=instance;
list=LazyList.this;
}
}
}

(The 'instance' parameter isn't necessary unless you remove the // from
the line below.)

Which gives this error:

LazyList.java:8: incompatible types
found : LazyList<T>
required: LazyList<T>

If either of the commented-out lines are used instead of the lines
below, the error magically disappears. It's the fact the removing the
<T> (first commented-out line) works that makes me think this is some
generics-related foolishness.
 
S

Stefan Schulz

public class LazyList<T>{
private class TruncatedIterator<T>{
//private LazyList list;
private LazyList<T> list;
public TruncatedIterator(LazyList<T> instance){
//list=instance;
list=LazyList.this;
}
}
}

You declare a new type parameter (also named T) in the declaration of the
iterator class. Omit the new type parameter, and things should be just
peachy.
 
C

Chris Uppal

Safalra said:
public class LazyList<T>{
private class TruncatedIterator<T>{
[...]

LazyList.java:8: incompatible types
found : LazyList<T>
required: LazyList<T>

I believe that this is because you have supplied a generic parameter to
TruncatedIterator, which hides the outer parameter of the same name.
TruncatedIterator is -- by implication -- already parameterised on the <T> of
LazyList, so you don't need to repeat it.

If you remove the <T> from TruncatedIterator then I think it should work as you
wish.

public class LazyList<T>
{
private class TruncatedIterator
{
private LazyList<T> remainder;

public TruncatedIterator()
{
remainder = LazyList.this;
}
}
}

-- chris
 
S

Safalra

Chris said:
Safalra said:
public class LazyList<T>{
private class TruncatedIterator<T>{
[...]

LazyList.java:8: incompatible types
found : LazyList<T>
required: LazyList<T>

I believe that this is because you have supplied a generic parameter to
TruncatedIterator, which hides the outer parameter of the same name.
TruncatedIterator is -- by implication -- already parameterised on the <T> of
LazyList, so you don't need to repeat it.

Ah, of course! I believe this is the kind of thing my younger brother
would call a 'schoolboy error'. It does show a lack of usability in the
compiler however - I suspect many people would make this mistake when
learning generics, and the baffling error message doesn't help
diagnosis. Thanks for the assistance.
 
J

John C. Bollinger

Safalra said:
Chris said:
Safalra wrote:
[...]
I believe that this is because you have supplied a generic parameter to
TruncatedIterator, which hides the outer parameter of the same name.
TruncatedIterator is -- by implication -- already parameterised on the <T> of
LazyList, so you don't need to repeat it.


Ah, of course! I believe this is the kind of thing my younger brother
would call a 'schoolboy error'. It does show a lack of usability in the
compiler however - I suspect many people would make this mistake when
learning generics, and the baffling error message doesn't help
diagnosis. Thanks for the assistance.

Yes, I suspect that many people learning generics (and even some have
have a fairly good handle on them) do hit something like this. I have
done. I agree that the error message is a bit baffling, but once you
already know what it means it's quite clear in hindsight: either the two
"LazyList" types must be different or the two "T" types must be different.
 
R

Raymond DeCampo

John said:
Safalra said:
Chris said:
Safalra wrote:

[...]
LazyList.java:8: incompatible types
found : LazyList<T>
required: LazyList<T>


I believe that this is because you have supplied a generic parameter to
TruncatedIterator, which hides the outer parameter of the same name.
TruncatedIterator is -- by implication -- already parameterised on
the <T> of
LazyList, so you don't need to repeat it.



Ah, of course! I believe this is the kind of thing my younger brother
would call a 'schoolboy error'. It does show a lack of usability in the
compiler however - I suspect many people would make this mistake when
learning generics, and the baffling error message doesn't help
diagnosis. Thanks for the assistance.


Yes, I suspect that many people learning generics (and even some have
have a fairly good handle on them) do hit something like this. I have
done. I agree that the error message is a bit baffling, but once you
already know what it means it's quite clear in hindsight: either the two
"LazyList" types must be different or the two "T" types must be different.

"[O]nce you already know what it means it's quite clear" is not really
the standard that error messages, or any message really, should aim for.

Ray
 
J

John C. Bollinger

Raymond said:
"[O]nce you already know what it means it's quite clear" is not really
the standard that error messages, or any message really, should aim for.

No, it isn't. I never suggested that it was.
 
S

Safalra

Raymond said:
John said:
Safalra said:
Chris Uppal wrote:
Safalra wrote: [...]
LazyList.java:8: incompatible types
found : LazyList<T>
required: LazyList<T>

I believe that this is because you have supplied a generic parameter to
TruncatedIterator, which hides the outer parameter of the same name.
TruncatedIterator is -- by implication -- already parameterised on
the <T> of LazyList, so you don't need to repeat it.

Ah, of course! I believe this is the kind of thing my younger brother
would call a 'schoolboy error'. It does show a lack of usability in the
compiler however - I suspect many people would make this mistake when
learning generics, and the baffling error message doesn't help
diagnosis. Thanks for the assistance.

Yes, I suspect that many people learning generics (and even some have
have a fairly good handle on them) do hit something like this. I have
done. I agree that the error message is a bit baffling, but once you
already know what it means it's quite clear in hindsight: either the two
"LazyList" types must be different or the two "T" types must be different.

"[O]nce you already know what it means it's quite clear" is not really
the standard that error messages, or any message really, should aim for.

Surely it wouldn't be too difficult for the compiler to be changed to
instead give something like this:

LazyList.java:8: incompatible types
found : LazyList<T(1)>
required: LazyList<T(2)>

....where different types, T, with the same name visible to users are
numbered T(1), T(2), and so on.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top