Proposal: Accepting a subclass as an element type in a for loop

Reinier Zwitserloot reinier at zwitserloot.com
Tue Mar 31 08:45:58 PDT 2009


Mistake in my sample. try List<Set<? extends Number>> as an input  
source.

I'll qualify my 'this is too niche' with: I've never, ever, needed  
that. I can think of many things that follow the same general line of  
thought that I'd also never need. Why is yours so special? Can you  
show some relevant use cases? Why is null included in this one? Only  
because it technically can be cast? If you consider the 'instanceof'  
syntax sugar on its face value, you should NOT include it. Why is  
inclusion preferred? Will there be an alternative syntax if I want to  
exclude null? If not, why is that not a valid use case, but yours is?


Some proposals have obvious use cases. Others dont. I would venture a  
guess that it would be quite useful to prove the merit of the use  
cases  you're trying to solve if you're not absolutely certain you  
fall into the former category.

  --Reinier Zwitserloot



On Mar 31, 2009, at 17:41, Jean-Louis Ardoint wrote:

> You might say that all proposals are very niche, and almost all of  
> them can be solved by writing some code (you may save some time by  
> writing a generic comment ☺).
>
> About
> List<Set<Number>> foo = someMethodCall();
> for ( Set<Double> set : foo ) {
>   // You can't do this in java.
> }
>
> I don't understand your point. A List<Set<Number>> should not  
> contain a Set<Double> if you use generics without tweaks. So what  
> would you expect?
>
> Anyway, thank you for your comments.
>
> --Jean-Louis Ardoint
>
>
>
> ________________________________________
> From: Reinier Zwitserloot [mailto:reinierz at gmail.com] On Behalf Of  
> Reinier Zwitserloot
> Sent: Tuesday, March 31, 2009 5:16 PM
> To: Jean-Louis Ardoint
> Cc: coin-dev at openjdk.java.net
> Subject: Re: Proposal: Accepting a subclass as an element type in a  
> for loop
>
> 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