You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@uima.apache.org by Marshall Schor <ms...@schor.com> on 2009/08/07 20:57:01 UTC

generics: getViewIterator

getViewIterator in CASImpl is written with the signature:
  Iterator<CAS> getViewIterator()

If you are working with things needing CASImpl objects, you would write:

  Iterator<CAS> s = aCas.getViewIterator();
  while (s.hasNext()) {
    CASImpl ci = (CASImpl) s.next();
      ... code using ci...
  }

If we changed the signature to:
  Iterator<T extends CAS> getViewIterator()
then you would write:
  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
support code, not here
  while (s.hasNext()) {
    CASImpl ci = s.next();  // works OK without casting
      ... code using ci...
  }

Would it be better to have that form of the signature? 
-Marshall


Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
On Aug 8, 2009, at 10:57 PM, Marshall Schor wrote:

> Jörn Kottmann wrote:
>>
>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>>
>>> getViewIterator in CASImpl is written with the signature:
>>> Iterator<CAS> getViewIterator()
>>>
>>> If you are working with things needing CASImpl objects, you would  
>>> write:
>>>
>>> Iterator<CAS> s = aCas.getViewIterator();
>>> while (s.hasNext()) {
>>>   CASImpl ci = (CASImpl) s.next();
>>>     ... code using ci...
>>> }
>>>
>>> If we changed the signature to:
>>> Iterator<T extends CAS> getViewIterator()
>>> then you would write:
>>> Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside  
>>> the
>>> support code, not here
>>> while (s.hasNext()) {
>>>   CASImpl ci = s.next();  // works OK without casting
>>>     ... code using ci...
>>> }
>>>
>>> Would it be better to have that form of the signature?
>>
>> +1, though did not know that its possible, we should check other
>> places too
>
> +1 to checking other places :-)
>
> The tutorial on generics by Gilad Bracha,
> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20  
> near
> the top says:
>
>> In general, if you have an API that only uses a type parameter T as  
>> an
>> argument, its
>> uses should take advantage of lower bounded wildcards (? super T).
>> Conversely, if
>> the API only returns T, you’ll give your clients more flexibility by
>> using upper bounded
>> wildcards (? extends T).
>
> There are many cases I think in our generification where the 2nd  
> part of
> this, returning XXX<? extends T> or a variant, is a better choice.

In the end we can do this generification for all methods which
return an object of a type which is declared by an UIMA interface,  
right ?

Jörn

Re: generics: getViewIterator

Posted by Thilo Goetz <tw...@gmx.de>.
Adam Lally wrote:
> On Sat, Aug 8, 2009 at 4:57 PM, Marshall Schor<ms...@schor.com> wrote:
>> Jörn Kottmann wrote:
>>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>>>
>>>> getViewIterator in CASImpl is written with the signature:
>>>>  Iterator<CAS> getViewIterator()
>>>>
>>>> If you are working with things needing CASImpl objects, you would write:
>>>>
>>>>  Iterator<CAS> s = aCas.getViewIterator();
>>>>  while (s.hasNext()) {
>>>>    CASImpl ci = (CASImpl) s.next();
>>>>      ... code using ci...
>>>>  }
>>>>
>>>> If we changed the signature to:
>>>>  Iterator<T extends CAS> getViewIterator()
>>>> then you would write:
>>>>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
>>>> support code, not here
>>>>  while (s.hasNext()) {
>>>>    CASImpl ci = s.next();  // works OK without casting
>>>>      ... code using ci...
>>>>  }
>>>>
>>>> Would it be better to have that form of the signature?
>>> +1, though did not know that its possible, we should check other
>>> places too
>> +1 to checking other places :-)
>>
>> The tutorial on generics by Gilad Bracha,
>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20 near
>> the top says:
>>
>>> In general, if you have an API that only uses a type parameter T as an
>>> argument, its
>>> uses should take advantage of lower bounded wildcards (? super T).
>>> Conversely, if
>>> the API only returns T, you’ll give your clients more flexibility by
>>> using upper bounded
>>> wildcards (? extends T).
>> There are many cases I think in our generification where the 2nd part of
>> this, returning XXX<? extends T> or a variant, is a better choice.
>>
> 
> I must say I don't understand why returning something like List<?
> extends CAS> is an improvement.  Is this supposed to mean that the
> client could specify ANY subtype of CAS and it's supposed to work?  So
> someone could write:
> class MyCas implements CAS {...}
> List<MyCas> result = aCAS.getViewIterator()
> 
> Which couldn't possibly work.  I guess it would compile but generate a
> ClassCastException at runtime.  Is that a good thing?
> 
> I found an expert with a differing point of view from your expert:
> http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU
> 
> "Keep bounded wildcards out of return values
> 
> It is sometimes tempting to use a bounded wildcard in the return type
> of a method. But this temptation is best avoided because returning
> bounded wildcards tends to "pollute" client code. If a method were to
> return a Box<? extends T>, then the type of the variable receiving the
> return value would have to be Box<? extends T>, which pushes the
> burden of dealing with bounded wildcards on your callers. Bounded
> wildcards work best when they are used in APIs, not in client code."
> 
>  -Adam

I agree with Adam and Jukka.  Even in our implementation code, it's
most of the time not a good idea to use CASImpl.  We shouldn't encourage
clients to do so.

--Thilo


Re: generics: getViewIterator

Posted by Adam Lally <al...@alum.rpi.edu>.
On Mon, Aug 10, 2009 at 9:49 AM, Jörn Kottmann<ko...@gmail.com> wrote:
>> Here's another (probably weak) use case for returning <T extends
>> AbstractCas> kinds of things:  If you have part of the code which
>> collects views and some of these views use one form of the AbstractCas
>> (e.g. CASImpl) and others use the JCas form, it would be nice to be able
>> to put these two uses into a collection (of AbstractCas) - which is the
>> kind of thing AbstractCas was trying to do, I believe.
>>
>
> I never really understood the reason why AbstractCas exists,
> it only has a release method, but CAS and JCas have many methods in
> common. Why are they not declared in AbstractCas ?
>
> The way its now AbstractCas is nearly useless expect
> for cas pooling or so.
>
> What was the reason to not move up the common methods
> when AbstractCas was introduced ?
>

