Proposal: Accepting a subclass as an element type in a for loop
Reinier Zwitserloot
reinier at zwitserloot.com
Tue Mar 31 08:16:01 PDT 2009
Why is this worthy of a language change? It's very niche.
You can solve your problem by writing 1 method, like so:
for ( Rectangle r : MyUtilityClass.filterOnType(shapes,
Rectangle.class) ) {
drawRectangle(r);
}
with:
public class MyUtilityClass {
public static <A, B> List<B> filterOnType(Iterable<? extends A>
in, Class<B> outType) {
List<B> list = new ArrayList<B>();
for ( A a : in )
if ( outType.isInstance(a) ) list.add(outType.cast(a));
return list;
}
Even if you disregard for a moment that if you add this, I've got
about a gazillion other niche things that have about as many use cases
and are about as easy to solve with a library for coin,your proposal
has omitted a rather serious issue:
What would you do if you have something like:
List<Set<Number>> foo = someMethodCall();
for ( Set<Double> set : foo ) {
// You can't do this in java.
}
--Reinier Zwitserloot
On Mar 31, 2009, at 14:55, Jean-Louis Ardoint wrote:
> I'm maybe a bit too late. Here's my proposal anyway.
>
>
>
> -- Jean-Louis Ardoint
>
>
>
> Accepting a subclass as an element type in a for loop
>
>
>
> AUTHOR(S): Jean-Louis Ardoint
>
>
>
> OVERVIEW
>
>
>
> FEATURE SUMMARY
>
>
>
> Add a filtering and downcast capability to the enhanced for statement
> (a.k.a for each).
>
>
>
> MAJOR ADVANTAGE
>
>
>
> It should reduce the number of lines of code and depth of nesting in
> loops. The resulting code would be more readable that what is done
> currently to achieve the same goal. The meaning of such a loop is
> quite
> obvious.
>
>
>
> MAJOR BENEFIT
>
>
>
> Better readability and expressiveness.
>
>
>
> MAJOR DISADVANTAGE
>
>
>
> More complexity in the compiler to generate a little bit more
> bytecode.
>
>
>
> ALTERNATIVE
>
>
>
> You can currently the same thing, yet it means adding an extra if
> statement and an intermediate variable to be cast.
>
>
>
> EXAMPLES
>
>
>
> Here is a small not very interesting example of such a enhanced for
> loop:
>
>
>
> Shape[] shapes = ...;
>
> for (Shape s : shapes)
>
> drawShape(s);
>
>
>
> If for a reason you would need to draw only the rectangles, you would
> need to write:
>
>
>
> for (Shape s : shapes) {
>
> if (s instanceof Rectangle)
>
> drawRectangle((Rectangle)s);
>
> }
>
>
>
> This is not very aesthetic. If only the for loop would directly
> accept a
> subclass as the element type and do the type checking and downcast, we
> could be able to write:
>
>
>
> for (Rectangle r : shapes)
>
> drawRectangle(r);
>
>
>
> Note that there is a subtlety w.r.t. the handling of nulls. See
> Compilation below for more details
>
>
>
> DETAILS
>
>
>
> SPECIFICATION:
>
>
>
> The grammar is unchanged. The equivalence between an enhanced for loop
> and a regular for loop has to be changed in JLS 14.14.2.
>
> COMPILATION:
>
>
>
> The way enhanced loop are translated into bytecode would change
> depending on whether the loop variable type is a subclass of the
> iterable or array element type.
>
> If the loop variable type is a subclass, then the loop is equivalent
> to:
>
>
>
> For an expression returning Iterable<C>:
>
> Iterable<C> cs...
>
> for (I #i = cs.iterator(); #i.hasNext(); ) {
>
> C #c = #i.next();
>
> if (#c == null || #c instanceof D) {
>
> D d = (C)#c;
>
> ...
>
> }
>
> }
>
>
>
> For an array:
>
>
>
> C[] ca...
>
> for (int i = 0; i < ca.length; i++) {
>
> C #c = ca[i];
>
> if (#c == null || #c instanceof D) {
>
> D d = (C)#c;
>
> ...
>
> }
>
> }
>
>
>
> Note that we need to test against null to keep the same behavior as
> the
> regular enhanced for loop.
>
>
>
> TESTING:
>
>
>
> This feature can be tested in the same way the enhanced for loop is
> tested.
>
>
>
>
>
> LIBRARY SUPPORT:
>
>
>
> There is no need for library support.
>
>
>
>
>
> REFLECTIVE APIS:
>
>
>
> No updates to the reflection APIs are needed.
>
>
>
>
>
> OTHER CHANGES:
>
>
>
> No other changes are needed.
>
>
>
>
>
> MIGRATION:
>
>
>
> Migration of existing enhanced for loop can be done if one desires so.
>
>
>
> COMPATIBILITY
>
>
>
>
>
> BREAKING CHANGES:
>
>
>
> This feature would not break any existing programs, since the new
> feature only permits more code to be parsed than before.
>
>
>
>
>
> EXISTING PROGRAMS:
>
>
>
> Class file format does not change, so existing programs can use class
> files compiled with the new feature without problems.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
More information about the coin-dev
mailing list