Tuesday, August 19, 2008

Modifier 'for'

Modifier 'for'

Method modifier 'for' enables us to declare and call "loop-like" methods.

  static for void eachEntry(int[] values, { int ==> void } block) {
    for (int p : values) {
      block.invoke(p);
    }
  }
  
  public static void main(String[] args) {
    int[] v = { 2, 3, 5, 7, 11 };
    for eachEntry(int i : v) {
      System.out.println(i);
      if (i > 3) {
        break;
      }
    }
  }
  

For example, we can declare a method that iterates through a map:

  static for <K, V> void eachMapEntry(Map<K, V> dict, 
      { K, V ==> void } block) {
    for (Map.Entry<K, V> entry : dict.entrySet()) {
      block.invoke(entry.getKey(), entry.getValue());
    }
  }
  
  public static void main(String[] args) {
    Map<String, String> dict = new HashMap<String, String>();
    ...
    for eachMapEntry(String k, String v : dict) {
      System.out.println(k + ": " + v);
    }
  }
  

6 comments:

Luc Duponcheel said...

cool post!

Anonymous said...

could you explain : I miss something which is probably so obvious that you forgot to explain to a newbie ... why is the first paramater declared int[] and then used as (int i : v) ?
a clearer descritpion of the rules is needed (I just "suspect" what is happening ..)
thanks

bernard (I can't remember my passwd!)

Zdeněk Troníček said...

Hi Bernard,

this definitely deserves explanation: 'i' in 'for eachEntry(int i : v)' is a formal parameter of the closure which is supplied using the control syntax and 'v' is the first argument of the eachEntry method. The syntax was probably inspired by the enhanced for loop but perhaps the reverse order (for eachEntry(v : int i)) would have been more logical.

Brian said...

If I declare a "for" method which takes no argument except for the closure, I can invoke it as 'for myMethod(Object p:) {...}. Should the colon really be required? The prototype compiler says it is.

Zdeněk Troníček said...

Hi Brian,

probably no. Thanks for the comment.

Dribeiro said...

Extended for (what is more formally called abstract iteration mechanism) is so usefull, and so old (Smalltalk had them back in the 80's).

I made a project called Fluent Javawhich brings down the power of Google Collections, Hamcrest and Fork Join CommonsOps to make such abstract iteration mechanisms easier on java, even though it still lacks real closures.