We could move some things like getViewIterator up, but we should be
careful that anything we move up would be applicable to any future CAS
interface we might imagine, not just CAS and JCas.

  -Adam

Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
Marshall Schor wrote:
> Jörn Kottmann wrote:
>   
>>> Here's another (probably weak) use case for returning <T extends
>>> AbstractCas> kinds of things:  If you have part of the code which
>>> collects views and some of these views use one form of the AbstractCas
>>> (e.g. CASImpl) and others use the JCas form, it would be nice to be able
>>> to put these two uses into a collection (of AbstractCas) - which is the
>>> kind of thing AbstractCas was trying to do, I believe.
>>>   
>>>       
>> I never really understood the reason why AbstractCas exists,
>> it only has a release method, but CAS and JCas have many methods in
>> common. Why are they not declared in AbstractCas ?
>>
>> The way its now AbstractCas is nearly useless expect
>> for cas pooling or so.
>>
>> What was the reason to not move up the common methods
>> when AbstractCas was introduced ?
>>     
>
> Good question :-)  -- I wasn't involved with the design here, but I can
> think of 2 reasons (there may be others).  (1) API stability - not
> wanting to change existing APIs.  I haven't studied API evolution as
> much as I might, but I think this kind of change would cause a binary
> incompatibility.
>   
We can move up these methods. And yes its not binary compatible,
because it breaks all implementations of AbstractCas, but in our
case we could do it because the interface is not intended to be
implemented by clients. Anyway we should double check this.

> (2) Some methods are the same except that in the CAS they return things
> of type CAS, and in the JCas they return things of type JCas.  So some
> kind of overloading is possible if the arguments are CAS vs JCas, but is
> not possible if the returned types are CAS vs JCas.  In this case, the
> solution might be to return things of AbstractCas type.
>   
Lets take the case of getViewIterator:

AbstractCas:

<T extends AbstractCas> Iterator<T> getViewIterator() throws CASException

CAS:

<T extends CAS> Iterator<T> getViewIterator()


JCas:

<T extends JCas> Iterator<T> getViewIterator() throws CASException


I am not sure about the exception, but looks fine to me.

Jörn

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.
Jörn Kottmann wrote:
>
>> Here's another (probably weak) use case for returning <T extends
>> AbstractCas> kinds of things:  If you have part of the code which
>> collects views and some of these views use one form of the AbstractCas
>> (e.g. CASImpl) and others use the JCas form, it would be nice to be able
>> to put these two uses into a collection (of AbstractCas) - which is the
>> kind of thing AbstractCas was trying to do, I believe.
>>   
> I never really understood the reason why AbstractCas exists,
> it only has a release method, but CAS and JCas have many methods in
> common. Why are they not declared in AbstractCas ?
>
> The way its now AbstractCas is nearly useless expect
> for cas pooling or so.
>
> What was the reason to not move up the common methods
> when AbstractCas was introduced ?

Good question :-)  -- I wasn't involved with the design here, but I can
think of 2 reasons (there may be others).  (1) API stability - not
wanting to change existing APIs.  I haven't studied API evolution as
much as I might, but I think this kind of change would cause a binary
incompatibility.

(2) Some methods are the same except that in the CAS they return things
of type CAS, and in the JCas they return things of type JCas.  So some
kind of overloading is possible if the arguments are CAS vs JCas, but is
not possible if the returned types are CAS vs JCas.  In this case, the
solution might be to return things of AbstractCas type.

I think the stronger reason was (1), though.

-Marshall
>
> Jörn
>
>
>

Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
> Here's another (probably weak) use case for returning <T extends
> AbstractCas> kinds of things:  If you have part of the code which
> collects views and some of these views use one form of the AbstractCas
> (e.g. CASImpl) and others use the JCas form, it would be nice to be able
> to put these two uses into a collection (of AbstractCas) - which is the
> kind of thing AbstractCas was trying to do, I believe.
>   
I never really understood the reason why AbstractCas exists,
it only has a release method, but CAS and JCas have many methods in
common. Why are they not declared in AbstractCas ?

The way its now AbstractCas is nearly useless expect
for cas pooling or so.

What was the reason to not move up the common methods
when AbstractCas was introduced ?

Jörn


Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
Adam Lally wrote:
> So, bottom line, I say we stick with the recommendation of Brian
> Goetz's article and don't use wildcards in return types.
>   
Well after all this discussion I think thats only true
for cases like getViewIteraterator because of the reasons
given by Adam.

There are other cases in our API where it could make sense
to use wildcards together with a return.

Marshall already started a thread for createFilteredIterator which
I think is worth to discuss and it would be nice if we can also discuss
FSIndexRepository in this context.

Jörn

Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
Marshall Schor wrote:
> Sounds right.  But we should use bounded wildcards for "arguments" where
> appropriate (of course, this doesn't apply to getViewIterator, which has
> no arguments).  The article,
>
> http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU
> has a nice "principle" called the "get-put" principle for arguments:
>
>     Use an |extends| wildcard when you only get values out of
>     a structure, use a |super| wildcard when you only put values
>     into a structure, and don't use a wildcard when you do both.
>
> For the last part, he also says the reason for not using a wild card if you do both:
>     If you can put a |T| or any of its subtypes, and you can get a |T| or any of its supertypes, then the only thing you can both get and
>     put is a |T| itself.
>
>   
Well, I was aware of the get part, but it does not always makes sense, 
in my eyes,
e.g. when a method receives a List<String> from somewhere.
I never used the put part of the rule, which may indicate I did 
something wrong
in a very few places, because output Lists for example are rarely used.

