|
|
||
Rémi Forax's BlogJanuary 2008 ArchivesYet another closure proposalPosted by forax on January 16, 2008 at 03:39 AM | Permalink | Comments (16)Everybody comes with its own closure proposal, why not me :) Unlike BGGA, CICE, or FCM (not entirely sure about FCM), i don't like the fact a closure is an instance of a class that implement a method. I prefer the John Rose's vision, closure are at runtime method handler on autonomous block of code. There is another thing I don't like in the current BGGA proposal: its syntax of function type, {int,int=>int} is not enough Javaish for me. My proposal comes with a new way to declare a function type I've separated my proposal in three parts:
Function types declaration A function type is declared using the 'almost' keyword function.
// function types declaration
class Ops {
// function are basically like typedef
// top-level functions are illegal
function <T> int comparator(T value1,T value2);
// here function is not a real keyword, the compiler
// recognize it as a keyword only in this construction
function <E> void block(E element);
// in the function below, E can be instantiated to any
// object types or any primitive types,
// it works because function are only declaration with no code.
// another function
function <R> R task();
}
How to use function type Function types are types so they can be used anywhere a type can be used except as bound of a type variable or type argument of a type variable.
// usage
import static Ops.*;
class Utils {
// note: comparator<?> is illegal
// (wildcard are prohibited for generics functions because
// they are not needed).
static <T> void sort(List<T> list,comparator<T> comparator) {
...
}
static <T> void forEach(Collection<T> c,block<T> block) {
for(T t:c) {
// invoke is a magic method that execute the block of code,
// a special rule in the compiler is able to infer its
// parameter type.
block.invoke(t);
}
}
}
Closure syntax
Unlike function type syntax of BGGA, i like its closure
syntax so basically my proposed closure syntax is identical.
I have borrow method references from FCM even if
we need to add a special lookup rule (because methods and fields
are not in the same lookup space)
for that in the compiler.
// at calling site
class Main {
static int f(Object o1,Object o2) {
...
}
void g(int value) {
...
}
public static void main(String[] args) {
Ops.comparator<Object> c=Main.f;
// using a primitive type here is legal,
// it creates a block of code that call g()
Ops.block<int> b=new Main().g;
List<String> l=Arrays.asList(args);
Utils.sort(l,c); // ok contravariance
// closure syntax, this syntax allow to specify the block of code
Utils.sort(l,{Charsequence c1, CharSequence c2 =>
c1.toString().compareTo(c1.toString());
});
// function to interface conversion
java.util.Comparator<Object> javaUtilComparator=c;
// it's roughly equivalent to
final Ops.comparator<Object> tempc=c;
java.util.Comparator<Object> javaUtilComparator=new java.util.Comparator<Object>() {
public int compare(Object o1,Object o2) {
return tempc.invoke(o1,o2);
}
};
// closure to interface conversion
java.util.Comparator<String> javaUtilComparator2={String s1, String s2 =>
-s1.compareTo(s2);
});
}
Examples of non-local transfer and local variable mutation.
// this is not allowed in contrast to BGGA.
class NotAllowed implements Ops.block {
...
}
static int counter(Collection<Integer> c) {
int count=0;
// bloc of code (closure) can mutate local variable,
// a function that returns an int is a subtype of a
// function that returns void.
Utils.forEach(c, {Integer i=>
count+=i;
});
return count;
}
static boolean startsWith(Collection<String> c, String prefix) {
// closure with non local tranfer,
// moreover prefix doesn't need to be final
// because this is not an interface conversion
Utils.forEach(c, {String s=>
if (s.startsWith(prefix) {
return true; // doesn't compile ambiguous
contains.return true; // ok
}
});
}
}
I wait your comments,
| ||
|
|