Skip to main content

About iterative control abstraction

Posted by forax on October 4, 2006 at 12:11 PM PDT

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 map, Block2 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 >>