Jörn

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.

Adam Lally wrote:
> On Mon, Aug 10, 2009 at 12:28 PM, Marshall Schor<ms...@schor.com> wrote:
>   
>> Adam Lally wrote:
>>     
>>>> Same issue with using Iterator<AbstractCas>
>>>> Two quick fixes:  casting:
>>>> Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator();
>>>> and
>>>> Iterator<? super CAS> s = aCas.getViewIterator();
>>>>
>>>>
>>>>         
>>> Right.. I think it needs to be like this:
>>>
>>> <T extends Iterator<? super CAS>> T getViewIterator()
>>>
>>>       
>> I tried this, and get for :
>> Iterator<CAS> s = aCas.getViewIterator();
>> the message: Bound mismatch: The generic method getViewIterator() of
>> type CAS is not applicable for the arguments (). The inferred type CAS
>> is not a valid substitute for the bounded parameter <T extends
>> Iterator<? super CAS>>
>> and no quick fixes.
>>
>> I tried some variants, but couldn't get something that worked...
>>
>>     
>
> Well, the following test compiles for me, but I realized that the
> solution isn't good anyway because even though the code can compile
> with a dummy method implementation, I can't actuall provide a real
> implementation for the method!
>
> public class Test {
>   public static void main(String[] args) throws Exception {
>     List<AbstractCas> x = getViewIterator();
>     List<CAS> y = getViewIterator();
>
>   }
>
>   private static <T extends List<? super CAS>> T getViewIterator() {
>     T result = null;
>     CAS c = null;
>     result.add(c);
>     return result;
>   }
>
>
> On the line "T result = null" I can't instantiate T to an actual list
> (I'd have to instantiate whatever type T the client requested, and
> there's no guarantee that's even possible to do.)
>
> So, bottom line, I say we stick with the recommendation of Brian
> Goetz's article and don't use wildcards in return types.
>   

Sounds right.  But we should use bounded wildcards for "arguments" where
appropriate (of course, this doesn't apply to getViewIterator, which has
no arguments).  The article,

http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU
has a nice "principle" called the "get-put" principle for arguments:

    Use an |extends| wildcard when you only get values out of
    a structure, use a |super| wildcard when you only put values
    into a structure, and don't use a wildcard when you do both.

For the last part, he also says the reason for not using a wild card if you do both:
    If you can put a |T| or any of its subtypes, and you can get a |T| or any of its supertypes, then the only thing you can both get and
    put is a |T| itself.


-Marshall
>   -Adam
>
>
>   

Re: generics: getViewIterator

Posted by Adam Lally <al...@alum.rpi.edu>.
On Mon, Aug 10, 2009 at 12:28 PM, Marshall Schor<ms...@schor.com> wrote:
> Adam Lally wrote:
>>> Same issue with using Iterator<AbstractCas>
>>> Two quick fixes:  casting:
>>> Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator();
>>> and
>>> Iterator<? super CAS> s = aCas.getViewIterator();
>>>
>>>
>>
>> Right.. I think it needs to be like this:
>>
>> <T extends Iterator<? super CAS>> T getViewIterator()
>>
>
> I tried this, and get for :
> Iterator<CAS> s = aCas.getViewIterator();
> the message: Bound mismatch: The generic method getViewIterator() of
> type CAS is not applicable for the arguments (). The inferred type CAS
> is not a valid substitute for the bounded parameter <T extends
> Iterator<? super CAS>>
> and no quick fixes.
>
> I tried some variants, but couldn't get something that worked...
>

Well, the following test compiles for me, but I realized that the
solution isn't good anyway because even though the code can compile
with a dummy method implementation, I can't actuall provide a real
implementation for the method!

public class Test {
  public static void main(String[] args) throws Exception {
    List<AbstractCas> x = getViewIterator();
    List<CAS> y = getViewIterator();

  }

  private static <T extends List<? super CAS>> T getViewIterator() {
    T result = null;
    CAS c = null;
    result.add(c);
    return result;
  }


On the line "T result = null" I can't instantiate T to an actual list
(I'd have to instantiate whatever type T the client requested, and
there's no guarantee that's even possible to do.)

So, bottom line, I say we stick with the recommendation of Brian
Goetz's article and don't use wildcards in return types.

  -Adam

Re: generics: getViewIterator

Posted by Thilo Goetz <tw...@gmx.de>.
Marshall Schor wrote:
> 
> Adam Lally wrote:
>>> Same issue with using Iterator<AbstractCas>
>>> Two quick fixes:  casting:
>>> Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator();
>>> and
>>> Iterator<? super CAS> s = aCas.getViewIterator();
>>>
>>>     
>> Right.. I think it needs to be like this:
>>
>> <T extends Iterator<? super CAS>> T getViewIterator()
>>   
> 
> I tried this, and get for :
> Iterator<CAS> s = aCas.getViewIterator();
> the message: Bound mismatch: The generic method getViewIterator() of
> type CAS is not applicable for the arguments (). The inferred type CAS
> is not a valid substitute for the bounded parameter <T extends
> Iterator<? super CAS>>
> and no quick fixes.
> 
> I tried some variants, but couldn't get something that worked...

Let's just try to keep it so simple that as a user, I don't
need a PhD in generics to figure out what the return type
of a method is.

--Thilo

> 
> -Marshall
>> But I am not sure the usefulness of this is worth the added complexity.
>>   -Adam
>>
>>
>>   


Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.

Adam Lally wrote:
>> Same issue with using Iterator<AbstractCas>
>> Two quick fixes:  casting:
>> Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator();
>> and
>> Iterator<? super CAS> s = aCas.getViewIterator();
>>
>>     
>
> Right.. I think it needs to be like this:
>
> <T extends Iterator<? super CAS>> T getViewIterator()
>   

I tried this, and get for :
Iterator<CAS> s = aCas.getViewIterator();
the message: Bound mismatch: The generic method getViewIterator() of
type CAS is not applicable for the arguments (). The inferred type CAS
is not a valid substitute for the bounded parameter <T extends
Iterator<? super CAS>>
and no quick fixes.

I tried some variants, but couldn't get something that worked...

-Marshall
> But I am not sure the usefulness of this is worth the added complexity.
>   -Adam
>
>
>   

Re: generics: getViewIterator

Posted by Adam Lally <al...@alum.rpi.edu>.
> Same issue with using Iterator<AbstractCas>
> Two quick fixes:  casting:
> Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator();
> and
> Iterator<? super CAS> s = aCas.getViewIterator();
>

Right.. I think it needs to be like this:

<T extends Iterator<? super CAS>> T getViewIterator()

But I am not sure the usefulness of this is worth the added complexity.
  -Adam

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.
Adam Lally wrote:
> On Mon, Aug 10, 2009 at 10:10 AM, Marshall Schor<ms...@schor.com> wrote:
>   
>> So, we're back to just the issue (unless another use case can be
>> conceived) of how to iterate, where the uses of the iterator want to use
>> methods from CASImpl.  Is the concensus that having to cast here (e.g.
>> Iterator<CAS> s = aCas.getViewIterator();
>>  while (s.hasNext()) {
>>   CASImpl ci = (CASImpl) s.next();
>>     ... code using ci...
>>  }
>> is preferable to allowing the coder to to specify they want an iterator
>> over <CASImpl> things, in this case?    (Note that you can't fix this by
>> writing:
>> Iterator<CASImpl> s = (Iterator<CASImpl>)aCas.getViewIterator();
>> //gives error message cannot cast from Iterator<CAS> to Iterator<CASImpl>
>> )
>>
>> My preference would be for the form which permitted "Iterator<CASImpl> s
>> = ...", because (a) it would make our code cleaner, (b) it's unlikely
>> users would be confused by this.  The amount of confusion to a user
>> seems similar to the cases without generics, i.e. where a user could
>> write a cast or assignment from a variable typed as a CAS to a CASImpl
>> (which is of course permitted today).
>>
>>     
>
> I actually think the code on top, with the explicit typecast, is
> cleaner.  The getViewIterator() guarantees only that it returns
> objects of type CAS.  If the caller expects those to be CASImpl,
> relying on an internal undocumented invariant, then a typecast is a
> perfectly appropriate way to do that.
>
> If a method's contract is that it returns an Iterator of objects of
> type CAS, then it's logical that it's signature should say that it
> returns Iterator<CAS>.  What is wrong with that?  If you change it to
> return Iterator<T extends CAS>, I think you are saying that it can
> return any subtype of CAS that the user may desire, which just isn't
> true.
>
> Actually if anything I could see a case for the signature
> Iterator<? super CAS> getViewIterator();
>
> because this would allow
> Iterator<AbstractCas> x = getViewIterator();
>
>   

True.  However, it suffers from the same issue you discovered above.

Iterator<CAS> s = aCas.getViewIterator(); // doesn't work, needs a cast:

Iterator<CAS> s = (Iterator<CAS>) aCas.getViewIterator();


Same issue with using Iterator<AbstractCas>
Two quick fixes:  casting:
Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator();
and
Iterator<? super CAS> s = aCas.getViewIterator();

-Marshall




>  -Adam
>
>
>   

Re: generics: getViewIterator

Posted by Adam Lally <al...@alum.rpi.edu>.
On Mon, Aug 10, 2009 at 10:10 AM, Marshall Schor<ms...@schor.com> wrote:
> So, we're back to just the issue (unless another use case can be
> conceived) of how to iterate, where the uses of the iterator want to use
> methods from CASImpl.  Is the concensus that having to cast here (e.g.
> Iterator<CAS> s = aCas.getViewIterator();
>  while (s.hasNext()) {
>   CASImpl ci = (CASImpl) s.next();
>     ... code using ci...
>  }
> is preferable to allowing the coder to to specify they want an iterator
> over <CASImpl> things, in this case?    (Note that you can't fix this by
> writing:
> Iterator<CASImpl> s = (Iterator<CASImpl>)aCas.getViewIterator();
> //gives error message cannot cast from Iterator<CAS> to Iterator<CASImpl>
> )
>
> My preference would be for the form which permitted "Iterator<CASImpl> s
> = ...", because (a) it would make our code cleaner, (b) it's unlikely
> users would be confused by this.  The amount of confusion to a user
> seems similar to the cases without generics, i.e. where a user could
> write a cast or assignment from a variable typed as a CAS to a CASImpl
> (which is of course permitted today).
>

I actually think the code on top, with the explicit typecast, is
cleaner.  The getViewIterator() guarantees only that it returns
objects of type CAS.  If the caller expects those to be CASImpl,
relying on an internal undocumented invariant, then a typecast is a
perfectly appropriate way to do that.

If a method's contract is that it returns an Iterator of objects of
type CAS, then it's logical that it's signature should say that it
returns Iterator<CAS>.  What is wrong with that?  If you change it to
return Iterator<T extends CAS>, I think you are saying that it can
return any subtype of CAS that the user may desire, which just isn't
true.

Actually if anything I could see a case for the signature
Iterator<? super CAS> getViewIterator();

because this would allow
Iterator<AbstractCas> x = getViewIterator();

 -Adam

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.

Jörn Kottmann wrote:
> Marshall Schor wrote:
>> Adam Lally wrote:
>>  
>>> On Sat, Aug 8, 2009 at 4:57 PM, Marshall Schor<ms...@schor.com> wrote:
>>>      
>>>> Jörn Kottmann wrote:
>>>>          
>>>>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>>>>>
>>>>>              
>>>>>> getViewIterator in CASImpl is written with the signature:
>>>>>>  Iterator<CAS> getViewIterator()
>>>>>>
>>>>>> If you are working with things needing CASImpl objects, you would
>>>>>> write:
>>>>>>
>>>>>>  Iterator<CAS> s = aCas.getViewIterator();
>>>>>>  while (s.hasNext()) {
>>>>>>    CASImpl ci = (CASImpl) s.next();
>>>>>>      ... code using ci...
>>>>>>  }
>>>>>>
>>>>>> If we changed the signature to:
>>>>>>  Iterator<T extends CAS> getViewIterator()
>>>>>> then you would write:
>>>>>>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done
>>>>>> inside the
>>>>>> support code, not here
>>>>>>  while (s.hasNext()) {
>>>>>>    CASImpl ci = s.next();  // works OK without casting
>>>>>>      ... code using ci...
>>>>>>  }
>>>>>>
>>>>>> Would it be better to have that form of the signature?
>>>>>>                   
>>>>> +1, though did not know that its possible, we should check other
>>>>> places too
>>>>>               
>>>> +1 to checking other places :-)
>>>>
>>>> The tutorial on generics by Gilad Bracha,
>>>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20
>>>> near
>>>> the top says:
>>>>
>>>>          
>>>>> In general, if you have an API that only uses a type parameter T
>>>>> as an
>>>>> argument, its
>>>>> uses should take advantage of lower bounded wildcards (? super T).
>>>>> Conversely, if
>>>>> the API only returns T, you’ll give your clients more flexibility by
>>>>> using upper bounded
>>>>> wildcards (? extends T).
>>>>>               
>>>> There are many cases I think in our generification where the 2nd
>>>> part of
>>>> this, returning XXX<? extends T> or a variant, is a better choice.
>>>>
>>>>           
>>> I must say I don't understand why returning something like List<?
>>> extends CAS> is an improvement.  Is this supposed to mean that the
>>> client could specify ANY subtype of CAS and it's supposed to work?  So
>>> someone could write:
>>> class MyCas implements CAS {...}
>>> List<MyCas> result = aCAS.getViewIterator()
>>> Which couldn't possibly work.  I guess it would compile but generate a
>>> ClassCastException at runtime.  Is that a good thing?
>>>
>>> I found an expert with a differing point of view from your expert:
>>> http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU
>>>
>>>
>>> "Keep bounded wildcards out of return values
>>>
>>> It is sometimes tempting to use a bounded wildcard in the return type
>>> of a method. But this temptation is best avoided because returning
>>> bounded wildcards tends to "pollute" client code. If a method were to
>>> return a Box<? extends T>, then the type of the variable receiving the
>>> return value would have to be Box<? extends T>, which pushes the
>>> burden of dealing with bounded wildcards on your callers. Bounded
>>> wildcards work best when they are used in APIs, not in client code."
>>>       
>>
>> This is a good discussion.  I didn't realize that about bounded
>> wildcards.  But there's another choice.
>>
>> Consider the difference between <? extends T> and a form that looks
>> like:
>> public <T extends AbstractCas> Iterator<T> getViewIterator() {
>>
>> This latter form doesn't use a wild card, and if it is used as the
>> return type of the method, the return type's match for T gets used, and
>> this doesn't have the issue above.
>> So that's another choice, and that was the choice I was thinking about
>> in my original post, where the actual form was written incorrectly (the
>> correct way is above).
>>
>>   
> If we do it like this we would be able to move the getViewIterator
> methods up to the AbstractCas interface.

That would be nice, but it would change our public APIs, right?
I noticed that JCas interface defines
  Iterator<CAS> getViewIterator() throws CASException; // comment says
each returned object is of type JCas
which I guess is incorrect, right? - should be
  Iterator<JCas> ...

>
> If you write it like proposed
>
> <T extends AbstractCas> Iterator<T> getViewIterator()
>
> then a user could think its ok to write
>
> CAS cas ...
> Iterator<JCAS> casIterator = cas.getViewIterator()
>
> which I think should fail with a compiler error.

But this should work I think:
   JCas aJCas = ...
  Iterator<JCas> it = aJCas.getViewIterator();

So your point is that if you start with a "cas" which is bound to an
instance of CAS (or CASImpl), then it should not return AbstractCas,
because that's too general.  Is that what you are saying? (Assuming so),
this seems correct.

>
>
>> Here's another (probably weak) use case for returning <T extends
>> AbstractCas> kinds of things:  If you have part of the code which
>> collects views and some of these views use one form of the AbstractCas
>> (e.g. CASImpl) and others use the JCas form, it would be nice to be able
>> to put these two uses into a collection (of AbstractCas) - which is the
>> kind of thing AbstractCas was trying to do, I believe.
>>
>> If we changed getViewIterator to return Iterator<AbstractCas>  (another
>> choice), that would serve the use case in the above paragraph, but then
>> the form
>> Iterator<CAS> it = aCas.getViewIterator()
>> would give a compile-time error.
>>
>> It seems to me that <T extends AbstractCas> is a better generification,
>> here.
>>   
>
> I am not getting this one. Lets say we have
>
> Iterator<CAS> getViewIterator()
>
> then a user could write an add method
>
> void add(Collection<AbstractCas> test, Iterator<? extends AbstractCas>
> iterator)
>
> to add the objects retrieved from a view iterator to a collection.

Yes, I tried that out - and it works.  So you've found a nice way that
addresses my (weak) use case :-) .

So, we're back to just the issue (unless another use case can be
conceived) of how to iterate, where the uses of the iterator want to use
methods from CASImpl.  Is the concensus that having to cast here (e.g.
Iterator<CAS> s = aCas.getViewIterator();
 while (s.hasNext()) {
   CASImpl ci = (CASImpl) s.next();
     ... code using ci...
 }
is preferable to allowing the coder to to specify they want an iterator
over <CASImpl> things, in this case?    (Note that you can't fix this by
writing:
Iterator<CASImpl> s = (Iterator<CASImpl>)aCas.getViewIterator(); 
//gives error message cannot cast from Iterator<CAS> to Iterator<CASImpl>
)

My preference would be for the form which permitted "Iterator<CASImpl> s
= ...", because (a) it would make our code cleaner, (b) it's unlikely
users would be confused by this.  The amount of confusion to a user
seems similar to the cases without generics, i.e. where a user could
write a cast or assignment from a variable typed as a CAS to a CASImpl
(which is of course permitted today). 

-Marshall
>
> Jörn
>

Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
Marshall Schor wrote:
> Adam Lally wrote:
>   
>> On Sat, Aug 8, 2009 at 4:57 PM, Marshall Schor<ms...@schor.com> wrote:
>>   
>>     
>>> Jörn Kottmann wrote:
>>>     
>>>       
>>>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>>>>
>>>>       
>>>>         
>>>>> getViewIterator in CASImpl is written with the signature:
>>>>>  Iterator<CAS> getViewIterator()
>>>>>
>>>>> If you are working with things needing CASImpl objects, you would write:
>>>>>
>>>>>  Iterator<CAS> s = aCas.getViewIterator();
>>>>>  while (s.hasNext()) {
>>>>>    CASImpl ci = (CASImpl) s.next();
>>>>>      ... code using ci...
>>>>>  }
>>>>>
>>>>> If we changed the signature to:
>>>>>  Iterator<T extends CAS> getViewIterator()
>>>>> then you would write:
>>>>>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
>>>>> support code, not here
>>>>>  while (s.hasNext()) {
>>>>>    CASImpl ci = s.next();  // works OK without casting
>>>>>      ... code using ci...
>>>>>  }
>>>>>
>>>>> Would it be better to have that form of the signature?
>>>>>         
>>>>>           
>>>> +1, though did not know that its possible, we should check other
>>>> places too
>>>>       
>>>>         
>>> +1 to checking other places :-)
>>>
>>> The tutorial on generics by Gilad Bracha,
>>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20 near
>>> the top says:
>>>
>>>     
>>>       
>>>> In general, if you have an API that only uses a type parameter T as an
>>>> argument, its
>>>> uses should take advantage of lower bounded wildcards (? super T).
>>>> Conversely, if
>>>> the API only returns T, you’ll give your clients more flexibility by
>>>> using upper bounded
>>>> wildcards (? extends T).
>>>>       
>>>>         
>>> There are many cases I think in our generification where the 2nd part of
>>> this, returning XXX<? extends T> or a variant, is a better choice.
>>>
>>>     
>>>       
>> I must say I don't understand why returning something like List<?
>> extends CAS> is an improvement.  Is this supposed to mean that the
>> client could specify ANY subtype of CAS and it's supposed to work?  So
>> someone could write:
>> class MyCas implements CAS {...}
>> List<MyCas> result = aCAS.getViewIterator()
>> Which couldn't possibly work.  I guess it would compile but generate a
>> ClassCastException at runtime.  Is that a good thing?
>>
>> I found an expert with a differing point of view from your expert:
>> http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU
>>
>> "Keep bounded wildcards out of return values
>>
>> It is sometimes tempting to use a bounded wildcard in the return type
>> of a method. But this temptation is best avoided because returning
>> bounded wildcards tends to "pollute" client code. If a method were to
>> return a Box<? extends T>, then the type of the variable receiving the
>> return value would have to be Box<? extends T>, which pushes the
>> burden of dealing with bounded wildcards on your callers. Bounded
>> wildcards work best when they are used in APIs, not in client code."
>>   
>>     
>
> This is a good discussion.  I didn't realize that about bounded
> wildcards.  But there's another choice.
>
> Consider the difference between <? extends T> and a form that looks like:
> public <T extends AbstractCas> Iterator<T> getViewIterator() {
>
> This latter form doesn't use a wild card, and if it is used as the
> return type of the method, the return type's match for T gets used, and
> this doesn't have the issue above.
> So that's another choice, and that was the choice I was thinking about
> in my original post, where the actual form was written incorrectly (the
> correct way is above).
>
>   
If we do it like this we would be able to move the getViewIterator
methods up to the AbstractCas interface.

If you write it like proposed

<T extends AbstractCas> Iterator<T> getViewIterator()

then a user could think its ok to write

CAS cas ...
Iterator<JCAS> casIterator = cas.getViewIterator()

which I think should fail with a compiler error.

> Here's another (probably weak) use case for returning <T extends
> AbstractCas> kinds of things:  If you have part of the code which
> collects views and some of these views use one form of the AbstractCas
> (e.g. CASImpl) and others use the JCas form, it would be nice to be able
> to put these two uses into a collection (of AbstractCas) - which is the
> kind of thing AbstractCas was trying to do, I believe.
>
> If we changed getViewIterator to return Iterator<AbstractCas>  (another
> choice), that would serve the use case in the above paragraph, but then
> the form
> Iterator<CAS> it = aCas.getViewIterator()
> would give a compile-time error.
>
> It seems to me that <T extends AbstractCas> is a better generification,
> here.
>   

I am not getting this one. Lets say we have

Iterator<CAS> getViewIterator()

then a user could write an add method

void add(Collection<AbstractCas> test, Iterator<? extends AbstractCas> iterator)

to add the objects retrieved from a view iterator to a collection.

Jörn

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.
Adam Lally wrote:
> On Sat, Aug 8, 2009 at 4:57 PM, Marshall Schor<ms...@schor.com> wrote:
>   
>> Jörn Kottmann wrote:
>>     
>>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>>>
>>>       
>>>> getViewIterator in CASImpl is written with the signature:
>>>>  Iterator<CAS> getViewIterator()
>>>>
>>>> If you are working with things needing CASImpl objects, you would write:
>>>>
>>>>  Iterator<CAS> s = aCas.getViewIterator();
>>>>  while (s.hasNext()) {
>>>>    CASImpl ci = (CASImpl) s.next();
>>>>      ... code using ci...
>>>>  }
>>>>
>>>> If we changed the signature to:
>>>>  Iterator<T extends CAS> getViewIterator()
>>>> then you would write:
>>>>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
>>>> support code, not here
>>>>  while (s.hasNext()) {
>>>>    CASImpl ci = s.next();  // works OK without casting
>>>>      ... code using ci...
>>>>  }
>>>>
>>>> Would it be better to have that form of the signature?
>>>>         
>>> +1, though did not know that its possible, we should check other
>>> places too
>>>       
>> +1 to checking other places :-)
>>
>> The tutorial on generics by Gilad Bracha,
>> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20 near
>> the top says:
>>
>>     
>>> In general, if you have an API that only uses a type parameter T as an
>>> argument, its
>>> uses should take advantage of lower bounded wildcards (? super T).
>>> Conversely, if
>>> the API only returns T, you’ll give your clients more flexibility by
>>> using upper bounded
>>> wildcards (? extends T).
>>>       
>> There are many cases I think in our generification where the 2nd part of
>> this, returning XXX<? extends T> or a variant, is a better choice.
>>
>>     
>
> I must say I don't understand why returning something like List<?
> extends CAS> is an improvement.  Is this supposed to mean that the
> client could specify ANY subtype of CAS and it's supposed to work?  So
> someone could write:
> class MyCas implements CAS {...}
> List<MyCas> result = aCAS.getViewIterator()
> Which couldn't possibly work.  I guess it would compile but generate a
> ClassCastException at runtime.  Is that a good thing?
>
> I found an expert with a differing point of view from your expert:
> http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU
>
> "Keep bounded wildcards out of return values
>
> It is sometimes tempting to use a bounded wildcard in the return type
> of a method. But this temptation is best avoided because returning
> bounded wildcards tends to "pollute" client code. If a method were to
> return a Box<? extends T>, then the type of the variable receiving the
> return value would have to be Box<? extends T>, which pushes the
> burden of dealing with bounded wildcards on your callers. Bounded
> wildcards work best when they are used in APIs, not in client code."
>   

