How would shallow generators compose with lambda?
Brendan Eich
brendan at mozilla.com
Thu May 14 12:38:21 PDT 2009
We still have open controversy over lambdas, if I recall correctly.
Separate thread, but I wanted to confirm that there is disagreement on
completion value being the implicit return value, at least. Some
strawman syntax for explicit result value was mooted.
I also seem to recall some folks (Waldemar in particular) thinking
that lambdas are redundant, and also potentially confusing to average
users precisely *because* of Tennant Correspondence being two-edged in
languages that have statements as well as expressions. The question
for naive readers is: "return" from what? The answer proposed is
always from the nearest enclosing function (ignoring return to label),
but some may stop at the nearest enclosing lambda, and resulting bugs
might hide in plain sight.
On May 14, 2009, at 10:25 AM, Mark S. Miller wrote:
> A return in a lambda returns from the immediately containing function
> activation, so long as that function activation is still active. If
> the containing function has already returned, then a postponed attempt
> to return from it again will fail[1], presumably with a thrown error.
> This applies as well to break, continue, labeled break, labeled
> continue, and labeled return if we introduce such a thing. What
> happens to a postponed 'yield'?
Same thing: yield is very much like return, except that the activation
is not deallocated because the generator-iterator g, created by
calling a generator function f that contains yield expresssions, which
was invoked via g.next(), g.send(v), or g.throw(e), holds a strong
reference to that activation for generator function f.
So a lambda that tries to yield from a deactivated function that
encloses it should fail with a big fat exception, same as for return.
> Also, does it make as much sense to
> introduce a labeled yield as it does to introduce a labeled return?
Return to label, aka "escape continuations", are motivated largely by
the expression-oriented lambda proposal with its final expression
evaluating to the return value, for working around the consequent lack
of "early returns".
Note that return to label as proposed works in any labeled statement,
and does not require a lambda to surround the return. It works via TC
in lambdas just as return does. The motivation via lambda having
implicit return of completion value is what connects the return to
label and lambda proposals.
In this light, yield to label is plausible, although the "early/
exceptional return from lambda" motivation is missing in the sense
that you can write yield expressions in larger expressions -- you
can't use return in the middle of an expression. But yield to label
could be just as useful as return to label.
The syntax works when the yield expression forms a complete expression
statement:
yield : expr;
but it requires parenthesization in the middle operand of the ?:
ternary operator.
Indeed the low-precedence (same as assignment) nature of the yield
unary caused JS1.7 to follow Python in requiring parentheses around
yield expressions in lists: in comma expressions and actual parameter
lists (although we diverged from Python by allowing an unparenthesized
yield expression as the last actual argument in a call or new
expression's parameter list -- Python requires foo((yield bar))
instead of foo(yield bar)).
/be
More information about the es-discuss
mailing list