simple shorter function syntax

# Trans (15 years ago)

I was reading about the proposed shorter function syntax on the wiki and want to comment on it.

strawman:shorter_function_syntax

I do not see how it is advantageous to using a special symbol, '#'.

Taking the example.

[0, 1, 2, 3].map( #(x) {x * x} )

If the goal is just to be more concise, what is wrong with 'f' as an abbreviation of 'function'?

[0, 1, 2, 3].map( f(x) {x * x} )

Or 'fn', if it seems a little clearer.

[0, 1, 2, 3].map( fn(x) {x * x} )

Heck you could even use 'y' as an upside down lambda if you wanted.

[0, 1, 2, 3].map( y(x) {x * x} )

Any of these seem a much nicer choice than '#', IMHO.

# Kris Kowal (15 years ago)

On Fri, Jul 23, 2010 at 10:08 AM, Trans <transfire at gmail.com> wrote:

[0, 1, 2, 3].map( f(x) {x * x} )  [0, 1, 2, 3].map( fn(x) {x * x} )  [0, 1, 2, 3].map( y(x) {x * x} ) Any of these seem a much nicer choice than '#', IMHO.

While I agree on principle, the real challenge here is to find syntax that will not break existing programs by promoting an existing variable name to a keyword. Otherwise, you'd have to look ahead to the curly brace block to distinguish the variable name from the function keyword. It's been a long time since I wrote a parser of this kind, but as I recall, looking ahead is generally hacky.

function expression: name, argument list, block

Of course, if that approach were taken, the spec might as well forgo having a function keyword at all and use the name or absence of a name to distinguish a named and anonymous function expression. But again, I expect there would be resistance to looking ahead.

Kris Kowal

# Bryan Kyle (15 years ago)

I believe # has the advantage of not being a valid character in an identifier so there won't be any backwards compatibility problems with existing code.

Your suggestions are legal identifiers so it makes the job of the parser harder. The parser would have to look further ahead to be able to tell the difference between an anonymous function and a call to an existing function. That isn't to say it's impossible, but simplicity speaks for itself :)

# Oliver Hunt (15 years ago)

On Jul 23, 2010, at 10:08 AM, Trans wrote:

Hi--

I was reading about the proposed shorter function syntax on the wiki and want to comment on it.

strawman:shorter_function_syntax

I do not see how it is advantageous to using a special symbol, '#'.

Taking the example.