This is a good discussion.  I didn't realize that about bounded
wildcards.  But there's another choice.

Consider the difference between <? extends T> and a form that looks like:
public <T extends AbstractCas> Iterator<T> getViewIterator() {

This latter form doesn't use a wild card, and if it is used as the
return type of the method, the return type's match for T gets used, and
this doesn't have the issue above.
So that's another choice, and that was the choice I was thinking about
in my original post, where the actual form was written incorrectly (the
correct way is above).

Here's another (probably weak) use case for returning <T extends
AbstractCas> kinds of things:  If you have part of the code which
collects views and some of these views use one form of the AbstractCas
(e.g. CASImpl) and others use the JCas form, it would be nice to be able
to put these two uses into a collection (of AbstractCas) - which is the
kind of thing AbstractCas was trying to do, I believe.

If we changed getViewIterator to return Iterator<AbstractCas>  (another
choice), that would serve the use case in the above paragraph, but then
the form
Iterator<CAS> it = aCas.getViewIterator()
would give a compile-time error.

It seems to me that <T extends AbstractCas> is a better generification,
here.

-Marshall


>  -Adam
>
>
>   

Re: generics: getViewIterator

Posted by Adam Lally <al...@alum.rpi.edu>.
On Sat, Aug 8, 2009 at 4:57 PM, Marshall Schor<ms...@schor.com> wrote:
> Jörn Kottmann wrote:
>>
>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>>
>>> getViewIterator in CASImpl is written with the signature:
>>>  Iterator<CAS> getViewIterator()
>>>
>>> If you are working with things needing CASImpl objects, you would write:
>>>
>>>  Iterator<CAS> s = aCas.getViewIterator();
>>>  while (s.hasNext()) {
>>>    CASImpl ci = (CASImpl) s.next();
>>>      ... code using ci...
>>>  }
>>>
>>> If we changed the signature to:
>>>  Iterator<T extends CAS> getViewIterator()
>>> then you would write:
>>>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
>>> support code, not here
>>>  while (s.hasNext()) {
>>>    CASImpl ci = s.next();  // works OK without casting
>>>      ... code using ci...
>>>  }
>>>
>>> Would it be better to have that form of the signature?
>>
>> +1, though did not know that its possible, we should check other
>> places too
>
> +1 to checking other places :-)
>
> The tutorial on generics by Gilad Bracha,
> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20 near
> the top says:
>
>> In general, if you have an API that only uses a type parameter T as an
>> argument, its
>> uses should take advantage of lower bounded wildcards (? super T).
>> Conversely, if
>> the API only returns T, you’ll give your clients more flexibility by
>> using upper bounded
>> wildcards (? extends T).
>
> There are many cases I think in our generification where the 2nd part of
> this, returning XXX<? extends T> or a variant, is a better choice.
>

