I don't think it's accurate to say that Java has clunky syntax for closures. Rather, I think it's more accurate to say that Java has no concept of closures. If you want that functionality, you need to roll your own support using existing concepts. C++ before C++11 is the same.
Having never used Common Lisp, I can't say if that's also accurate for your other example.
Edit: ARGH. I forgot string literals in C. So C clearly does have the concept of strings. The problem is that's the only support in the language for that concept. Aside from being able to define string literals, C does not help you with strings at all.
Coffeescript vs Javascript forms a good case study because they largely have the same semantics but with different syntax for key features.
To my mind, the big difference with Coffeescript is the syntax for functions, e.g.
(x) -> x * x
vs.
function (x) { return x * x; }
Coffeescript's syntax eliminates "function" and "return", which significantly lightens the syntactic weight for functions.
I would assume on average that Coffeescripters write significantly more functions than Javascripters (say, for normalization, per bytes of minified JS). This assumption is based on reinforcing selective pressures: Coffeescript encourages programmers to write more functions, and programmers who want to write more functions choose Coffeescript.
Basically, there are some languages whose syntax is so distinctive that it makes a qualitative difference to the experience of programming.
I believe his argument then is that of the following three syntaxes (syntaxen?) to describe closures:
function(x) { ... }
\x -> ...
{ |x| ... }
The differences are so slight as to not be worth quibbling over. Perhaps his point, as yours, is that Java's closure-equivalents are so onerous to employ that they might as well not exist at all. :) {|x| x}
Trying to rewrite this in your syntax as: {x| x}
could cause ambiguity if you had defined a variable x somewhere up-scope: is that a bitwise OR or is it a closure? True, the correct behavior could probably (maybe?) be inferred from context, but that might require Rust to switch from a simple LR(1) parser to an arbitrary-lookahead parser, which would inflate compilation times.In any case, Ruby's hamburger-notation for closures is well-known by this point, and I'd hardly call it novel anymore. In the case of Python's __special__ methods, the whole point was to discourage people from heavily using them in the first place. Making ugly operations ugly, as it were.
Your point that newcomers might be turned off by a language's syntax remains valid, but you've also demonstrated that newcomers lack the context necessary to be aware of the tradeoffs necessary in language design. But hey, tough shit for language developers, huh? Yes, tough shit indeed. Languages must be familiar enough to attract people, but they must also be sufficiently expressive enough to retain the interest of the people in the community who really matter (the elite hackers and the devoted evangelists), while at the same time seeming novel enough to justify switching away from whatever language you were previously using in that domain.
TL;DR: It's a thorny issue, and simply saying "syntax matters" is an unjust simplification. :)
Java definitely has no syntax for closures, because it has no semantics for function types. It has interfaces and anonymous classes, which you can use to accomplish the same requirement, but the semantics of interfaces are not 100% the same as that of function types. A small example: there's only one function type for a function that takes one int and returns one int, whereas there are infinitely many interfaces you can define to represent that function type and none of them are necessarily interchangeable among themselves.
I think this distinction is important and that this is what the author is talking about when he says "there had better be a way to write a closure somehow!" In Java, there isn't.
For example, C# supports function types, but it can have hundreds of function types (it calls them delegate types) for a function that takes one int and returns one int:
delegate int Func1(int x);
delegate int Func2(int x);
delegate int Func3(int x);
and so on; all these function types are incompatible with one another.I believe the distinctive feature of closures is closing over (hence the name) the outer lexical environment and binding to variables in the outer environment, in such a way that those variables are available during evaluation. Which is exactly what an anonymous class lets you have (so long as locals in the outer scope are declared final).
Java is the refutation, IMO: it does have a way to express a closure, it's just that the syntax (anonymous class) is laborious. You need to wrap up any mutable variables to be captured in final single-element arrays, and your closure type will be a single-method interface, but the expressiveness is there. The syntax just sucks.
The laborious syntax is what stops you from writing what may be expressed in C# as 'foo.Where(x => x.Name.Length > 10).OrderBy(x => x.Name)' in Java. The equivalent, even using the smaller Javascript syntax of 'function(x) { return x.name.length > 10; }', is tedious. The (current) Java syntax is just silly.
The syntax "weight" of a feature matters. Syntax that's light and unobtrusive invites use. Syntax that's large and clumsy dissuades use, to the point that whole libraries may not come into existence, not because of a lack of expressiveness in the language, but because of aesthetic ugliness.
Lisp has an out here because of macros; almost everything is equally ugly. Many people appear to consider this base level of ugliness unacceptable; others may see it as a flaw of Lisp, because the very malleability of the syntax makes it harder to encode implementation costs in the form of the program.