[0, 1, 2, 3].map( #(x) {x * x} )

If the goal is just to be more concise, what is wrong with 'f' as an abbreviation of 'function'?

[0, 1, 2, 3].map( f(x) {x * x} )

Or 'fn', if it seems a little clearer.

[0, 1, 2, 3].map( fn(x) {x * x} )

Heck you could even use 'y' as an upside down lambda if you wanted.

[0, 1, 2, 3].map( y(x) {x * x} )

Any of these seem a much nicer choice than '#', IMHO.

This would require an LL(infinity) grammar as you get ambiguity between a function call and a lambda declaration -- this is solvable with an LALR parser but at substantial performance cost, and in general LALR parsers require a secondary tree walk to validate code in strict mode. Just using an LALR vs LL parser is a very easy way to more than double the time it takes to parse stuff, and that's without all the other optimisations we can do if we know we don't need to look at the full parse tree after validating the input.*

Additionally I suspect that this syntax would behave awkwardly in the presence of automatic semicolon insertion, eg. is f(a) {... a function call followed by an open block, or is it a function declaration? I also suspect that there's plenty of minified code that's perfectly happy to plant something like f(foo) { ... } which would be broken by such a change.

--Oliver

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.
# Bryan Kyle (15 years ago)

On Fri, Jul 23, 2010 at 10:20 AM, Kris Kowal <kris.kowal at gmail.com> wrote:

On Fri, Jul 23, 2010 at 10:08 AM, Trans <transfire at gmail.com> wrote:

[0, 1, 2, 3].map( f(x) {x * x} ) [0, 1, 2, 3].map( fn(x) {x * x} ) [0, 1, 2, 3].map( y(x) {x * x} ) Any of these seem a much nicer choice than '#', IMHO.

While I agree on principle, the real challenge here is to find syntax that will not break existing programs by promoting an existing variable name to a keyword. Otherwise, you'd have to look ahead to the curly brace block to distinguish the variable name from the function keyword. It's been a long time since I wrote a parser of this kind, but as I recall, looking ahead is generally hacky.

function expression: name, argument list, block

You're correct. Once the parser sees the identifier followed by an open paren it would need to parser forward through the tokens until after the closing paren and look to see if it's an open brace. The parser can then determine whether the initial identifier is a call or an anonymous function. As you can imagine the parse would need to have near infinite lookahead since it has to read through an undetermined number of tokens before it can make a decision.

# Alex Russell (15 years ago)

Oliver's right (as usual). Erik and I talked through alternatives like "f" before proposing "#", and the other constraint not mentioned yet in the thread is typability. Yes, "#" requires a shift key on US keyboards, but it's not any harder than that on dvorak and european layouts. "#" (or something like it) seemed a good tradeoff.

On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:

On Jul 23, 2010, at 10:08 AM, Trans wrote:

Hi--

I was reading about the proposed shorter function syntax on the wiki and want to comment on it.

strawman:shorter_function_syntax

I do not see how it is advantageous to using a special symbol, '#'.

Taking the example.

[0, 1, 2, 3].map( #(x) {x * x} )

If the goal is just to be more concise, what is wrong with 'f' as an abbreviation of 'function'?

[0, 1, 2, 3].map( f(x) {x * x} )

Or 'fn', if it seems a little clearer.

[0, 1, 2, 3].map( fn(x) {x * x} )

Heck you could even use 'y' as an upside down lambda if you wanted.

[0, 1, 2, 3].map( y(x) {x * x} )

Any of these seem a much nicer choice than '#', IMHO.

This would require an LL(infinity) grammar as you get ambiguity between a function call and a lambda declaration -- this is solvable with an LALR parser but at substantial performance cost, and in general LALR parsers require a secondary tree walk to validate code in strict mode. Just using an LALR vs LL parser is a very easy way to more than double the time it takes to parse stuff, and that's without all the other optimisations we can do if we know we don't need to look at the full parse tree after validating the input.*

Additionally I suspect that this syntax would behave awkwardly in the presence of automatic semicolon insertion, eg. is f(a) {... a function call followed by an open block, or is it a function declaration? I also suspect that there's plenty of minified code that's perfectly happy to plant something like f(foo) { ... } which would be broken by such a change.

--Oliver

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.

es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# Brendan Eich (15 years ago)

On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:

[Good point about LL(∞) snipped.]

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.

Ollie, was that with browser-side Objective-J compilation, or with the server translating and feeding the Obj-J-lowered-to-JS code to the browser?

I have polled audiences at talks in the last year about shorter function syntax, see first two links at brendaneich.com/presentations. Results mainly for fun but somewhat informative (to me at any rate) were not resoundingly in favor of a new and much shorter keyword to use instead of function.

This was before strawman:shorter_function_syntax was proposed, so I didn't ask the audiences to clap for its # syntax.

People like the expression-closure idea, although syntax needs to be hammered out. See developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)

# Oliver Hunt (15 years ago)

On Jul 23, 2010, at 10:32 AM, Brendan Eich wrote:

On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:

[Good point about LL(∞) snipped.]

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.

Ollie, was that with browser-side Objective-J compilation, or with the server translating and feeding the Obj-J-lowered-to-JS code to the browser?

I believe it was with the browser being passed preprocessed source, but i'll harass them to find out.

I have polled audiences at talks in the last year about shorter function syntax, see first two links at brendaneich.com/presentations. Results mainly for fun but somewhat informative (to me at any rate) were not resoundingly in favor of a new and much shorter keyword to use instead of function.

This was before strawman:shorter_function_syntax was proposed, so I didn't ask the audiences to clap for its # syntax.

People like the expression-closure idea, although syntax needs to be hammered out. See developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)

I personally am not too fussed about the reduced typing -- if people really wanted reduced typing we could simply adopt "" which seems to be the common symbol used for a function.

# Kevin Curtis (15 years ago)

Should the proposed shorter form # desugar to function or a const function: strawman:const_functions

I dislike the verbosity of function - though I can't help feeling # could be used for other ends.

let dict = #{"hello": 4, "world":5}; // it's a hash/dict not an object let arr = #[4,4,5] // typed array - Numbers only - contiguous memory block?

Maybe the verbosity of function is painful when used as an anonymous function. Does the blackslash idea for anon functions (only) work grammar wise:

doIt((x) { alert(x * x) } ); // braces doIt((x) ( x * x)); // parens - no return let myfun = (x) (x * x);

Also, is anything proposed for rationalizing ASI in Harmony.

# Alex Russell (15 years ago)

On Jul 24, 2010, at 9:21 AM, Kevin Curtis wrote:

Should the proposed shorter form # desugar to function or a const function: strawman:const_functions

Regular, plain-old function. No funky return semantics (ala some of the closure proposals), no extra qualifiers. If you want 'em, you can pay for 'em. The common problem "#" attempts to address is the huge verbosity of "function", nothing more.

I dislike the verbosity of function - though I can't help feeling # could be used for other ends.

let dict = #{"hello": 4, "world":5}; // it's a hash/dict not an object

So a new dictonary/map type is interesting, but it's unclear that we really need anything like that until/unless we turn off the "delete" operator.

let arr = #[4,4,5] // typed array - Numbers only - contiguous memory block?

How about we start with the long form for things that are currently uncommon and shorten them when they become painfully long to use?

Maybe the verbosity of function is painful when used as an anonymous function. Does the blackslash idea for anon functions (only) work grammar wise:

doIt((x) { alert(x * x) } ); // braces doIt((x) ( x * x)); // parens - no return let myfun = (x) (x * x);

Also, is anything proposed for rationalizing ASI in Harmony.


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# Mark S. Miller (15 years ago)

On Fri, Jul 23, 2010 at 10:37 AM, Oliver Hunt <oliver at apple.com> wrote:

On Jul 23, 2010, at 10:32 AM, Brendan Eich wrote:

On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:

[Good point about LL(∞) snipped.]

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.

Ollie, was that with browser-side Objective-J compilation, or with the server translating and feeding the Obj-J-lowered-to-JS code to the browser?

I believe it was with the browser being passed preprocessed source, but i'll harass them to find out.

I have polled audiences at talks in the last year about shorter function syntax, see first two links at brendaneich.com/presentations. Results mainly for fun but somewhat informative (to me at any rate) were not resoundingly in favor of a new and much shorter keyword to use instead of function.

This was before strawman:shorter_function_syntaxwas proposed, so I didn't ask the audiences to clap for its # syntax.

People like the expression-closure idea, although syntax needs to be hammered out. See developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)

I personally am not too fussed about the reduced typing -- if people really wanted reduced typing we could simply adopt "" which seems to be the common symbol used for a function.

The reason I prefer "#" to "" is simply that JavaScript source text [fragments] frequently appear in literal strings. Right now, the only quoting hazard this introduced is quotes and backslashes in nested literal strings. (Is this true?). If you use backslash in syntax elsewhere in the language, then it becomes an additional quoting hazard that's easy to miss.

+1 on "#".

# Brendan Eich (15 years ago)

On Jul 24, 2010, at 11:00 AM, Alex Russell wrote:

On Jul 24, 2010, at 9:21 AM, Kevin Curtis wrote:

Should the proposed shorter form # desugar to function or a const function: strawman:const_functions

Regular, plain-old function. No funky return semantics (ala some of the closure proposals), no extra qualifiers. If you want 'em, you can pay for 'em. The common problem "#" attempts to address is the huge verbosity of "function", nothing more.

That's not what the proposal from you and arv says :-/:

strawman:shorter_function_syntax

The completion value of the statements in the braced body of a # function is the return value.

I dislike the verbosity of function - though I can't help feeling # could be used for other ends.

let dict = #{"hello": 4, "world":5}; // it's a hash/dict not an object

So a new dictonary/map type is interesting, but it's unclear that we really need anything like that until/unless we turn off the "delete" operator.

Why wouldn't you ever delete from a dictionary?

The real motivator for dictionaries is to avoid Object.prototype pollution of the dict's "in" (not "own") property namespace.

let arr = #[4,4,5] // typed array - Numbers only - contiguous memory block?

How about we start with the long form for things that are currently uncommon and shorten them when they become painfully long to use?

Good in general if you can iterate quickly enough. If we can cut to the chase, even better given the cycle times among browsers and Ecma editions.

I see Kevin's point, too: use # for "hashes" and other object initialiser extensions, use something more lambda-looking for function.

# Alex Russell (15 years ago)

On Jul 24, 2010, at 12:27 PM, Brendan Eich wrote:

On Jul 24, 2010, at 11:00 AM, Alex Russell wrote:

On Jul 24, 2010, at 9:21 AM, Kevin Curtis wrote:

Should the proposed shorter form # desugar to function or a const function: strawman:const_functions

Regular, plain-old function. No funky return semantics (ala some of the closure proposals), no extra qualifiers. If you want 'em, you can pay for 'em. The common problem "#" attempts to address is the huge verbosity of "function", nothing more.

That's not what the proposal from you and arv says :-/:

strawman:shorter_function_syntax

The completion value of the statements in the braced body of a # function is the return value.

I take the point, but again, that's to shorten things up, not to change semantics where you would have otherwise added a "return".

My apologies for being imprecise.

I dislike the verbosity of function - though I can't help feeling # could be used for other ends.

let dict = #{"hello": 4, "world":5}; // it's a hash/dict not an object

So a new dictonary/map type is interesting, but it's unclear that we really need anything like that until/unless we turn off the "delete" operator.

Why wouldn't you ever delete from a dictionary?

Oh, you would, but if you have a new dictionary type, you can turn of "delete" in regular objects and provide a new method on the dict to handle that internally.

The real motivator for dictionaries is to avoid Object.prototype pollution of the dict's "in" (not "own") property namespace.

Which sound the like the long way around just providing a form of the iterator that list only the hasOwnProperty items.

let arr = #[4,4,5] // typed array - Numbers only - contiguous memory block?

How about we start with the long form for things that are currently uncommon and shorten them when they become painfully long to use?

Good in general if you can iterate quickly enough. If we can cut to the chase, even better given the cycle times among browsers and Ecma editions.

...which can go down if we can get the cycle times for browser versions down. We're building a language predicated on browser resource/network behavior constraints and we succeed/fail by browser adoption. Given that browsers are moving faster, I suspect we'll get another shot at shortening obviously-painful and hard-to-use Harmony features sooner rather than later.

I see Kevin's point, too: use # for "hashes" and other object initialiser extensions, use something more lambda-looking for function.

/be

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# Brendan Eich (15 years ago)

On Jul 24, 2010, at 12:39 PM, Alex Russell wrote:

On Jul 24, 2010, at 12:27 PM, Brendan Eich wrote:

On Jul 24, 2010, at 11:00 AM, Alex Russell wrote:

On Jul 24, 2010, at 9:21 AM, Kevin Curtis wrote:

Should the proposed shorter form # desugar to function or a const function: strawman:const_functions

Regular, plain-old function. No funky return semantics (ala some of the closure proposals), no extra qualifiers. If you want 'em, you can pay for 'em. The common problem "#" attempts to address is the huge verbosity of "function", nothing more.

That's not what the proposal from you and arv says :-/:

strawman:shorter_function_syntax

The completion value of the statements in the braced body of a # function is the return value.

I take the point, but again, that's to shorten things up, not to change semantics where you would have otherwise added a "return".

My apologies for being imprecise.

No problem, but there's more to say about this completion value is return value idea. It's not a no-brainer.

Waldemar pointed out something he and other LISP hackers run into: unintended completion value leakage via return. This is a hazard in expression languages. I added the unary void operator to JS from the beginning to help suppress it.

Another point: if the body becomes at all involved in its control flow, you'll want early return or something like it. If you allow return in # functions, now there's greater user-confusion surface because of the implicit return before the tail position expressions (plural).

I dislike the verbosity of function - though I can't help feeling # could be used for other ends.

let dict = #{"hello": 4, "world":5}; // it's a hash/dict not an object

So a new dictonary/map type is interesting, but it's unclear that we really need anything like that until/unless we turn off the "delete" operator.

Why wouldn't you ever delete from a dictionary?

Oh, you would, but if you have a new dictionary type, you can turn of "delete" in regular objects and provide a new method on the dict to handle that internally.

We're not removing delete, so this seems like a snipe hunt. Harmony is not going to be gratuitously incompatible or older-edition code that should migrate, won't migrate, all else equal.

The real motivator for dictionaries is to avoid Object.prototype pollution of the dict's "in" (not "own") property namespace.

Which sound the like the long way around just providing a form of the iterator that list only the hasOwnProperty items.

Iteration is not the issue, "in" testing is and "get" false hits are. We don't have any short getOwnPropertyValue syntax or method, and hasOwnProperty is painful, especially if you have to write

Object.prototype.hasOwnProperty.call(dict, key)

let arr = #[4,4,5] // typed array - Numbers only - contiguous memory block?

How about we start with the long form for things that are currently uncommon and shorten them when they become painfully long to use?

Good in general if you can iterate quickly enough. If we can cut to the chase, even better given the cycle times among browsers and Ecma editions.

...which can go down if we can get the cycle times for browser versions down.

Yeah, good luck with that! Not everyone is going to agree before implementing. Not everyone is going to implement on the same schedule. And not everyone is going to Chrome's six week release cycle (which I admire, btw).

# Alex Russell (15 years ago)

On Jul 24, 2010, at 12:45 PM, Brendan Eich wrote:

On Jul 24, 2010, at 12:39 PM, Alex Russell wrote:

On Jul 24, 2010, at 12:27 PM, Brendan Eich wrote:

On Jul 24, 2010, at 11:00 AM, Alex Russell wrote:

On Jul 24, 2010, at 9:21 AM, Kevin Curtis wrote:

Should the proposed shorter form # desugar to function or a const function: strawman:const_functions

Regular, plain-old function. No funky return semantics (ala some of the closure proposals), no extra qualifiers. If you want 'em, you can pay for 'em. The common problem "#" attempts to address is the huge verbosity of "function", nothing more.

That's not what the proposal from you and arv says :-/:

strawman:shorter_function_syntax

The completion value of the statements in the braced body of a # function is the return value.

I take the point, but again, that's to shorten things up, not to change semantics where you would have otherwise added a "return".

My apologies for being imprecise.

No problem, but there's more to say about this completion value is return value idea. It's not a no-brainer.

Yeah, Erik and I went round-and-round on it before proposing it. The only reason it seemed workable is that "#" is new syntax.

Waldemar pointed out something he and other LISP hackers run into: unintended completion value leakage via return. This is a hazard in expression languages. I added the unary void operator to JS from the beginning to help suppress it.

Another point: if the body becomes at all involved in its control flow, you'll want early return or something like it. If you allow return in # functions, now there's greater user-confusion surface because of the implicit return before the tail position expressions (plural).

I think the plan was to allow for "return" in # functions. Again, we went around on this point a couple of times and I may be wrong to want auto-return. Frankly, I'd settle for a shorter name for "return" ;-)

I dislike the verbosity of function - though I can't help feeling # could be used for other ends.

let dict = #{"hello": 4, "world":5}; // it's a hash/dict not an object

So a new dictonary/map type is interesting, but it's unclear that we really need anything like that until/unless we turn off the "delete" operator.

Why wouldn't you ever delete from a dictionary?

Oh, you would, but if you have a new dictionary type, you can turn of "delete" in regular objects and provide a new method on the dict to handle that internally.

We're not removing delete, so this seems like a snipe hunt. Harmony is not going to be gratuitously incompatible or older-edition code that should migrate, won't migrate, all else equal.

I'm not advocating removing delete (yet), I was just trying to outline cases in which I could see a new Dictionary type being a hard requirement. I can't think of others offhand.

The real motivator for dictionaries is to avoid Object.prototype pollution of the dict's "in" (not "own") property namespace.

Which sound the like the long way around just providing a form of the iterator that list only the hasOwnProperty items.

Iteration is not the issue, "in" testing is and "get" false hits are. We don't have any short getOwnPropertyValue syntax or method, and hasOwnProperty is painful, especially if you have to write

Object.prototype.hasOwnProperty.call(dict, key)

Yeah, that's bad. Would a new dictionary type have a specialization for "in"? Or just a method (ala Python)? If the latter, it all seems moot-ish.

let arr = #[4,4,5] // typed array - Numbers only - contiguous memory block?

How about we start with the long form for things that are currently uncommon and shorten them when they become painfully long to use?

Good in general if you can iterate quickly enough. If we can cut to the chase, even better given the cycle times among browsers and Ecma editions.

...which can go down if we can get the cycle times for browser versions down.

Yeah, good luck with that! Not everyone is going to agree before implementing.

Not required. We just need to clear the path so folks can implement quickly. Fast standard iterations and fast browser iterations together create a dynamic that allows the economics of a better-functioning browser market to disseminate new features faster than we have recently.

Not everyone is going to implement on the same schedule.

That's cool. My comments were with a view toward better, not perfect.

And not everyone is going to Chrome's six week release cycle (which I admire, btw).

/be

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# Brendan Eich (15 years ago)

On Jul 24, 2010, at 12:59 PM, Alex Russell wrote:

I think the plan was to allow for "return" in # functions. Again, we went around on this point a couple of times and I may be wrong to want auto-return. Frankly, I'd settle for a shorter name for "return" ;-)

Propose one? The completion value hazard is going to be a stumbling block in TC39, I would bet real money (andnot due to me).

Yeah, that's bad. Would a new dictionary type have a specialization for "in"? Or just a method (ala Python)? If the latter, it all seems moot-ish.

As with tuple in the large and baggy shadow of Array, it is hard to beat Object syntax -- #{...} and related ideas are worth exploring but I suspect we'll end up saying "library" (your "just a method").

Yeah, good luck with that! Not everyone is going to agree before implementing.

Not required. We just need to clear the path so folks can implement quickly. Fast standard iterations and fast browser iterations together create a dynamic that allows the economics of a better-functioning browser market to disseminate new features faster than we have recently.

I agree, and we've been trying to do this with SpiderMonkey (and Rhino, thanks to nboyd, stevey, et al.), but it can backfire, and you then have to carry an extension that did not make it into a standard for a while. The time constant is shrinking now that TC39 is functioning again, but we added getters and setters over a decade ago.

Not everyone is going to implement on the same schedule.

That's cool. My comments were with a view toward better, not perfect.

I'm with you, but note that some browser vendors won't take the chance I pointed to above. They'll wait for a finished ECMA-262 Edition. However pipelined some browsers are, others will not be "superscalar" this way, and developers won't have as coherent, closely-versioned, and cleanly upgrading a supported-browser market.

Just some grains of salt, we should definitely persevere. It's my other middle name. :-)

# Brendan Eich (15 years ago)

On Jul 24, 2010, at 1:10 PM, Brendan Eich wrote:

On Jul 24, 2010, at 12:59 PM, Alex Russell wrote:

I think the plan was to allow for "return" in # functions. Again, we went around on this point a couple of times and I may be wrong to want auto-return. Frankly, I'd settle for a shorter name for "return" ;-)

Propose one? The completion value hazard is going to be a stumbling block in TC39, I would bet real money (andnot due to me).

Of course dherman already proposed explicit "result here" syntax: => expr. See

strawman:let_expressions

But these were deferred.

# Dmitry A. Soshnikov (15 years ago)

On 23.07.2010 21:24, Bryan Kyle wrote:

I believe # has the advantage of not being a valid character in an identifier so there won't be any backwards compatibility problems with existing code.

Backward compats are good. But is this a good reason to provide ugly syntax constructs into the language? What does this sharp # mean regarding the concept of a "function" in math? No, I'm not conservator, but vice-versa, I like innovations (# for functions can quickly become familiar and habitual for me). But just think that "fn" or "fun" is more human-read and elegantly short at the same time. I don't also see a big problem in full "function" keyword because think that every good editor should have good autocomplete and snnipets.

Your suggestions are legal identifiers so it makes the job of the parser harder. The parser would have to look further ahead to be able to tell the difference between an anonymous function and a call to an existing function. That isn't to say it's impossible, but simplicity speaks for itself :)