I must say I don't understand why returning something like List<?
extends CAS> is an improvement.  Is this supposed to mean that the
client could specify ANY subtype of CAS and it's supposed to work?  So
someone could write:
class MyCas implements CAS {...}
List<MyCas> result = aCAS.getViewIterator()

Which couldn't possibly work.  I guess it would compile but generate a
ClassCastException at runtime.  Is that a good thing?

I found an expert with a differing point of view from your expert:
http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU

"Keep bounded wildcards out of return values

It is sometimes tempting to use a bounded wildcard in the return type
of a method. But this temptation is best avoided because returning
bounded wildcards tends to "pollute" client code. If a method were to
return a Box<? extends T>, then the type of the variable receiving the
return value would have to be Box<? extends T>, which pushes the
burden of dealing with bounded wildcards on your callers. Bounded
wildcards work best when they are used in APIs, not in client code."

 -Adam

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.
Jörn Kottmann wrote:
>
> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:
>
>> getViewIterator in CASImpl is written with the signature:
>>  Iterator<CAS> getViewIterator()
>>
>> If you are working with things needing CASImpl objects, you would write:
>>
>>  Iterator<CAS> s = aCas.getViewIterator();
>>  while (s.hasNext()) {
>>    CASImpl ci = (CASImpl) s.next();
>>      ... code using ci...
>>  }
>>
>> If we changed the signature to:
>>  Iterator<T extends CAS> getViewIterator()
>> then you would write:
>>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
>> support code, not here
>>  while (s.hasNext()) {
>>    CASImpl ci = s.next();  // works OK without casting
>>      ... code using ci...
>>  }
>>
>> Would it be better to have that form of the signature?
>
> +1, though did not know that its possible, we should check other
> places too

