Skip to main content

Closure Syntax

Posted by alexwinston on February 27, 2008 at 11:00 AM PST

I would like to preface this entry with the fact that I am not suggesting a concrete syntax in the examples below. I am merely using the examples as talking points and illustrations of what I consider to be the "syntactical spirit" of the Java language.

I will be the first to admit that syntax is quite subjective and typically creates consternation within the context of programming specifically. However, there is also what could be considered the "syntactical spirit" of a language and in this regard I feel that BGGA and FCM have ostensibly missed the mark.

The most concerning illustration of this is from the FCM proposal itself, "Finally, it should be borne in mind that the syntax is relatively unimportant - the semantics of the proposal are what really matter". This statement in my opinion is one reason the Java community has been adverse to embrace the proposed changes. Inherently people are averse to change but if change is inevitable it should be familiar. Syntax is very important and can in some ways inhibit or foster the use of new functionality and to suggest that either proposal is familiar or similar to Java in most regards would be dubious at best.

I would like to state the fact that I do not take issue with the semantics of either proposal simply the syntax of each. That being said let me provide examples from each proposal.


    {int=>int} plus2 = {int x => x+2};

I would like to ask honestly who in there right mind thinks this is consistent within any stretch of the imagination with the spirit of the Java language? Yes Java is verbose, yes it can be cumbersome, but it is not this. Now I am not going to purport to know the best syntax but wouldn't something like the following be more in line with the Java language?

    int plus2(int) = int (int x) { return x + 2; };

I have read similar statements from a number of individuals within the community and the discussion invariably turns to semantics while overlooking the importance of syntax.

The following example is even more disturbing.

    public {T => U} converter({=> T} a, {=> U} b, {T => U} c) {  
        return {T t => a.invoke().equals(t) ? b.invoke() : c.invoke(t)}; 

Not only that but something like the following appears more terse.

    public <T, U> U converter(T a(), U b(), U c(T)) {
        return (T t) { a().equals(t) ? b() : c(t); };

Again this is just a talking point, and might very well not be syntactically equivalent, but as an avid supporter of the Java language I cannot support the BGGA syntax in any capacity.


Unfortunately FCM is not much better, they did put some thought into the syntax but it only makes for a marginally more spirited alignment.

    public class MyClass {
        public void process() {
            (void(String)) example = #(String message) {
                Logger.log(this, message);
            example.invoke("Logged message");

It seems there are unneeded parentheses and calls to invoke. Something like the following seems more appropriate although less terse.

    public class MyClass {
        public void process() {
            void example(String) =  void (String message) {
                Logger.log(this, message);
            example("Logged message");

One thing I am not sure I understand either is the need for the invoke(...) call. Is there a particular reason function(...) could not be used over function.invoke(...)?

All that being said I am not trying to create controversy. I am merely encouraging a reevaluation of the syntax proposed by both BGGA and FCM. This, in my opinion, will be as critical to the success of closures as semantics. It almost seems as though we should refocus BGGA and FCM on the semantics and create competing proposals for the syntax. I do realize that the syntax of each proposal follows the semantics, form follows function, but that is a moot point until we have something more palatable.

Related Topics >>


Closures in BGGA can complete in two different ways, one of which already uses the return keyword, so if you use return as you suggest you also have to suggest some syntax for the other case. Java has benefited from being relatively easy to parse and thus build tools, as compared with C++ which is a parsing nightmare. We need to be cautious in suggesting syntax which might break this property.

You can't use the syntax function() in place of function.invoke() because in Java you can have a method and variable with the same identifier but are completely unambiguous.

Focussing on invoke demonstrates a problem of focus. Really, it doesn't matter how the code to implement an algortihm looks. That's all shoved away into some library somewhere. What's important is all that code that uses the library. Spending syntax complexity on making library code use less symbols is a waste. And because it is used infrequently used, it wont actually be so obvious that something different is going on.

Eh, i just remembered a case where if the syntax i propose could be implemented, it would get quite ugly. But only if the developer is insane i imagine. to invoke the function that returns a function and invoke that function. function()(); or even, to get more insane: function()()(); ad infinitium

Hear, hear! I've been following the closure proposals for awhile and that same sentence in BGGA's description made me extremely uneasy. It's like a developer saying "we'll slap a UI on it when it's done". I don't think, at this point, that any of the proposals should be adding new operators to the language, for one thing. Any proposal that uses => or # in its syntax is a non-starter. I like hlovatt's suggestions as well as the ones presented in the post, and I suspect both could be refined. (All those "call"s and/or "invoke"s are rather unfortunate as well. Can't the parser disambiguate it most of the time, and only force the explicit usage when necessary?)

In my proposal Clear, Consistent, Concise Syntax (C3S):

You use the method keyword which I think is more Java like (unabbreviated keyword). The examples, in order, in C3S are:

// In example below MethodX are generic predefined interfaces in java.lang, they have a call method // Keyword method, creates a MethodX // () when calling a method are optional if unambiguous // return is optional // type is optionally inferred in variable and field declarations // ; is optional before a } final plus2 = method( Integer x ) { x+2 }; public Method1<U, T> converter( Method0<T> a, Method0<U> b, Method1<U, T> c ) { method(T t ) { t ) ? : t ) }; } public void process() { final example = method( String message ) { Logger.log( this, message ) }; "Logged message" ) }

With regard to non-local returns I have suggested in the C3S proposal either disallowing them (they have few use cases) or using named returns if people really want them.

I think C3S are clearer, what do others think?

Or even forbidden if you're trying to impose a standard.

Cay, are you worried about reading this? int pre2(int) function(){ return null; }

For between that and

{int => int} function(){ return null; }

There is no appreciable difference to me. Actually the 2º one looks a little worse.

However how about you make the name optional in some circumstances: Better or worse?

int (int) function(){ return null; }

I think the discussion about problems of aliasing between aFieldName variable and aFieldName() function are just crap. Just do some compiler wrangling, make the function have a aditional prefix in compiled form. Or if your issue is looking up, just make function names after the corresponding field name, so when ever the syntax check sees aFieldName() it checks that there is indeed a function field name. Heck make () part of the name, and make it a special statement. To do aFieldName.invoke() is plain moronic.

I think int plus2(int) is a non-starter. Don't entangle the declared variable within fragments of the type. That approach has been thoroughly discredited after it made a disastrous appearance in C/C++. Try writing a function that yields an int=>int function using your syntax...