So what? Is it so now with a "funciton" keyword? Why does a parser -- if "fn" or "fun" will be keywords (just like currently existing "function") should think that it could be a "function call"?

Harmony /anyway/ brings some new syntax constructs, so maybe yet another good short innovation -- "fun" (just like in Erlang) or "fn" or even "def" (like in Ruby and Python, although I think "fun" is better) is good?

Also I think JS still has some redundant C-syntax garbage. For example, that "break" keyword each time in "case" of a "switch" -- for what it is there? For what to write several times "case-case-case" if it's possible to write it once and separate testing operands with a colon? Moreover, this "switch" construct is non-logical in control flow if to place "default" not in the end or to forget this "break" garbage. Why on earth if I have x = 5 and "case 5:" should I catch also "case 6:" if I forgot that useless "break" garbage there? So I like better Ruby's or Coffee's way, e.g. jashkenas.github.com/coffee-script/#switch Btw, there're many good syntax sugars which Harmony can borrow (I know some of them are already planned and it's very good, but maybe others too).

Regarding ASI (here also was a talk). It's about client side JS and its minification why this can be a problem. "Scary" cases with defining a FE (with forgetting semicolon) and call another FE (which is an argument for the first one FE) -- are well-known long time and not scary in any respect. Generally, explicit semicolon is also a /garbage/ -- new line is enough -- with defining all related rules such as what will be with "return". ASI mechanism is in many languages and if it's implemented well -- it's a good mechanism. I myself use explicit semicolon of course -- everywhere. But I think I wouldn't e.g. programming on server-side JS where minification into one line is not needed.

Dmitry.

# Maciej Stachowiak (15 years ago)

On Jul 24, 2010, at 11:51 AM, Mark S. Miller wrote:

On Fri, Jul 23, 2010 at 10:37 AM, Oliver Hunt <oliver at apple.com> wrote:

On Jul 23, 2010, at 10:32 AM, Brendan Eich wrote:

On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:

[Good point about LL(∞) snipped.]

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.

Ollie, was that with browser-side Objective-J compilation, or with the server translating and feeding the Obj-J-lowered-to-JS code to the browser?

I believe it was with the browser being passed preprocessed source, but i'll harass them to find out.

I have polled audiences at talks in the last year about shorter function syntax, see first two links at brendaneich.com/presentations. Results mainly for fun but somewhat informative (to me at any rate) were not resoundingly in favor of a new and much shorter keyword to use instead of function.

This was before strawman:shorter_function_syntax was proposed, so I didn't ask the audiences to clap for its # syntax.

People like the expression-closure idea, although syntax needs to be hammered out. See developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)