+1 to checking other places :-) 

The tutorial on generics by Gilad Bracha, 
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf,  on page 20 near
the top says:

> In general, if you have an API that only uses a type parameter T as an
> argument, its
> uses should take advantage of lower bounded wildcards (? super T).
> Conversely, if
> the API only returns T, you’ll give your clients more flexibility by
> using upper bounded
> wildcards (? extends T).

There are many cases I think in our generification where the 2nd part of
this, returning XXX<? extends T> or a variant, is a better choice.

-Marshall
>
>
> Jörn
>
>
>

Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote:

> getViewIterator in CASImpl is written with the signature:
>  Iterator<CAS> getViewIterator()
>
> If you are working with things needing CASImpl objects, you would  
> write:
>
>  Iterator<CAS> s = aCas.getViewIterator();
>  while (s.hasNext()) {
>    CASImpl ci = (CASImpl) s.next();
>      ... code using ci...
>  }
>
> If we changed the signature to:
>  Iterator<T extends CAS> getViewIterator()
> then you would write:
>  Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the
> support code, not here
>  while (s.hasNext()) {
>    CASImpl ci = s.next();  // works OK without casting
>      ... code using ci...
>  }
>
> Would it be better to have that form of the signature?

+1, though did not know that its possible, we should check other
places too

Jörn


Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.
Jukka Zitting wrote:
> Hi,
>
> On Mon, Aug 10, 2009 at 11:44 AM, Jörn Kottmann<ko...@gmail.com> wrote:
>   
>>> On a related note, have you considered using Iterables instead of
>>> Iterators? They make the looping constructs much nicer.
>>>       
>> Its not possible to use Iterables instead of Itertors because
>> that will break backward compatibility of our API.
>>     
>
> Yep, the benefit is not big enough to break backwards compatibility.
>
> I was thinking more about internal interfaces and constructs. We
> recently upgraded Apache Jackrabbit to Java 5 and there we switched to
> Iterables in many internal code paths.
>
> The change from
>
>     Iterator<Foo> iterator = ...;
>     while (iterator.hasNext()) {
>         Foo foo = iterator.next();
>         ...;
>     }
>
> to
>
>     for (Foo foo : ...) {
>         ...;
>     }
>
> made many parts of the codebase more readable.
>
>   

