About the "arrowling" syntax

Thomas Münz, XDEV Software Corp. t.muenz at xdev-software.de
Mon Oct 18 23:11:58 PDT 2010


---------
Sorry I messed up a little by first posting and then registering to the list. After 24h, I'm not sure if/when the first mail will be approved by an administrator, so I send it again. My apologies if this causes a double post eventually.
---------

Hello!

I'm following this list since the beginning but never wrote so far as I don't have much insight in design of language, compiler, VM, etc. (Compiler lectures only scratched the surface back then...)

Now after seeing the draft syntax changed from #(){} to #{->}, I dare to write and deliver some arguments to the formerly pretty controversially received statement that the "->" syntax does not "feel like Java" (which I second).
I know everyone says "we talk about syntax later" and I gladly catch some reprimand for bringing it up once again now ;), still I think it's good timing to intermediately post some thoughts on the issue (and maybe link to it later) that haven't been brought up before, if I'm not mistaken.


A)
In Java Syntax, the let me call it "optical information flow" always goes from right to left
for example:
int doStuff(int i);
int a = 5;

When reading Java source code, one always implicitely reads it as "some input value starts at the right and the result is passed to the left".

When I first read examples for closures (in 2009 or so) like
#{ int x -> x + 1 }
I had to study the short snippets for minutes (really minutes, not seconds) to figure out what they are supposed to mean.
There are two major problems: one is that all of a sudden, the syntax implies a left to right information flow even though it actually works like calling a method and is supposed to eventually pass the result to the left. The other is that what somehow appears to should have to be something like a parameter is visually INSIDE the code block like a local variable instead of before the block in brackets like parameters are.

This structure-breaking dual-reversal of long time constant Java syntax characteristics is very confusing when reading source code and is not only a matter of "just not being used to it yet".


B)
The "arrow operator" itself creates a misleading intuitive impression. The primary association with "->" is "go to" or "goes to".
here -> there
ball -> goal
man -> moon

A good example from mathematics is limes: lim(x -> 0)
"Limes: for x (goes) to 0 ..."

A nice example in programming where this impression is fitting and actually helps reading source code is:
int i = 10;
while(i --> 0){...}
The impression when reading is: "while i goes to 0, do ..."

Quite intuitive as well is the use as a hashmap association:
"blue" -> new color(0,0,255)
Impression: "key "blue" goes to value color blue".


But for Lambdas?
A simple case like
#{ int x -> x + 1 }
might still be somewhat understandable, "x goes to x plus 1". Problem already here is that this implies that the variable x itself is incremented instead of implying "return x+1".

But what about only a little more complex examples like
#{ c -> System.out.println("pippo") };
?
"c goes to print "pippo"". Immediate thought is: "What the?! Can variable c become a print call execution?"

Or
#{ e -> sum += e.size(); }
"e goes to sum add e's size". Impression: "Huh?! Can e become an addition operation? Really?"


Again, look at the comparable math example: f(x) = x+1
"f of x is x plus 1". A much more intuitive impression than f(x -> x+1) could ever be.



C)
All calls of program code in Java have one inherent, consistent, clarifying signal syntax: the "()". Whenever there are "()" after an identifier, either empty or with values passed in it, you know that some code represented by this identifier is called.
The "->" syntax breaks that as well.
The form "#(...){...}" would perfectly fit into the way Java syntax is structured so far. The "{}" signal (only!) the block, the "()" signal that it's callable code and the parameters used. And as a new feature, everyone can quickly understand that because lambdas are some kind of "anonymous code snippets", there is no identifier but instead the "#" before the "()". (and btw: notice the similarity to the clear and well-known mathematical syntax)
The form "#{... -> ...}", on the other hand, causes massive confusion, implying something like "this is some random uncallable code (or is it a hashmap association?) with no parameters that applies some new operation "->" from one part of the code inside the block to the other". Say what? o_0


I hope this explains what (as I understand it) is meant with "it does not feel like Java" and objectively shows why this syntax is so painful to read for many (ordinary ;)) Java developers (like me).

Personally, I strongly appeal to whoever makes the syntax sugar decision to not choose the structure-breaking and very confusing #{...->...} "arrowling" syntax (sounds only half as funny after translating the german word "Pfeilchen" into english :( ) but to choose the perfectly conforming syntax #(...){...} instead.


Thank you for reading




More information about the lambda-dev mailing list