I personally am not too fussed about the reduced typing -- if people really wanted reduced typing we could simply adopt "" which seems to be the common symbol used for a function.

The reason I prefer "#" to "" is simply that JavaScript source text [fragments] frequently appear in literal strings. Right now, the only quoting hazard this introduced is quotes and backslashes in nested literal strings. (Is this true?). If you use backslash in syntax elsewhere in the language, then it becomes an additional quoting hazard that's easy to miss.

+1 on "#".

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages. Two other characters totally disallowed in the syntax are @ and `, I wonder if either of those would be more visually pleasing:

[0, 1, 2, 3].map( #(x) {x * x} ) [0, 1, 2, 3].map( `(x) {x * x} ) [0, 1, 2, 3].map( @(x) {x * x} )

I also wonder if using a strictly binary operator might be workable without creating syntax ambiguities:

[0, 1, 2, 3].map( ^(x) {x * x} ) [0, 1, 2, 3].map( *(x) {x * x} ) [0, 1, 2, 3].map( %(x) {x * x} )

I kind of like ` but it may be too visually subtle and may be confusing to lisp users. @ seems less visually harsh than #. I like ^ for resemblance to lambda, overall visual weight, and alignment with Apple's "blocks" extension to C[1]. I have a vague memory that we discussed ^ before and discarded it, but I can't find that discussion in the archives at the moment.

Perhaps the strawman page for shorter function syntax should list reasons for rejecting other syntax options. I would be happy to document the reasons against fn, fun, f and , but I can't seem to remember my username and password (I'm not even sure if I have an account). Who can help with wiki access issues?

, Maciej

[1] en.wikipedia.org/wiki/Blocks_(C_language_extension)

# Mark S. Miller (15 years ago)

On Sun, Jul 25, 2010 at 4:57 PM, Maciej Stachowiak <mjs at apple.com> wrote:

On Jul 24, 2010, at 11:51 AM, Mark S. Miller wrote:

On Fri, Jul 23, 2010 at 10:37 AM, Oliver Hunt <oliver at apple.com> wrote:

On Jul 23, 2010, at 10:32 AM, Brendan Eich wrote:

On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:

[Good point about LL(∞) snipped.]

  • To give you an idea of how important parsing is, the 280 North folk once told me that parsing made up 25% of the load time for 280 Slides.

Ollie, was that with browser-side Objective-J compilation, or with the server translating and feeding the Obj-J-lowered-to-JS code to the browser?

I believe it was with the browser being passed preprocessed source, but i'll harass them to find out.

I have polled audiences at talks in the last year about shorter function syntax, see first two links at brendaneich.com/presentations. Results mainly for fun but somewhat informative (to me at any rate) were not resoundingly in favor of a new and much shorter keyword to use instead of function.

This was before strawman:shorter_function_syntaxwas proposed, so I didn't ask the audiences to clap for its # syntax.

People like the expression-closure idea, although syntax needs to be hammered out. See developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)

I personally am not too fussed about the reduced typing -- if people really wanted reduced typing we could simply adopt "" which seems to be the common symbol used for a function.

The reason I prefer "#" to "" is simply that JavaScript source text [fragments] frequently appear in literal strings. Right now, the only quoting hazard this introduced is quotes and backslashes in nested literal strings. (Is this true?). If you use backslash in syntax elsewhere in the language, then it becomes an additional quoting hazard that's easy to miss.

+1 on "#".

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages. Two other characters totally disallowed in the syntax are @ and `, I wonder if either of those would be more visually pleasing:

[0, 1, 2, 3].map( #(x) {x * x} ) [0, 1, 2, 3].map( `(x) {x * x} ) [0, 1, 2, 3].map( @(x) {x * x} )

I also wonder if using a strictly binary operator might be workable without creating syntax ambiguities:

[0, 1, 2, 3].map( ^(x) {x * x} ) [0, 1, 2, 3].map( *(x) {x * x} ) [0, 1, 2, 3].map( %(x) {x * x} )

I kind of like ` but it may be too visually subtle and may be confusing to lisp users. @ seems less visually harsh than #. I like ^ for resemblance to lambda,

Cool idea. Even better, it looks like an uppercase lambda: < en.wikipedia.org/wiki/Lambda>. If it doesn't create syntactic

ambiguities, +1 on "^".

overall visual weight, and alignment with Apple's "blocks" extension to C[1]. I have a vague memory that we discussed ^ before and discarded it, but I can't find that discussion in the archives at the moment.

Perhaps the strawman page for shorter function syntax should list reasons for rejecting other syntax options. I would be happy to document the reasons against fn, fun, f and , but I can't seem to remember my username and password (I'm not even sure if I have an account). Who can help with wiki access issues?

I think that would be Brendan.

# Sam Ruby (15 years ago)

On Sun, Jul 25, 2010 at 7:57 PM, Maciej Stachowiak <mjs at apple.com> wrote:

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages. Two other characters totally disallowed in the syntax are @ and , I wonder if either of those would be more visually pleasing: [0, 1, 2, 3].map( #(x) {x * x} ) [0, 1, 2, 3].map((x) {x * x} ) [0, 1, 2, 3].map( @(x) {x * x} ) I also wonder if using a strictly binary operator might be workable without creating syntax ambiguities: [0, 1, 2, 3].map( ^(x) {x * x} ) [0, 1, 2, 3].map( *(x) {x * x} ) [0, 1, 2, 3].map( %(x) {x * x} )

The ruby syntax for the above is as follows:

[0,1,2,3].map {|x| x*x}

(try it in 'irb' to see what I mean)

While I don't believe that would fly here, perhaps adding parens around the function would:

[0,1,2,3].map({|x| x*x})

  • Sam Ruby
# Brendan Eich (15 years ago)

On Jul 25, 2010, at 4:57 PM, Maciej Stachowiak wrote:

On Jul 24, 2010, at 11:51 AM, Mark S. Miller wrote:

The reason I prefer "#" to "" is simply that JavaScript source text [fragments] frequently appear in literal strings. Right now, the only quoting hazard this introduced is quotes and backslashes in nested literal strings. (Is this true?). If you use backslash in syntax elsewhere in the language, then it becomes an additional quoting hazard that's easy to miss.

+1 on "#".

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages.

Plus some interest in reserving it for "hash"-y dictionary literal syntax.

Two other characters totally disallowed in the syntax are @ and `, I wonder if either of those would be more visually pleasing:

[0, 1, 2, 3].map( #(x) {x * x} ) [0, 1, 2, 3].map( `(x) {x * x} ) [0, 1, 2, 3].map( @(x) {x * x} )

FWIW, @ is used by ECMA-357 (E4X) but that use (XML attribute names) could be reconciled with this one.

I also wonder if using a strictly binary operator might be workable without creating syntax ambiguities:

[0, 1, 2, 3].map( ^(x) {x * x} ) [0, 1, 2, 3].map( *(x) {x * x} ) [0, 1, 2, 3].map( %(x) {x * x}

If you allow such a shorthand at the start of a statement (expression statement), then lack of semicolon at the end of the previous statement will result in a binary operator expression spanning more than one line being parsed:

x = y + z ^(a){a*a}.mapOver(array)

# Maciej Stachowiak (15 years ago)

On Jul 25, 2010, at 4:57 PM, Maciej Stachowiak wrote:

Perhaps the strawman page for shorter function syntax should list reasons for rejecting other syntax options. I would be happy to document the reasons against fn, fun, f and , but I can't seem to remember my username and password (I'm not even sure if I have an account). Who can help with wiki access issues?

I documented the alternate proposals and known problems if any here:

strawman:shorter_function_syntax#alternate_syntax_proposals

For the Ruby-like syntax, I was not sure what the zero-argument case would look like.

Would it be like this:

[0, 1, 2, 3].map({|| x * x})

Or like this:

[0, 1, 2, 3].map({x * x})

The former looks ugly to me and the latter may create parser difficulties.

, Maciej

# Dmitry A. Soshnikov (15 years ago)

On 26.07.2010 3:57, Maciej Stachowiak wrote:

On Jul 24, 2010, at 11:51 AM, Mark S. Miller wrote:

On Fri, Jul 23, 2010 at 10:37 AM, Oliver Hunt <oliver at apple.com <mailto:oliver at apple.com>> wrote:

On Jul 23, 2010, at 10:32 AM, Brendan Eich wrote:

> On Jul 23, 2010, at 10:27 AM, Oliver Hunt wrote:
>
> [Good point about LL(∞) snipped.]
>
>> *  To give you an idea of how important parsing is, the 280
North folk once told me that parsing made up 25% of the load time
for 280 Slides.
>
> Ollie, was that with browser-side Objective-J compilation, or
with the server translating and feeding the Obj-J-lowered-to-JS
code to the browser?

I believe it was with the browser being passed preprocessed
source, but i'll harass them to find out.

> I have polled audiences at talks in the last year about shorter
function syntax, see first two links at
http://brendaneich.com/presentations/. Results mainly for fun but
somewhat informative (to me at any rate) were not resoundingly in
favor of a new and much shorter keyword to use instead of function.
>
> This was before
http://wiki.ecmascript.org/doku.php?id=strawman:shorter_function_syntax
was proposed, so I didn't ask the audiences to clap for its # syntax.
>
> People like the expression-closure idea, although syntax needs
to be hammered out. See
https://developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_%28Merge_into_own_page.2fsection%29

I personally am not too fussed about the reduced typing -- if
people really wanted reduced typing we could simply adopt "\"
which seems to be the common symbol used for a function.

The reason I prefer "#" to "" is simply that JavaScript source text [fragments] frequently appear in literal strings. Right now, the only quoting hazard this introduced is quotes and backslashes in nested literal strings. (Is this true?). If you use backslash in syntax elsewhere in the language, then it becomes an additional quoting hazard that's easy to miss.

+1 on "#".

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages. Two other characters totally disallowed in the syntax are @ and `, I wonder if either of those would be more visually pleasing:

[0, 1, 2, 3].map( #(x) {x * x} ) [0, 1, 2, 3].map( `(x) {x * x} ) [0, 1, 2, 3].map( @(x) {x * x} )

I also wonder if using a strictly binary operator might be workable without creating syntax ambiguities:

[0, 1, 2, 3].map( ^(x) {x * x} ) [0, 1, 2, 3].map( *(x) {x * x} ) [0, 1, 2, 3].map( %(x) {x * x} )

I kind of like ` but it may be too visually subtle and may be confusing to lisp users. @ seems less visually harsh than #. I like ^ for resemblance to lambda, overall visual weight, and alignment with Apple's "blocks" extension to C[1]. I have a vague memory that we discussed ^ before and discarded it, but I can't find that discussion in the archives at the moment.

Is it RegExp? Or ASCII-art maybe? Or modern smiles? Looking on all this, I already think that old "function" is not so bad.

The thing is not to invent some "cool" symbol for that. The thing is to make convenient short notation which /at the same time/ will reflect a /human-read function/ concept -- a function from math and programming. %

  • what is this?

The good thing of JS, that it (in contrast with all those Python, Ruby, Erlang, etc) has the same syntactically definition of a /casual subroutine/ -- a function declaration (FD) and a /"functional object"/ -- a literally defined function expression (FE). Python has defs and lambdas, Ruby has defs, lambdas, procs, blocks and other, Erlang

  • casual functions and funs.

JS is better: (1) all functions (FE, (N)FE) are defined syntactically the same, (2) all are closures, (3) all are higher-order functions.

So it may be good to keep it the same, but then casual FDs should be defined as:

fun foo() { ... }

[1, 2, 3].map(fun(x) { x * x});

But I guess you want to keep "function" keyword to defined casual FD (or "lambda" I've heard). If simple functions will be named as "lambda"s, it can also be used in "funargs":

lambda foo() { -- not bad ... }

[1, 2, 3].map(lambda(x) { x * x}); -- also nice

Perhaps the strawman page for shorter function syntax should list reasons for rejecting other syntax options. I would be happy to document the reasons against fn, fun, f and , but I can't seem to remember my username and password (I'm not even sure if I have an account). Who can help with wiki access issues?

Yeah, that's interesting, I'll follow. I guess you'll describe also how bad is "function" keyword now (and not because it's long, I mean that "problems" with parser, etc).

# Dmitry A. Soshnikov (15 years ago)

On 26.07.2010 4:16, Sam Ruby wrote:

On Sun, Jul 25, 2010 at 7:57 PM, Maciej Stachowiak<mjs at apple.com> wrote:

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages. Two other characters totally disallowed in the syntax are @ and , I wonder if either of those would be more visually pleasing: [0, 1, 2, 3].map( #(x) {x * x} ) [0, 1, 2, 3].map((x) {x * x} ) [0, 1, 2, 3].map( @(x) {x * x} ) I also wonder if using a strictly binary operator might be workable without creating syntax ambiguities: [0, 1, 2, 3].map( ^(x) {x * x} ) [0, 1, 2, 3].map( *(x) {x * x} ) [0, 1, 2, 3].map( %(x) {x * x} )

The ruby syntax for the above is as follows:

[0,1,2,3].map {|x| x*x}

(try it in 'irb' to see what I mean)

While I don't believe that would fly here, perhaps adding parens around the function would:

[0,1,2,3].map({|x| x*x})

In JS |x| can be placed outside, and then some special name won't be needed at all:

[1, 2, 3].map((x) {x * x}).

This exactly how it's used in CoffeeScript. But in contrast with Coffee, JS has obligatory parens, so (( looks not so good. But really, this syntax is nice:

withFoo: (x) -> x* x -- define a function

[1, 2, 3].map (x) -> x * x -- pass an anonymous "funarg" to map

Or the same:

[1, 2, 3].map withFoo -- it sounds! And declaratively looks nice.

Will Harmony consider to call a function without parens -- to provide ability of more declarative in some cases?

Dmitry.

# Dmitry A. Soshnikov (15 years ago)

On 26.07.2010 4:48, Brendan Eich wrote:

On Jul 25, 2010, at 4:57 PM, Maciej Stachowiak wrote:

On Jul 24, 2010, at 11:51 AM, Mark S. Miller wrote:

The reason I prefer "#" to "" is simply that JavaScript source text [fragments] frequently appear in literal strings. Right now, the only quoting hazard this introduced is quotes and backslashes in nested literal strings. (Is this true?). If you use backslash in syntax elsewhere in the language, then it becomes an additional quoting hazard that's easy to miss.

+1 on "#".

Good point about the escaping hazard. I think # may look funny to people because it is a "noisy" symbol and also because it is a comment delimiter in many languages.

Plus some interest in reserving it for "hash"-y dictionary literal syntax.

The same magic symbol -- # -- for several purpose is good and bad at the same time. Here it creates/defines a function, and there -- is already about "hash"-y stuff. Don't know, maybe it's good, although not so consistent for an operator which is "too magic". But, it's a variant, and maybe be, yeah, a good variant.

# Cameron McCormack (15 years ago)

Dmitry A. Soshnikov:

In JS |x| can be placed outside, and then some special name won't be needed at all:

[1, 2, 3].map((x) {x * x}).

Wouldn’t this have the same problem that Oliver mentioned? Only in this case the ambiguity would be whether the “(x)” is a parenthesized expression or the introduction of the anonymous function.

Sam Ruby:

[0,1,2,3].map {|x| x*x}

(try it in 'irb' to see what I mean)

While I don't believe that would fly here, perhaps adding parens around the function would:

[0,1,2,3].map({|x| x*x})

I think having the braces on the outside would help with the aforementioned problem. The vertical bars don’t particularly grab me (not being a Rubyist), but this does:

[0, 1, 2, 3].map({ x => x * x }); // optionally { (x) => x * x }?

function mapPairs(o, f) { for (var p in o) { f(p, o[p]); } }

mapPairs(someObject, { (a, b) => a + '=' + b) });

(Sorry for adding more options to the discussion — quick rebuttals as to why the above wouldn’t work welcome.)

# Dmitry A. Soshnikov (15 years ago)

On 26.07.2010 12:06, Cameron McCormack wrote:

Dmitry A. Soshnikov:

In JS |x| can be placed outside, and then some special name won't be needed at all:

[1, 2, 3].map((x) {x * x}).

Wouldn’t this have the same problem that Oliver mentioned? Only in this case the ambiguity would be whether the “(x)” is a parenthesized expression or the introduction of the anonymous function.

Sam Ruby:

[0,1,2,3].map {|x| x*x}

(try it in 'irb' to see what I mean)

While I don't believe that would fly here, perhaps adding parens around the function would:

[0,1,2,3].map({|x| x*x})

I think having the braces on the outside would help with the aforementioned problem. The vertical bars don’t particularly grab me (not being a Rubyist), but this does:

[0, 1, 2, 3].map({ x => x * x }); // optionally { (x) => x * x }?

function mapPairs(o, f) { for (var p in o) { f(p, o[p]); } }

mapPairs(someObject, { (a, b) => a + '=' + b) });

That's look interesting, yeah, I (personally) like it. Also beside =>

can be used "traditional" function definition sign of some functional (and not only functional) languages: ->

Coffee (while using -> for functions) uses => sugar for binding the this value with defining a function at the same time: jashkenas.github.com/coffee-script/#fat_arrow which I think also a good sugar for .bind method.

# Peter van der Zee (15 years ago)

On 26.07.2010 12:06, Cameron McCormack wrote:

Sam Ruby:

[0,1,2,3].map {|x| x*x}

(try it in 'irb' to see what I mean)

While I don't believe that would fly here, perhaps adding parens around the function would:

[0,1,2,3].map({|x| x*x})

I think having the braces on the outside would help with the aforementioned problem. The vertical bars don't particularly grab me (not being a Rubyist), but this does:

[0, 1, 2, 3].map({ x => x * x }); // optionally { (x) => x * x }?

function mapPairs(o, f) { for (var p in o) { f(p, o[p]); } }

mapPairs(someObject, { (a, b) => a + '=' + b) });

I don't really like the proposed alternatives for function so far. The single character alternatives to "function", except perhaps for the lambda or florin sign (being Dutch ;)), don't have the visual appeal. Just like Dmitry pointed out.

I'm not sure all of this is really worth having a shorter function keyword. In fact, it seems to contradict the ASI discussion where we're trying to prevent problems. Readability seems to be an important concern... So introducing obscure syntax, even at the cost of upping parser complexity, seems weird to me.

Having said that. I like the ruby syntax proposed by Sam. If you combine the opening curly with an existing operator and require it to be a literal (so no space allowed between { and |, much like any other literal) you could have a production like

func :: {| arguments | functionbody }

Which should be no problem for parsers. Obviously you can pick alternatives for | and { but as long as you pick a combination that's currently illegal, there should not be a problem.

My vote would go to leave function as it is, if not then to use lambda or florin and otherwise something like the above. Reserve # and @ for new syntax.

  • peter
# Maciej Stachowiak (15 years ago)

On Jul 26, 2010, at 1:06 AM, Cameron McCormack wrote:

I think having the braces on the outside would help with the aforementioned problem. The vertical bars don’t particularly grab me (not being a Rubyist), but this does:

[0, 1, 2, 3].map({ x => x * x }); // optionally { (x) => x * x }?

function mapPairs(o, f) { for (var p in o) { f(p, o[p]); } }

mapPairs(someObject, { (a, b) => a + '=' + b) });

(Sorry for adding more options to the discussion — quick rebuttals as to why the above wouldn’t work welcome.)

If you allow multiple arguments with this syntax, either with or without parens, you're back to unbounded lookahead required for an LL parser.

, Maciej

# Kevin Curtis (15 years ago)

Re symbols and new syntax:

I think there's plans for the backtick ` with the quasis strawman.

The @ symbol reminds me of the c# string escape symbol: var x = @"hello \n world"; And leads on to thinking about python strings: """, r", b" etc.

It's probably been discussed - but any possibility of multi-line, escaped, raw strings etc in Harmony?

# Cameron McCormack (15 years ago)

Cameron McCormack:

mapPairs(someObject, { (a, b) => a + '=' + b) });

