But one thing I do know about the BGGA closures proposal is that I don't like the syntax. Take the example in Weiqi Gao's recent Java Quiz:
public class Fib {
private static {int=>int} fib = { int n =>
n==0 ? 0 :
n==1 ? 1 :
fib.invoke(n-1) + fib.invoke(n-2)
};
public static void main(String[] args) {
System.out.println(fib.invoke(6));
}
}
To me, this is just hard to read. The whole "=>" thing seems like a weak attempt to create a new lexical character and is too visually similar to ==, >>, etc. I also don't like the 'invoke' syntax. I was discussing this with Weiqi the other day and came up with a syntax that I like better.
public class Fib {
private static {int # int} fib = { # int n #
n==0 ? 0 :
n==1 ? 1 :
#fib(n-1) + #fib(n-2)
};
public static void main(String[] args) {
System.out.println(#fib(6));
}
}
Note that you could also invoke fib like this:
System.out.println(#Fib.fib(6));
I wonder what other people think of this alternative?
8 comments:
re: =>. My guess is that this is inspired by Scala. See the PDF of Tim Dalton's slides (look for functions):
http://tinyurl.com/yunx8t
Odersky was involved in the early Generics prototype and I wonder if that is the link. (This is pure speculation on my part. I don't know if he even espouses closures.)
I was originally put off by => but now like it. I prefer it over #. Using -> versus => is an interesting debate.
Because fib is a function, I think invoke is quite readable. There is enough subtlety with closures! ;-)
The FCM proposal shares some overlap with your ideas; not sure if you've seen it. I like FCM's syntax except for their placement of the return type. I understand their reasoning, just don't like it.
Well, to be honest, the BGGA seems more readable and less verbose than the # notation you propose ... especially for the # before int n, which seems ... out of phase.
Isn't this similar to the Ruby notation once you replace the # by the | ?
Cheers.
Yes, the syntax is similar to Ruby's. I don't like Ruby's vertical bars much (probably due to my background with Unix shells and pipes). But I like the concise syntax of Ruby's closures quite a bit. I find it easier to locate the arguments to the block when they are 'bracketed' by characters.
I don't like 'invoke' because it's so long. I suppose an alternative would be to treat closures as if they were functions and just say fib(12). I don't know what this would mean for parser complexity. I really, really don't like 'invoke'.
I just took a quick look at the FCM proposal. I may be misunderstanding it but it seems that it's semantics/mechanisms are very different than BGGA. At first blush I don't care much for the direction they seem to be headed. I'm essentially proposing an alternate syntax for BGGA.
In C3S:
http://www.artima.com/weblogs/viewpost.jsp?thread=182412
The example is:
private static Method[Integer,Integer] fib = method(int n) {
__n==0 ? 0 :
__n==1 ? 1 :
__fib.call(n-1) + fib.call(n-2)
};
Based upon the URL provided for C3S, I was unable to find any syntax that looks like that specified. Can you point me at an explanation of what this syntax means?
@Brian,
In my example I swapped angle brackets for [] and used _ to indent because of posting convenience. Method1[Integer,Integer] is a generic interface that has a method call. The keyword method introduces anonymous method definitions.
I am no expert either but it seems like you want a strongly typed instance of a Method object, for that to be possible you need to define the return type and passed arguments.
public class Example
{
public static final void args(String[] args)
{
Example example = new Example();
List numbers = new ArrayList<Integer>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
// Calling a method with a closure
Boolean[Integer i] numberEqualsThree = new Boolean[Integer i]{ return i == 3; };
example.methodThatTakesAClosure(numbers, numberEqualsThree);
// Calling a closure which does recursion
final Integer[Integer i] fib = new Integer[Integer i]{ return n==0 ? 0 : n==1 ? 1 : fib(n-1) + fib(n-2)};
Integer result = fib(8);
// Calling a closure with recursion that knows about itself
Integer result = new Integer[Integer i]{ return n==0 ? 0 : n==1 ? 1 : this(n-1) + this(n-2)}(8);
}
public Integer methodThatTakesAClosure(List<Integer>>integers, Boolean[Integer i] aClosure)
{
for (Integer integer : integers)
{
if (aClosure(integer))
{
return integer;
}
}
}
}
Post a Comment