transparent lambda

Peter Levart peter.levart at
Tue Dec 29 04:03:15 PST 2009

On Monday 28 December 2009 17:38:55 Neal Gafter wrote:
> Loops are not an abstraction mechanism.  Loops are supposed to change the
> execution of the code within them, by repeating their execution.
> Nevertheless, there are two syntactic forms of loops: transparent loops and
> non-transparent loops, just as we've proposed two forms for lambda
> expressions.  The transparent ones are the ones that use a label.  You can
> nest these any way you want, and as long as you keep your labels unique and
> use labelled break and continue, nesting does not change the meaning of the
> statements that are placed within a loop.  Your proposal, while purporting
> to introduce transparency, actually remove the transparent (expression
> lambda) form by making it non-transparent.

My proposal, with mentioned flaws, was an attempt at merging the two forms of lambdas into one. I aggree that the idea of a block expression with early yield has the problems and is not so valuable per se. But, as you say below, merging two forms into one is worth exploring.

Let me explain what I mean by two forms. Not syntactical forms. I now think that two syntactical forms are actually useful. The expression lambda form is a very useful syntactical shortcut. I mean the transparent/nontransparent form defined by different syntax. I think worth exploring further is how to make statement lambda transparent, so that the meaning of statements in statement lambda would be the same as the meaning of statements in 0.6b block expression. 0.6b block expression might then lose the value and control invocation syntax could be defined in terms of statement lambda.
> One approach that could be used to have lambdas that are both transparent
> and allow early return would be to introduce some kind of labelling
> mechanism.  The labelling mechanism could either be part of the lambda
> expression syntax or the block expression syntax.  Then, introduce a
> labelled return statement, possibly something like this:
> *return label : expression;*
> I haven't found a way to do this that feels right, but it is an approach
> worth exploring.

What about the following syntax (another use-case for optionally naming the lambda - the other being predictable serializable class names):

#int(int, int) adder = #Adder(int a, int b) { yield#Adder a + b; }

When wrapped in lambda and executed:

#int(int, int) adder = #Adder(int a, int b) { #() { yield#Adder a + b; }.invoke(); } retains the meaning.

The we can have two variations:

- yield has a mandatory label, therefore the referenced lambda must have a name. In that case 0.6b block expression still has it's value by providing a kind of "unlabeled yield" as the last expression - though not an early yield.

- yield has an optional label. The set of yields that belong to particular lambda (and define the return type) is then the union of labeled yields with label being equal to the lambda name and the unlabeled yields for which the lambda is their innermost lambda.

Regarding the use of unlabeled yield: Should we be pragmatic? If one is not concerned about serializing lambdas and is writing lambdas that will never have to be simplified by introducing nested lambdas, why should (s)he be forced to label each lambda and only use labeled yields? The distinction is: enabling transparent lambda vs. supporting only transparent lambda. Would unlabeled yields cause to many problems?

Regards, Peter

More information about the closures-dev mailing list