Maciej Stachowiak:

If you allow multiple arguments with this syntax, either with or without parens, you're back to unbounded lookahead required for an LL parser.

Shouldn’t be. Take the parens required option. After parsing the open brace, there are only two options: either you get an identifier or string literal, in which case the open brace started an object literal, or you get an open parenthesis, in which case it’s a function.

expr -> LBRACE expr-brace-rest | … (various other productions, none of which begin with LBRACE)

expr-brace-rest -> LPAREN args RPAREN ARROW expr RBRACE | obj-literal-prop more-obj-literal-props RBRACE

args -> IDENT more-args | <empty>

more-args -> COMMA IDENT more-args | <empty>

obj-literal-prop -> IDENT COLON expr | STRING COLON expr

more-obj-literal-props -> COMMA obj-literal-prop more-obj-literal-props | <empty>

That’s LL(1). With the optional parens case, you know whether it’s an object literal or a function either if you find an opening paren or, in the case of omitted parens in a function, when you find the arrow. It’d even work if the parens could be omitted with multiple arguments — finding a comma instead of a colon means that it’s a function.

expr -> LBRACE expr-brace-rest | … (various other productions, none of which begin with LBRACE)

expr-brace-rest -> LPAREN args RPAREN ARROW expr RBRACE | ARROW expr RBRACE | STRING COLON expr more-obj-literal-props RBRACE | IDENT obj-literal-or-function-rest RBRACE

