Skip to main content

About iterative control abstraction

Posted by forax on October 4, 2006 at 3:11 PM EDT

Neal proposes to use for to tag methods that take a synchronous closure as parameter and to call this new kind of method.

It's better than to use synchronized as proposed before but (there is always a but :) i see two drawbacks.
First, for is used to tag the whole method and not one of its parameter so there is no way to define a method that takes a synchronous closure and an asynchronous one. Second, in Java, for is an instruction and not an expression but synchronous method may return a value.

  int sum=for each(int sum,Integer value:Arrays.asList(2,3),0) {
    sum+value
  }
  ...

Else, there is a bug in signature of the method eachEntry proposed by Neal. He uses the syntax of the closure v0.2 and as i was explained here if you don't use function type, you have to care about subtyping relationship between parametrized types.
The code above is not legal with the signature given by Neal void for eachEntry(Map<K,V> map, Block2<K,V,E> block) throws E.

 Map<String,Droid> map=...
 for eachEntry(CharSequence droidName, Droid droid : map) {
   ...
 }

The type of droidName must be the same than the first type argument of the map, here String and not CharSequence.
The method signature eachEntry must be changed to :

public interface Block2<K,V,throws E> {
    void invoke(K k, V v) throws E;
}
public static <K,V,throws E>
void for eachEntry(Map<K,V> map, Block2<? super K,? super V,E> block) throws E {
    for (Map.Entry<K,V> entry : map.entrySet()) {
        block.invoke(entry.getKey(), entry.getValue());
    }
}

I still prefer the closure v0.1, i think dispite the fact that it introduce a new type (function type), it's simpler to read.
The method each of my first example with the v0.2 is coded like this:

  public interface Expr1<V,R> {
    R invoke(V v,R r);
  }
  public static <R,V>
  R for each(Collection<? extends V> values,R initialValue,
   Expr1<R,? super V> expr) {
    for(V value:values)
      initialValue=expr1.invoke(value,initialValue);
    return initialValue;
  }
and with v0.1 :
  public static <R,V>
  R each(Collection<V> values,R initialValue,R(V v,R R) expr) {
    for(V value:values)
      initialValue=expr1(value,initialValue);
    return initialValue;
  }

Rémi

Related Topics >>