PROPOSAL: fold keyword (original) (raw)

Gabriel Belingueres belingueres at gmail.com
Tue Mar 10 07:01:20 PDT 2009


Hi,

First, thanks you for the input.

The main issue I wanted to avoid was creating new objects/anonymous classes for executing the body of the loop, acting on the elements of the collection. The ideal case would be to have closures in place, but since this was not possible, using the current code in the for body was my second choice.

There might be two benefits on doing it this way though, assuming the following simple example:

Integer sum = 0; for (Integer n : list) sum += n;:

  1. In the current way, you want to compute a unique value from the collection, but you are accumulating on the same variable unwanted values of the target result, meaning this could potentially introduce bugs if in the middle of the iteration an exception is thrown, leaving your variable with garbage. With the fold version, the resulting variable is scoped to the for loop, therefore an exception doesn't touch the final result variable.

  2. In the current way, you can't assign the result to a "final" variable, which is something a programmer might want to do:

final Integer sum = 0; // wrong for (Integer n : list) sum += n;

so you need to introduce the code inside a new method:

final Integer sum = sumAll(list);

private Integer sumAll(List l) { Integer sum = 0; for(Integer x : l) sum += x; return sum; }

with the fold keyword:

final Integer sum = fold(Integer n : list; Integer s = 0) { s += n; }

You are right in that the current for is somewhat simpler, and maybe this is all because I don't like to see "break" or "continue" in loops, but I think that the idiom would be a little more readable when you introduce the break condition in the loop. For example: sum all elements in the collection until the first prime number is found:

Now:

Integer sum = 0; for(Integer x: list) if (isPrimeNumber(x)) break; else sum += x;

with fold:

Integer sum = fold(Integer x : list; Integer s = 0; isPrimeNumber(x)) { s += x; }

Regards, Gabriel

2009/3/5 Joshua Bloch <jjb at google.com>:

Gabriel,

This doesn't seem compelling. Here's your simple example: // sum all numbers in the list Integer sum = fold(Integer n : list;     // iterating collection element n Integer result = 0) { // Where to accumulate the result, and the initial value result += n; }; } And here's how it looks today (with no change to the language or libraries): Integer sum = 0; for (Integer n : list) sum += n;

Here's one of your complex examples: // returns a new collection with the salaries of the employees not on vacation  List salaries =  fold(Employee e : emps; List newList = new ArrayList()) {  if (!e.onVacation()) {  newList.add(e.getSalary());  }  } And here's how it looks today: List salaries = new ArrayList(); for (Employee e : emps) if (!e.onVacation()) salaries.add(e.getSalary()); To my eyes, the current version is clearer as well as shorter. Josh



More information about the coin-dev mailing list