args -> IDENT more-args | <empty>

more-args -> COMMA IDENT more-args | <empty>

obj-literal-prop -> IDENT COLON expr | STRING COLON expr

more-obj-literal-props -> COMMA obj-literal-prop more-obj-literal-props | <empty>

obj-literal-or-function-rest -> COMMA IDENT more-args ARROW expr | ARROW expr

That’s LL(1) too. (Or I’m missing something, also quite possible. I didn’t thoroughly check the above productions, but they should be approximately correct, simplifications and assumptions notwithstanding.)

# Maciej Stachowiak (15 years ago)

On Jul 26, 2010, at 3:56 AM, Cameron McCormack wrote:

Cameron McCormack:

mapPairs(someObject, { (a, b) => a + '=' + b) });

Maciej Stachowiak:

If you allow multiple arguments with this syntax, either with or without parens, you're back to unbounded lookahead required for an LL parser.

Shouldn’t be. Take the parens required option. After parsing the open brace, there are only two options: either you get an identifier or string literal, in which case the open brace started an object literal, or you get an open parenthesis, in which case it’s a function.

I see. I was thinking of ambiguity with a block, but those generally can't appear in the same context as expressions.

, Maciej

# Dmitry A. Soshnikov (15 years ago)

On 23.07.2010 21:27, Oliver Hunt wrote:

On Jul 23, 2010, at 10:08 AM, Trans wrote:

Hi--

I was reading about the proposed shorter function syntax on the wiki and want to comment on it.

strawman:shorter_function_syntax

I do not see how it is advantageous to using a special symbol, '#'.

Taking the example.

