So long as the Runtime error is meaningful and documented then I vote for option 3. <T extends TOP> still limits the user to the family of the UIMA universe so to speak without limiting them to an explicit FS inheritance which is a useful flexibility in spite of the risk of a casting error.
Thanks, Thomas Ginter 801-448-7676 thomas.gin...@utah.edu > On Jul 8, 2015, at 09:14, Marshall Schor <m...@schor.com> wrote: > > I agree that (3) is not "safe". However it imposes a burden on the user > (assuming they want to use some method that's in the type but not in TOP) to > cast the result to the type. This cast could also throw a runtime error, of > course. > > So, what I'm thinking is that there's no particular value in not allowing 3) - > the user could cause a runtime error in either case; > but not doing 3) would make UIMA "get in the way" of coders trying to get > their > work done :-) - for the case where they were doing proper type casting. > > On balance, it seems to me to be better to allow 3. > > re: using the older forms: yes, that's really not needed (except perhaps for > edge cases), so could be deprecated. At this point, I'm not sure that's worth > doing, though... > > Here's one edge case (these are hard to think of :-) ). The coder has a type > hierarchy A -> B . They define JCas class for A, but not for B. > To get all instances of B, they would need the older format. > > -Marshall > > On 7/8/2015 9:44 AM, Richard Eckart de Castilho wrote: >>> If type inferencing from the surrounding context wasn't done, and the user >>> needed to cast the result, the user would be exposed to the same runtime >>> error. So, unless there's some other pros/cons, it seems to me it would be >>> best to allow generic type inferencing in cases where there's a type >>> specified (by any means) in the getAllIndexedFS method call. >> I'd not say "by any means". >> >> using JCas APIs: >> 1) FSIterator<TOP> getAllIndexedFS(aType); >> 2) <T extends TOP> FSIterator<T> getAllIndexedFS(Class<T> clazz) >> 3) <T extends TOP> FSIterator<T> getAllIndexedFS(aType) >> >> I'd consider 1 and 2 to be safe and ok: >> - 1 is guaranteed to return TOP or a subtype of it. >> - 2 is quaranteed to return clazz or a subtype of it. >> >> 3 is not save: >> >> FSIterator<Token> i = getAllIndexedFS(Sentence.type) >> >> This causes a runtime error. >> >> Question: except for history reasons, why do we need the "aType" >> signature in a JCas context at all? Couldn't it be deprecated >> in favor of the type-safe "clazz" variant? >> >> -- Richard >> >> On 08.07.2015, at 15:24, Marshall Schor <m...@schor.com> wrote: >> >>> More about the signatures and type inference. >>> >>> We have the following cases: >>> >>> (maybe) not JCas, using CAS APIs: >>> (maybe because a JCas user might get a CAS - not a JCas - in some >>> routine) >>> >>> (no arguments in getAllIndexedFS) >>> FSIterator<...> getAllIndexedFS(); >>> >>> (type argument in getAllIndexedFS) >>> FSIterator<...> getAllIndexedFS(aType); >>> >>> using JCas APIs: >>> (no arguments in getAllIndexedFS) >>> FSIterator<...> getAllIndexedFS(); >>> >>> (type argument in getAllIndexedFS) >>> FSIterator<...> getAllIndexedFS(aType); >>> FSIterator<...> getAllIndexedFS(Class<Foo> clazz) >>> >>> For the getAllIndexedFS() (no argument) kinds of calls, I think there's >>> agreement to use the generic FeatureStructure for the CAS APIs, and TOP for >>> the JCas APIs. >>> >>> When the getAllIndexedFS is given type arguments, the method returns an >>> iterator over that type and its subtypes. Here it seems best to use the >>> JCas type corresponding to the type argument. This is easy to do in the >>> last case, above. It can be "allowed" if the other calls use generic >>> method forms and pick up the type from the surrounding context. >>> >>> The "pro" for doing this is that it makes UIMA more coder-friendly, by not >>> requiring the coder to "cast" the result. >>> The "con" for doing this is that it allows the coder to make a mistake >>> (specifying the wrong type). This would only be caught at run time. >> >