I agree - Good change for internals.  I've seen some instances of this
kind of rewrite going on when a module is opened up (usually for other
issues).
-Marshall
> BR,
>
> Jukka Zitting
>
>
>   

Re: generics: getViewIterator

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Mon, Aug 10, 2009 at 11:44 AM, Jörn Kottmann<ko...@gmail.com> wrote:
>> On a related note, have you considered using Iterables instead of
>> Iterators? They make the looping constructs much nicer.
>
> Its not possible to use Iterables instead of Itertors because
> that will break backward compatibility of our API.

Yep, the benefit is not big enough to break backwards compatibility.

I was thinking more about internal interfaces and constructs. We
recently upgraded Apache Jackrabbit to Java 5 and there we switched to
Iterables in many internal code paths.

The change from

    Iterator<Foo> iterator = ...;
    while (iterator.hasNext()) {
        Foo foo = iterator.next();
        ...;
    }

to

    for (Foo foo : ...) {
        ...;
    }

made many parts of the codebase more readable.

BR,

Jukka Zitting

Re: generics: getViewIterator

Posted by Jörn Kottmann <ko...@gmail.com>.
> On a related note, have you considered using Iterables instead of
> Iterators? They make the looping constructs much nicer.
>   
Its not possible to use Iterables instead of Itertors because
that will break backward compatibility of our API.

