return when desugaring to closures

Mark S. Miller erights at
Mon Aug 25 12:26:24 PDT 2008

On Sun, Aug 24, 2008 at 12:31 AM, Brendan Eich <brendan at> wrote:
> On Aug 23, 2008, at 10:23 PM, Mark S. Miller wrote:
>> On Sat, Aug 23, 2008 at 8:36 PM, Peter Michaux <petermichaux at>
>> wrote:
>>> (function (x, y) {...})(a, b)
>>> would be quite welcome. It is clear people like this pattern and it is
>>> confusing when the formals and actuals are more than a couple and more
>>> than a couple lines apart.
>> As Lars pointed out, using ES-Harmony's optional parameters with
>> defaults, you can keep the actuals and formals together by writing
>>    (function (x=a, y=b){...})()
> Good point, although I say it's no fair to talk desugaring but then
> special-plead extensions into the mix. Optional parameters are not just
> syntax, especially in their evaluation and scope rules.

Sorry I hadn't responded to this earlier.

I am not a "no new semantics -- desugaring only" absolutist; just
close. I recognize there are tradeoffs. When new semantics has a high
enough benefit and a low enough cost when compared with alternatives,
then we should add new semantics. Of course, there are no objective
measures here, so all we can do is to strive to set very high bars and
to err on the side of simplicity.

Optional and (especially) rest parameters pass my subjective test.
They are new semantics that I believe should appear in Harmony. As you
have pointed out, "new Date(args...)" demonstrates that they are not
equivalent to any desugaring.

>> Given this, I don't see any need for let blocks or let expressions
>> that justifies their added complexity.
> They may indeed not be justified on complexity grounds, but I'd like to
> argue against your reason:
>> Especially since, as we've
>> established, they can't be added as sugar that desugars to anything
>> like the above code.
> The above code has issues in the ... you didn't show. |this|, arguments
> aliasing, the arguments name shadowing an outer arguments that would
> otherwise be visible, e.g., in a JS.1.7 let block, and probably other
> compatibility burdens I'm forgetting atm, all make it undesirable to map a
> binding form with explicitly delimited scope and let-not-letrec rules for
> initialization (JS1.7's let block or let expression) onto a lambda-call.

What I'm saying is that, given optional args, the let expression and
let block no longer have enough differential benefit to justify the
cost of adding them. I'm not invoking any absolute principles. I'm
arguing about relative costs and benefits.

> So let blocks and expressions indeed can't desugar -- that could be the end
> of it. But that argument does not prevail in all cases,

Of course. It depends.

> particularly in the
> case of let declarations (let as the new var), which I believe you support.

I do indeed. The benefits of this feature are overwhelming.

> My counter-argument is this: If the existing semantics have their own
> complexity problems, even though we are stuck with them for compatibility,
> we could make the language better overall, and some day hope to move
> programmers off bad old forms, by adding some carefully designed better
> forms. Desugaring is not the only good to consider. Reforming the core
> semantics while keeping compatibility may require new runtime semantics.

Agreed in principle. We are even in agreement on many particular
applications of this principle. However, we must strive -- *much*
harder than we have historically -- to keep needless complexity out
and to only admit features whose benefits clearly exceed their costs.

> I agree with you that conserving runtime semantics when adding syntax is a
> good discipline and an appropriate bias. But the lexical scope breaks, the
> extra gewgaws such as |this| and arguments that afflict JS functions should
> not be ignored.

Rest assured that I am not ignoring them. They have been a source of a
great deal of pain. I expect they will continue to be ;).


More information about the Es-discuss mailing list