Claus,
Thanks for the suggestions. Let me see if I can summarize them and respond
briefly:
* functions with expression bodies
This was proposed for ES4 and implemented in SpiderMonkey. I believe there are
some unfortunate ambiguities in the grammar that came up, and I think they've
been treated as moribund. But I love them, and would love it if we could find a
way to bring them back in a way that didn't break the grammar.
* using @ for infix function application
I'm pretty skeptical. I don't see it solving any major problems. The @ sigil is
wanted for many other purposes, so I'm loath to give it up for something that
isn't incredibly compelling.
* curried function definitions
This seems potentially do-able. I don't think there's necessarily huge demand
for it, but I'm cautiously open to the idea. We'd have to think through the
consequences for the grammar pretty carefully.
* functions with expression bodies using => as a separator
Now we're in bikeshedding territory. At the risk of upsetting people, I just
have to say that I don't have enough time in my life to participate in more
es-discuss mega-threads on surface syntax.
* making nested callbacks better via all of the above
I think this is a deeper problem that can't be solved with cosmetics. This is
why I've worked on generators as a good solution for the nested-callback
problem.
Dave
On Apr 8, 2011, at 3:42 AM, Claus Reinke wrote:
> In my previous post, I suggested tail nests as a profitable target for
> reducing reducing parens and braces that distract from common code patterns.
> I made two concrete suggestions, to
> make both braces around function bodies and parens around
> function applications optional.
>
> The combination of both suggestions would allow to reduce
> the nesting of parens and braces in tail nests, such as nested callbacks
> (function definition nested in function application
> argument nested in ..). For the running example, this was
> successful, but rather odd looking - it should be possible
> to do better.
>
> So I would like to modify those suggestions, to bring them more in line with
> Javascript practice and Harmony directions.
> As a bonus, the modified suggestions simplify another common
> case of nesting, namely curried function definitions.
>
>> [mnemonic summary of old suggestions, to be modified]
>>
>> Suggestion 1 (optional braces around function bodies):
>> '(function (..) ..)' may be used instead of 'function (..) {..}'
>>
>> Suggestion 2 (optional parens around function applications):
>>
>> '(f @ a1, .. , an)' may be used instead of 'f(a1,..,an)'
>
> Suggestion 2 is especially problematic if the argument list
> has more than one component: the hope was that we might later get rid of the
> commas as well, assuming that
> argument lists are argument tuples, which could become individual arguments
> by currying. However, I've come to think that this underlying assumption does
> not fit Javascript:
> With optional arguments and unbounded lengths, argument lists are really
> argument arrays - they do not stand for multiple arguments (Javascript has
> curried functions for that), they each stand for a single argument with an
> unspecified number of components. We just use them for multiple arguments
> because
> curried function definitions are so awkward.
>
> Harmony changes, such as formal parameter destructuring and spreads, will
> remove the differences in feature sets between
> argument lists and arrays, making it possible to replace
>
> 'f(a1,..,an)' and 'function f(a1,..,am) {..}'
>
> with
> 'f([a1,..,an])' and 'function f([a1,..,am]) {..}'
>
> at which point the parens will be redundant and each argument
> list can be a proper array (dear arguments: I want my syntax back!-). So this
> part is well in hand already, and trying to break up those argument list
> arrays in other ways would go against the direction Harmony is taking.
>
> Also, the language already provides for curried function definitions and
> applications, they just don't get used much
> yet. Curried applications are easy, but curried definitions
> happen to be very awkward, syntactically.
>
> My modified suggestions take both curried functions and
> argument lists as arrays into account, so they do a little less work on
> applications, making better use of existing syntax, and a little more work on
> definitions, hoping to give curried definitions a lift.
>
> What I'd like is to be able to replace the horrible
>
> function (..) { return function (..) { .. }}
>
> with the shorthand notation
>
> function (..)(..) { .. }
>
> (and, similarly, '#(..)(..){..}' instead of '#(..){ #(..){..}}')
>
> giving curried function definitions the same short syntax
> as curried function applications. This shorthand makes it
> obvious that each argument list really is just a single, complex argument to
> the function. There are a few obvious problems which would have made this
> difficult before
> Harmony:
>
> - using the outer function's arguments pseudo-array
> in the inner function's body;
> Harmony's spreads avoid that problem entirely.
>
> - using the outer function's 'this' in the inner function's
> body (the shorthand notation no longer has an outer
> function body in which to rename 'this' to 'self');
> this is being addressed in other threads here, so Harmony is
> likely to offer at least one solution
> (optional naming for the implicit argument 'this').
>
> - if the formal parameters can consist of multiple
> argument lists, the beginning of the function body
> is no longer unambiguous without those braces;
> to address this, we need an explicit syntactic marker
> at the boundary between arguments and body;
>
> from the archives, it seems that '=>' has been a
> fairly popular suggestion (usually instead of a prefix
> marker), so I'll adopt that, but without removing the
> prefix marker, be it 'function' or '#'.
>
> Which results in the following modified suggestions
>
> // --------------------------------------------------
> // Modified suggestion 1 (function definitions):
> 1a (curried definition shorthand)
> function (..)(..) { .. }
>
> may be used instead of
>
> function (..) { return function (..) { .. }}
>
> for arbitrary nestings.
>
> 1b (function bodies)
>
> (function (..)..(..) => ..)
>
> may be used instead of
> function (..)..(..) {..}
>
> (the outer parens are _not_ part of the function definition
> syntax - they indicate that the source context delimits the
> function definition from the outside: if the construct in
> which the definition is nested ends, so does the definition)
> 1c (ASI needs to know about 1b's implicit block endings)
>
> // --------------------------------------------------
> // Modified suggestion 2 (function applications):
>
> (f @ x)
>
> may be used instead of
>
> f(x)
>
> (the outer parens are _not_ part of the function application
> syntax - they indicate that the source context delimits the
> function application from the outside: if the construct in
> which the application is nested ends, so does the application)
> '@' is now just a left-associative infix operator (same precedence as
> function application), so
>
> (f @ x @ y @ z)
>
> is
>
> (((f @ x) @ y) @ z)
>
> which is
>
> f (x) (y) (z)
>
> (ideally, infix function application would just be juxtaposition,
> ie, the parens around single-component argument lists
> would be optional, without requiring an explicit operator)
>
> // --------------------------------------------------
>
> The effect on our running example, in terms of removing
> redundant parens and braces, can be similar, but that
> now needs support from the libraries: they would need to
> curry their API functions so that the callback becomes a
> second, separate argument (instead of the last component
> in a single complex argument list).
> (mainWindow.menu("File") @ function(file) =>
> file.openMenu @ function(menu) =>
> menu.item("Open") @ function(item) =>
> item.click @ function() =>
> mainWindow.getChild(type('Window')) @ function(dialog) =>
> ...
> );
>
> // Note: since function definitions extend as far as possible,
> // to the closing paren here, the inner '@' are unambiguosly
> // nested
>
> These modified suggestions are simpler, more in line with
> Harmony's directions, and help to reduce the syntactic noise
> for two common sources of nesting: curried definitions and
> definitions as callback arguments.
>
> Comments, please?-)
> Claus
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss