Function types syntax

John Rose John.Rose at Sun.COM
Tue Jan 26 23:41:29 PST 2010


On Jan 26, 2010, at 11:17 PM, Zdenek Tronicek wrote:

> Neal Gafter napsal(a):
>> On Tue, Jan 26, 2010 at 5:17 AM, Peter Levart
>> <peter.levart at marand.si>wrote:
>> 
>>> For example:
>>> 
>>> #(String: int) stringLength = #(String s: int length) label:{
>>> if (s == null) { length =-1; break label; }
>>> length = s.length();
>>> };
>>> 
>> 
>> Rather than introducing two different names and requiring separate
>> statements for assignment and break, you could combine them into one
>> construct:
>> 
>> #(String: int) stringLength = #int(String s) length: {
>> if (s == null) break length =-1;
>> length = s.length();
>> };
>> 
> 
> But then the return type is not present and although the compiler can
> infer it quite easily, for a human being it means worse readability. And
> Java is a language for human beings, isn't it?

The return type is there, between the # and (.  It's just hard to notice!  Having the return type before the arguments slightly helps parsing but I don't think there's much more to be said for it.

On the subject of readability:  The C declarator-like syntax for function types is nobody's favorite (I claim).  The analogy between T(A) and T method(A) { is widely cited, but is also (I claim) widely experienced as a strained analogy.  The reason for this is the usual focus of attention and anchor for informal parsing—the method name—is missing in the former syntax.  In C++0x, the C-style function type syntax is being improved (but not replaced) by a more standard postfix arrow syntax: (A)->R.

Here's a variation of Neal's suggestion using a postfix placement for return types, which is much more standard in languages (e.g., Haskell) that rely heavily on function types:

#(String)->int stringLength;

stringLength = #(String s) int length: {
  if (s == null) break length = -1;
  length = s.length();
  };

Remember that postfix type syntax (with right associativity) reads very well when writing higher-order functions:  (int)->(String)->boolean is clearly something that takes an int, then takes a String later on and produces a boolean.  Compare the stuff people are complaining about, which is the fault of C-declarator-style syntax:  ##boolean(String)(int).  Who's going to read that one correctly!?

Best wishes,
-- John

P.S.  That last example of stringLength could be (I think should be) viewed as the combination of two independent language features, an expression-lambda of the form #(ARGS) EXPR and a block-let-expression of the form TYPE VAR: BLOCK, equipped with a value-bearing break statement: break VAR = EXPR;

With such a block-let-expression, there would be no need to define statement-lambdas of the form #(ARGS) BLOCK, except for void-valued lambdas.



More information about the lambda-dev mailing list