An option is to let FSIterator also extend Iterable, though
the semantics of an Iterator having the iterator method
may be confusing to some.

Jörn

Re: generics: getViewIterator

Posted by Marshall Schor <ms...@schor.com>.

Jukka Zitting wrote:
> Hi,
>
> On Fri, Aug 7, 2009 at 8:57 PM, Marshall Schor<ms...@schor.com> wrote:
>   
>> Would it be better to have that form of the signature?
>>     
>
> I don't know much about UIMA patterns, but in general something like
> that seems a bit questionable to me. Where's the part of the API that
> says that the client can expect CASImpl objects from the returned
> Iterator?
>   

True, that's not part of the API.  So users won't use that.  But the
internal code makes use of the xxx_impl forms a lot, and generification
with returned things of the form <? extends T> are needed to enable that
use, I think.
> On a related note, have you considered using Iterables instead of
> Iterators? They make the looping constructs much nicer.
>   

I agree; these could be added.  Would they be "additions to", not
updates of the existing APIs?

-Marshall
> BR,
>
> Jukka Zitting
>
>
>   

Re: generics: getViewIterator

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Fri, Aug 7, 2009 at 8:57 PM, Marshall Schor<ms...@schor.com> wrote:
> Would it be better to have that form of the signature?

I don't know much about UIMA patterns, but in general something like
that seems a bit questionable to me. Where's the part of the API that
says that the client can expect CASImpl objects from the returned
Iterator?

On a related note, have you considered using Iterables instead of
Iterators? They make the looping constructs much nicer.

BR,

Jukka Zitting