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 > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss