transparent lambda

Neal Gafter neal at gafter.com
Tue Dec 29 08:53:04 PST 2009


On Tue, Dec 29, 2009 at 4:03 AM, Peter Levart <peter.levart at marand.si>wrote:

> 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(); }
>
> ...it 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?
>

The existence of unlabelled yields makes lambdas non-transparent.  The
consequence of that is that refactorings involving lambdas cannot be
performed locally, but may require transformation of the enclosed code.  If
you look at the control invocation form, for example, it is defined in terms
of a lambda expression.  That means that placing a control invocation
statement inside of a lambda would cause any unlabelled yield statements in
the control invocation to go to "the wrong place":

*#() {
  withLock(lock) {
    yield 23;  // oops, yields to the withLock, not the enclosing lambda
  }
}
*

I therefore think the variation in which the label is mandatory is more
promising.  It also has the advantage that we can use a context-sensitive
keyword for "yield".  However, I don't think you've perfected it yet.  Two
issues come to mind:

   1. I'm afraid there might be some ambiguity with function types.
   Specifically, is "#X() Y" the declaration of a variable Y of function type
   "#X()", or is it a lambda labelled X whose value is Y?  Adding mandatory
   parens around the expression part of a lambda expression might help.
   2. I think the labelled yield syntax could be improved.  I suspect
   something like "yield label : expression;" would be easier on the eyes.

If we do this, I would want to drop the block expression from the closures
proposal.  If block expressions are added, they would no longer have
anything to do with closures.

Cheers,
Neal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091229/613bfc16/attachment-0001.html 


More information about the closures-dev mailing list