I don't think what you want to express can be expressed in Java
because Iterable is invariant - an Iterable<Child> isn't a subtype of
Iterable<Parent>.  Nor can you write "interface Parent extends
Iterable<? extends Parent>"

It can be expressed in Scala, but not with Java's standard Iterator/
Iterable because they aren't covariant.  Scala has a rough equivalent
in its library that is covariant so this works fine
  trait Parent extends Iterable[Parent]
  trait Child extends Parent with Iterable[Child]

It would work in a hypothetical future version of Java with C# 4 style
variance annotations

  interface Iterator<out T> {
     public boolean hasNext();
     publict T next():
  }

  interface Iterable<out T> {
     public Iterator<T> iterator();
  }

  interface Parent implements Iterable<Parent>
  interface Child extends Parent, Iterable<Child>

This also shows Reinier a use case where immutability isn't necessary
for covariant type parameters to be useful (an Iterator is not
immutable).

And to quickly head Reinier off at the pass - it would be trivial to
write a wrapper to convert this Iterable/Iterator pair into the JCL
pair so that in order to work with other bits of Java's standard
library or Java's extended for loop.  So yes, even if the JCL can't be
"fixed", it's a useful extension to the language.

On Jan 29, 5:44 am, Christian Catchpole <[email protected]>
wrote:
> Thanks Reinier.  The problem with this is, it requires the calling /
> working code know the Impl.  And the code which operates on Parents
> should also operate on Children.  So I never really wanted generic
> defs on the left hand side.
>
> These are the first interface definitions I wrote.. Parent will work,
> but the Child cant extend this way..
> So I'm looking for something that's functionally identical to this...
>
> interface Parent extends Iterable<Parent> { }
>
> interface Child extends Parent, Iterable<Child> { }
>
> All I really want to do is extend the Iterable type.. The fact that
> it's it self is irrelevant I guess.
>
> On Jan 29, 11:27 pm, Reinier Zwitserloot <[email protected]> wrote:
>
> > Christian: Are you kidding? Of course this code won't work. It's
> > missing most of the generics! You missed 12 places where you need
> > generics.
>
> > I can't fix your code because the snippet just doesn't give any hint
> > as to what its supposed to do.
>
> > You need generics parameters almost everywhere with the way you've set
> > it up - you need them after:
>
> > class ParentImpl<HERE>
> > class ChildImpl<HERE>
>
> > Parent<HERE> parent = new ParentImpl<HERE>();
> > for ( Parent<HERE> p2 : parent)
>
> > for (Parent <HERE> p3 : p2)
>
> > Parent<HERE> p = parent.iterator().next();
>
> > Child<HERE> child = new ChildImpl<HERE>();
> > for (Child<HERE> c2 : child)
> > for (Child<HERE> c3 : c2)
>
> > Child<HERE> c = child.iterator.next();
>
> > Possibly this is what you meant? The code below compiles without
> > errors or warnings.
>
> > import java.util.*;
>
> > interface Parent<T extends Parent<T>> extends Iterable<T> {
>
> > }
>
> > interface Child<T extends Child<T>> extends Parent<T> {
>
> > }
>
> > class ParentImpl implements Parent<ParentImpl> {
> >     public Iterator<ParentImpl> iterator() {
> >         List<ParentImpl> list = new ArrayList<ParentImpl>();
> >         list.add(new ParentImpl());
> >         return list.iterator();
> >     }
>
> > }
>
> > class ChildImpl implements Child<ChildImpl> {
> >     public Iterator<ChildImpl> iterator() {
> >         List<ChildImpl> list = new ArrayList<ChildImpl>();
> >         list.add(new ChildImpl());
> >         return list.iterator();
> >     }
>
> > }
>
> > public class Tester {
> >     public static void main(String[] args) {
> >         Parent<ParentImpl> parent = new ParentImpl();
> >         for (Parent<ParentImpl> p2 : parent) {
> >             System.out.println("> " + p2);
> >             for (Parent<ParentImpl> p3 : p2) {
> >                 System.out.println(">> " + p3);
> >             }
> >         }
> >         Parent<ParentImpl> p = parent.iterator().next();
> >         Child<ChildImpl> child = new ChildImpl();
> >         for (Child<ChildImpl> c2 : child) {
> >             System.out.println("> " + c2);
> >             for (Child<ChildImpl> c3 : c2) {
> >                 System.out.println(">> " + c3);
> >             }
> >         }
> >         Child<ChildImpl> c = child.iterator().next();
> >     }
>
> > }
>
> > On Jan 29, 7:11 am, Christian Catchpole <[email protected]>
> > wrote:
>
> > > My brain hurts.  I love Iterable,  In this example, I'm trying to
> > > define a Parent interface which iterates a sub-list of it's self
> > > type.  But I want to be able to inherit to Child and change the
> > > Iterator to Child.  Which in theory should work because Child is a sub
> > > class of Parent.  I would expect any code which can operate on Child,
> > > be able to operate on Parent.
>
> > > My IDE thinks the "for (Parent p2 : parent)" loops are valid, but they
> > > don't compile.  I think the problem is I'm not actually implementing
> > > Parent with any Generic type info.. but I can't find any type
> > > combinations which work.  And I'd prefer to not have the implementor
> > > need to pass the type info.
>
> > > interface Parent<T extends Parent<T>> extends Iterable<T> {
>
> > > }
>
> > > interface Child<T extends Child<T>> extends Parent<T> {
>
> > > }
>
> > > class ParentImpl implements Parent {
> > >     public Iterator<Parent> iterator() {
> > >         List<Parent> list = new ArrayList<Parent>();
> > >         list.add(new ParentImpl());
> > >         return list.iterator();
> > >     }
>
> > > }
>
> > > class ChildImpl implements Child {
> > >     public Iterator<Child> iterator() {
> > >         List<Child> list = new ArrayList<Child>();
> > >         list.add(new ChildImpl());
> > >         return list.iterator();
> > >     }
>
> > > }
>
> > > public class Tester {
> > >     public static void main(String[] args) {
> > >         Parent parent = new ParentImpl();
> > >         for (Parent p2 : parent) {
> > >             System.out.println("> " + p2);
> > >             for (Parent p3 : p2) {
> > >                 System.out.println(">> " + p3);
> > >             }
> > >         }
>
> > >         Parent p = parent.iterator().next();
>
> > >         Child child = new ChildImpl();
> > >         for (Child c2 : child) {
> > >             System.out.println("> " + c2);
> > >             for (Child c3 : c2) {
> > >                 System.out.println(">> " + c3);
> > >             }
> > >         }
>
> > >         Child c = child.iterator().next();
> > >     }
>
> > > }
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to