transparent lambda

Peter Levart peter.levart at gmail.com
Mon Dec 28 03:38:30 PST 2009


On Sun, Dec 27, 2009 at 9:28 PM, Neal Gafter <neal at gafter.com> wrote:

> Your block expression is syntactically ambiguous with an array initializer,
> and probably also ambiguous with Coin's proposed collection literals.
>

Oh yes, array initializer. But only if *Block*Expression vs. *
ArrayInitializer* is empty, isn't it? Since empty BlockExpression is
meaningless, the syntax could be fixed from this:

*BlockExpression**:*
*        Block*

*    Block:*
        {* BlockStatements**opt* }


to something like this:

*BlockExpression**:*
        {* BlockStatements* }



The yield syntax does not look good to me.  I think it would be hard to
> notice, scanning the code, that there is an early termination, and the
> target of the early termination is also hard to notice.  Instead of writing
> this
> *
> *
> *#int(int,int) zeroesComeFirst = #(int x, int y) {*
> *    if (x == y) return 0;*
> *    if (x == 0) return -1;*
> *    if (y == 0) return 1;*
> *    return (x < y) ? -1 : 1; }*
>
> one would write
>
> *#int(int,int) zeroesComeFirst = #(int x, int y) {*
> *     if (x == y) =0;*
> *     if (x == 0) =-1;*
> *     if (y == 0) =1;*
> *     =(x < y) ? -1 : 1; }*
>

I agree about the hard to notice objection (vivid colouring in IDE would
help here). That was an attempt to not introduce a new keyword. With a
keyword like "yield" it would be no different from "return" - for the price
of new keyword, of course.

But what did you mean with: "and the target of the early termination is also
hard to notice"? Did you mean in situations when BlockExpression was used as
part of other expressions - not as the expression in "expression lambda"?
When used in expression lambda, the target of early termination has the same
notice-ability as the target of early termination (return) in CfJ's
statement lambdas. In other situations, nesting normal statement blocks and
expression blocks would lower notice-ability of early termination target -
to a much lesser extent that same is true for nesting CfJ's statement
lambdas.

Maybe BlockExpression, as suggested, doesn't have that much value in itself
- only in company with expression lambdas. Maybe there should be two forms
of lambdas: expression lambda and statement lambda. But:


>
> Worse, your proposal breaks transparency.  That is explained in detail in <
> http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html>,
> ...


Being able to return early from a lambda has inherent conflicts with lambda
transparency since it targets lambda's bounds - lambda becomes visible. In
spite of that, I think (but I may be persuaded to think otherwise) that it
is possible to combine transparency to other constructs and "additional
features" like early return (that break Tennent's principle) in one form,
provided that those additional features use unique statement forms -
re-usage of same statements (return, break, continue) among different kinds
of constructs is not allowed.

That single lambda form is mostly transparent. Non-transparency is obvious
only when you nest same kind of constructs - features that target those
kinds then select the innermost one. That's true with loops and methods in
Java today - they are not transparent to their own kind.

I have read your blog (above link) where you say: "while *existing* code
doesn't use this new statement form, once we introduce it into the language
we should expect people to start using it in *new* code. And once they do,
any code that includes this statement cannot be wrapped in a closure without
changing its meaning. Once we identified the bad smell this way, it wasn't
hard to come up with realistic examples where it gets in the way of using
the language."

What realistic example did you have in mind? Does it get in the way of using
the language any more than when you try to use nested loops with unlabeled
break/continue?

Regards, Peter


More information about the lambda-dev mailing list