ceylon/ceylon-spec — Issue #54: Syntax for inline functions and objects
Author: gavinking
Created: 2011-11-20 17:17:58+00:00
State: open

Something we need to decide as a community, and relatively soon, since this is one of the first things we need to implement after delivering M1 is the syntax for inline functions and, optionally, inline objects.

### We already have this feature for named argument lists

Now, note that we already have one very nice way to do inline functions and objects:

value adults = people.filter {
function by(Person p) {
return p.age>18;
}
};

And:

text.addListener {
object listener satisfies TextListener {
shared actual onEdit(TextChange change) { ... }
}
};

And for many usecases this syntax is really great. The question is if we need something for use with positional argument invocations.

### Obvious extension to positional argument lists

Now, the most obviously natural thing would be to simply allow an ordinary `function` or `object` declaration, but without the name, for example:

value adults = people.filter(function (Person p) {
return p.age>18;
});

text.addListener(object satisfies TextListener {
shared actual onEdit(TextChange change) { ... }
});

This is the option strongly favored by Stef, and I'm also very sympathetic to it because it's simple, straightforward, super-easy to parse and very regular with the syntax of the rest of the language. The verbosity can be at addressed by supporting an abbreviation in the case of a function which simply returns an expression. Either:

value adults = people.filter(function (Person p) p.age>18);

might work, or at worst:

value adults = people.filter(function (Person p) (p.age>18));

It would also be possible to eliminate the `function` keyword:

value adults = people.filter((Person p) (p.age>18));

But now it's getting less regular, less explicit, and somewhat more difficult to parse.

The real doubt I have about this solution is it is simply not really a very good or natural or easy to format syntax for extending the language with new control structures, which is kinda the whole practical point of inline functions.

### Smalltalk-style arguments

A different option we've discussed is to let you put inline functions *outside* the parens of a positional argument invocation, resulting in an invocation protocol that looks a lot like Smalltalk's.

value adults = people.filter()
by (Person p) {
return p.age>18;
};

text.addListener()
listener satisfies TextListener {
shared actual onEdit(TextChange change) { ... }
};

Again, we can provide an abbreviation for inline functions that just return an expression:

value adults = people.filter() by (Person p) (p.age>18);

I personally find that this results in something that is highly readable once you get used to it. But I can understand if many people find it a lot less familiar/natural.

So this issue is a request for general community feedback.