[0, 1, 2, 3].map( #(x) {x * x} )

If the goal is just to be more concise, what is wrong with 'f' as an abbreviation of 'function'?

[0, 1, 2, 3].map( f(x) {x * x} )

Or 'fn', if it seems a little clearer.

[0, 1, 2, 3].map( fn(x) {x * x} )

Heck you could even use 'y' as an upside down lambda if you wanted.

[0, 1, 2, 3].map( y(x) {x * x} )

Any of these seem a much nicer choice than '#', IMHO.

This would require an LL(infinity) grammar as you get ambiguity between a function call and a lambda declaration -- this is solvable with an LALR parser but at substantial performance cost, and in general LALR parsers require a secondary tree walk to validate code in strict mode. Just using an LALR vs LL parser is a very easy way to more than double the time it takes to parse stuff, and that's without all the other optimisations we can do if we know we don't need to look at the full parse tree after validating the input.*

Excuse me, can you clarify (I don't know LL, LR grammar parsers work well), but it's just interesting:

What the difference between the following two cases, and what the issue of the "LL(infinity) grammar" for the second one?

[1,2,3].map(function (x) { return x * x }); // current implementation, or even with exp.closures function (x) x * x

[1,2,3].map(fun(x) { x * x }); // suggested which will cause "LL(infinity) grammar" issue

P.S.: in general, I'm not against #, as I said, it's possible to get a habit for it quickly. But, just interesting about "issues" of "fun" and other readable variants.

Dmitry.

# Brendan Eich (15 years ago)

Deja vu, or as dherman tweeted, "Groundhog Day".

In case people don't know about it, there's an archive for this list, and it has a pretty complete (clumsy to search directly; use google site: search) but sporadically messed-up record of past discussions. Not to pick randomly, but December 2008 had both "Allen's lambda syntax proposal" / "Concise functions..." and "Proposal: Modify automatic semicolon insertion in strict mode".

esdiscuss/2008-December

The LL(∞) problem came up then:

esdiscuss/2008-December/008348, esdiscuss/2008-December/008352

Braces on the outside can solve this lookahead problem, and another problem worth reiterating (below). My hope is that if we keep working over these issues, then we (like Bill Murray's character) will achieve enlightenment and our lambda "Groundhog Day" will end.

In this post:

esdiscuss/2008-December/008512

I mention a problem beyond LL(∞), which is bottom-up parsing ambiguity:

a => a ? f : x++ (0);

Note that PostFixExpression cannot be an unparenthesized callee in a CallExpression, only MemberExpression can be the callee Here, the whole C#-style lambda must be parsed as the callee being passed (0). If lambdas of any kind are not braced or otherwise parenthesized, they end with a low-precedence expression body and a top-down parser cannot decide correctly when that body should end. A bottom-up parser generator would complain about "reduce/reduce conflict".

Waldemar first pointed this out in

esdiscuss/2008-October/007883

# Kevin Curtis (15 years ago)

Re backslash and the issue of creating an escaping hazard when JS code is included in a quoted string.

How so - is there a problem with eval'ing: eval("[0, 1, 2, 3].map((x) {x * x})");

(The backslash is sweet on both us and euro keyboards - no shift needed as with # or @. yeah trivial...).

# Brendan Eich (15 years ago)

On Jul 26, 2010, at 10:00 AM, Kevin Curtis wrote:

Re backslash and the issue of creating an escaping hazard when JS code is included in a quoted string.

How so - is there a problem with eval'ing: eval("[0, 1, 2, 3].map((x) {x * x})");

js> "(".length

1 js> "(".charAt(0) "("

Big problem.

(The backslash is sweet on both us and euro keyboards - no shift needed as with # or @. yeah trivial...).

Shifting is a problem, I've heard from RSI-suffering friends.

# Dmitry A. Soshnikov (15 years ago)

On 26.07.2010 18:44, Dmitry A. Soshnikov wrote:

On 23.07.2010 21:27, Oliver Hunt wrote:

On Jul 23, 2010, at 10:08 AM, Trans wrote:

Hi--

I was reading about the proposed shorter function syntax on the wiki and want to comment on it.

strawman:shorter_function_syntax

I do not see how it is advantageous to using a special symbol, '#'.

Taking the example.

[0, 1, 2, 3].map( #(x) {x * x} )

If the goal is just to be more concise, what is wrong with 'f' as an abbreviation of 'function'?

[0, 1, 2, 3].map( f(x) {x * x} )

Or 'fn', if it seems a little clearer.

[0, 1, 2, 3].map( fn(x) {x * x} )

Heck you could even use 'y' as an upside down lambda if you wanted.

[0, 1, 2, 3].map( y(x) {x * x} )

Any of these seem a much nicer choice than '#', IMHO. This would require an LL(infinity) grammar as you get ambiguity between a function call and a lambda declaration -- this is solvable with an LALR parser but at substantial performance cost, and in general LALR parsers require a secondary tree walk to validate code in strict mode. Just using an LALR vs LL parser is a very easy way to more than double the time it takes to parse stuff, and that's without all the other optimisations we can do if we know we don't need to look at the full parse tree after validating the input.*

Excuse me, can you clarify (I don't know LL, LR grammar parsers work well), but it's just interesting:

What the difference between the following two cases, and what the issue of the "LL(infinity) grammar" for the second one?

[1,2,3].map(function (x) { return x * x }); // current implementation, or even with exp.closures function (x) x * x

[1,2,3].map(fun(x) { x * x }); // suggested which will cause "LL(infinity) grammar" issue

I didn't even consider the fact that "fun" won't be a keyword in discussed variation of proposal (@ohunt clarified on Twitter). Then of course the parser ambiguity is understandable.

But I don't think I'd like the language where "fun" may be a variable name and at the same time create a function (of course if "fun" isn't a keyword in such system). How was such system considered at all then? Of course "fun" in my misunderstanding was a keyword. Actually, ES5 already has such case, when a keyword - is normal identifier name, but because of e.g. "function" is a keyword there is no ambiguity:

this.function = function() {}; // global "function" function

this.function(); // OK function(); SyntaxError, there's no LL(∞) problem, of course

Dmitry.

# Waldemar Horwat (15 years ago)

Peter van der Zee wrote:

My vote would go to leave function as it is, if not then to use lambda or florin and otherwise something like the above. Reserve # and @ for new syntax.

I second that.

Waldemar
# Irakli Gozalishvili (15 years ago)

On Mon, Jul 26, 2010 at 10:15, Dmitry A. Soshnikov < dmitry.soshnikov at gmail.com> wrote:

That's look interesting, yeah, I (personally) like it. Also beside => can be used "traditional" function definition sign of some functional (and not only functional) languages: ->

Coffee (while using -> for functions) uses => sugar for binding the this value with defining a function at the same time: jashkenas.github.com/coffee-script/#fat_arrow which I think also a good sugar for .bind method.

  • 1 (my two cents here)

Another I thing good point here is that CoffeeScript is a working & successful proof of concept and many webdevs are already familiar with it. Acquiring even more of it's syntax may be a good ide!!

-- Irakli Gozalishvili Web: www.jeditoolkit.com Phone: +31 614 205275 Address: 29 Rue Saint-Georges, 75009 Paris, France goo.gl/maps/3CHu