Function Syntax

# Douglas Crockford (14 years ago)

ECMAScript has a large set of problems. I think that the fact that 'function' has eight letters is at the bottom of the priority list. And yet, I am open to the possibility of introducing new syntactic sugar to the language to make the expression of functions more elegant.

I look at ECMAScript as serving four groups:

  1. The beginners for whom the language was designed.
  2. The web developers who owe their livelihoods to the language.
  3. The scientists who will use the language for greatness.
  4. Language designers and critics.

I want to improve the language for the first three groups. I don't believe it will be possible to please the fourth group, so we shouldn't even try.

The language has difficult syntax due to its C/Fortran heritage which daily makes the use of the language unnecessarily painful. I would like to repair the traps and confusions so that the language can be practiced more productively. Brendan says that that ship has sailed, or sunk, but I think introduction of expressive function syntax gives us some license to reconsider some things.

Some of the proposals and wishes for new syntax are alarming, in that they appear to be increasing the problem set, rather than reducing it. For example, the language has a confusion between blocks and object literals. Any new syntax should reduce or eliminate this confusion, not amplify it.

I see this design problem as an intricate puzzle. There are many conflicting goals, and the solution is far from obvious. If we can solve it, and I am unreasonably optimistic that a solution is possible, then we will have obtained a language that is easier to read, easier to write, and more resistant to error. If we get it wrong, then we will have accomplished something far worse than having done nothing.

I want to make the language easier to beginners to learn, streamlining the syntax, replacing automatic semicolon insertion with statements that are by design semicolon free.

I want to smooth over the language's rough areas so that web applications can be developed more effectively, with fewer nasty surprises.

And I want the language to help us better harness the power of the function. I think that is the best path for keeping this language viable for many years.

At this point I do not know what the language should look like. But I think I will know it when I see it.

# Isaac Schlueter (14 years ago)

As always, very well put, Douglas.

On Tue, May 10, 2011 at 16:53, Douglas Crockford <douglas at crockford.com> wrote:

ECMAScript has a large set of problems. I think that the fact that 'function' has eight letters is at the bottom of the priority list. And yet, I am open to the possibility of introducing new syntactic sugar to the language to make the expression of functions more elegant.

I look at ECMAScript as serving four groups:

  1. The beginners for whom the language was designed.
  2. The web developers who owe their livelihoods to the language.
  3. The scientists who will use the language for greatness.
  4. Language designers and critics.

I think that there is a very subtle way in which Ruby's blocks are perceived, largely because they involve less ceremony than JavaScript's functions. Making the expression of functions more elegant will go a long way towards making newcomers grok their importance and power, as well as a lot of typing (and visual clutter) for those of us in the second group.

Some of the proposals and wishes for new syntax are alarming, in that they appear to be increasing the problem set, rather than reducing it. For example, the language has a confusion between blocks and object literals. Any new syntax should reduce or eliminate this confusion, not amplify it.

+1.

I want to make the language easier to beginners to learn, streamlining the syntax, replacing automatic semicolon insertion with statements that are by design semicolon free.

Some of us are already writing JavaScript this way :)

The newline elision thing is unnecessarily persnickety, though.

# David Herman (14 years ago)

I want to make the language easier to beginners to learn, streamlining the syntax, replacing automatic semicolon insertion with statements that are by design semicolon free.

Can I ask what you mean by this? Just an illustrative example would probably be enough.

Thanks,

# Brendan Eich (14 years ago)

On May 10, 2011, at 4:53 PM, Douglas Crockford wrote:

The language has difficult syntax due to its C/Fortran heritage which daily makes the use of the language unnecessarily painful. I would like to repair the traps and confusions so that the language can be practiced more productively. Brendan says that that ship has sailed, or sunk,

No, I have a proposal, IIRC you liked it:

strawman:paren_free

It also allows us to clean the for-in slate so ' for v in [1, 2, 3] {...}' iterates over the values 1, 2, and 3.

but I think introduction of expressive function syntax gives us some license to reconsider some things.

Definitely.

Some of the proposals and wishes for new syntax are alarming, in that they appear to be increasing the problem set, rather than reducing it. For example, the language has a confusion between blocks and object literals. Any new syntax should reduce or eliminate this confusion, not amplify it.

Working on that. I'll mail when the strawman:arrow_function_syntax page has been upated.

I see this design problem as an intricate puzzle. There are many conflicting goals, and the solution is far from obvious. If we can solve it, and I am unreasonably optimistic that a solution is possible, then we will have obtained a language that is easier to read, easier to write, and more resistant to error. If we get it wrong, then we will have accomplished something far worse than having done nothing.

The elephant in the room is significant whitespace including newlines. I have said this seems something we can't standardize in ECMA-262. I think this for a couple of reasons:

  1. Because it requires new lexical and syntactic grammars, and possibly a CoffeeScript-like "rewriter" in between.

  2. Changing to significant space and newlines risks changing the meaning of extant JS. Consider CoffeeScript's paren-free actual parameter lists to function calls.

Maybe there's a safe and modular way to "add" significant whitespace and newlines. But we'll need the current mostly-insignificant spec language forever, for non-opt-into-Harmony code, so some variant of 1 remains.

# Allen Wirfs-Brock (14 years ago)

On May 10, 2011, at 4:53 PM, Douglas Crockford wrote:

I look at ECMAScript as serving four groups:

  1. The beginners for whom the language was designed.
  2. The web developers who owe their livelihoods to the language.
  3. The scientists who will use the language for greatness.
  4. Language designers and critics.

I'm not exactly sure what you mean by "scientists". The third group I would identify are professional software developers who will use the language to implemented complex applications of the soft that today are more commonly implemented using Java, C++, etc. These are larger systems that need more emphasis upon upon abstraction building in order to manage the domain and application complexity.

At a meeting today, the dichotomy we used in talking about this is the difference between "imperative programmers" and "abstraction builders". Imperative programmer know how to use basic imperative statements to manipulate predefined abstractions. Abstraction builders create such abstractions. I think that all of your #1 and much of #2 are "imperative programmers". While we need to continue to improve the language for this group we also need to start better serving the needs of the abstraction builders. Much of what we have promoted to proposal status seems to be oriented target on this latter group.

# John J. Barton (14 years ago)

On 11:59 AM, Allen Wirfs-Brock wrote:

On May 10, 2011, at 4:53 PM, Douglas Crockford wrote:

I look at ECMAScript as serving four groups:

  1. The beginners for whom the language was designed.
  2. The web developers who owe their livelihoods to the language.
  3. The scientists who will use the language for greatness.
  4. Language designers and critics.

I'm not exactly sure what you mean by "scientists". The third group I would identify are professional software developers who will use the language to implemented complex applications of the soft that today are more commonly implemented using Java, C++, etc. These are larger systems that need more emphasis upon upon abstraction building in order to manage the domain and application complexity.

At a meeting today, the dichotomy we used in talking about this is the difference between "imperative programmers" and "abstraction builders". Imperative programmer know how to use basic imperative statements to manipulate predefined abstractions. Abstraction builders create such abstractions. I think that all of your #1 and much of #2 are "imperative programmers". While we need to continue to improve the language for this group we also need to start better serving the needs of the abstraction builders. Much of what we have promoted to proposal status seems to be oriented target on this latter group.

Both application developers and library/framework developers benefit from clear, widely understandable code. Adding bizarre special characters and programming constructs that require world-class programming language expertise to understand helps neither group.

jjb

# Garrett Smith (14 years ago)

On 5/10/11, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

On May 10, 2011, at 4:53 PM, Douglas Crockford wrote:

I look at ECMAScript as serving four groups:

  1. The beginners for whom the language was designed.
  2. The web developers who owe their livelihoods to the language.

Library users.

  1. The scientists who will use the language for greatness.

Not much greatness in web development these days, is there?

  1. Language designers and critics.

I'm fine with calling these traits; calling them mutually exclusive categories is a thinking error.

I'm not exactly sure what you mean by "scientists". The third group I would identify are professional software developers who will use the language to implemented complex applications of the soft that today are more commonly implemented using Java, C++, etc. These are larger systems that need more emphasis upon upon abstraction building in order to manage the domain and application complexity.

At a meeting today, the dichotomy we used in talking about this is the difference between "imperative programmers" and "abstraction builders". Imperative programmer know how to use basic imperative statements to manipulate predefined abstractions. Abstraction builders create such abstractions. I think that all of your #1 and much of #2 are "imperative programmers". While we need to continue to improve the language for this group we also need to start better serving the needs of the abstraction builders. Much of what we have promoted to proposal status seems to be oriented target on this latter group.

The mentality that "imperative programmers" and "abstraction builders" are non-overlapping is a thinking error that pissed me off to the end of my career as a javascript programmer.

Abstractions aren't to be done by the ivory tower architect (or "js library author" or "javascript guru"). They're created out of need. The need comes from fulfilling the requirements. I recommend Domain Driven Design, by Eric Evans (and I have a copy for sale, in excellent condition).

Please don't design Ecmascript based on categorizational false dichotomies.

# Claus Reinke (14 years ago)

ECMAScript has a large set of problems. I think that the fact that 'function' has eight letters is at the bottom of the priority list.

  • fixing ECMAScript's oddities would be worth a language revision, even without adding anything new

  • ECMAScript's oddities have been deployed, resulting in a big momentum against change

  • adding new features stirs up discussion, but much less so than changing old features

  • if new features allow programmers to avoid the oddities in old features, the reasons for clinging to odd-but-deployed disappear, at which point the old features can be deprecated

  • fixing ECMAScript problems is great; offering alternatives to problematic features that resist immediate fixing is a slower path, but sometimes the only way to make progress

  • good functional programming support allows to build abstractions, both to work around some of the remaining language problems, and to provide new solutions to application domain problems

  • a large number of ECMAScript problems intersect with functions (including but not limited to: implicit this, arguments, mutability, scoping, expressions vs statements, blocks vs objects, restricted production for return, ..)

So, progress on the function front (beyond shorter keywords) has a high payoff and is difficult, unless the issues can be treated one by one; if the issues can be treated one-by-one, then syntax is one of them; if the syntax issue is easy to solve, progress there can provide motivation for going back to work on the harder issues.

More concise function syntax is important, as long as the deeper issues get resolved, too. As long as new syntax does not introduce new issues, does not try to patch over real issues with mere sugar, and does not distract from tackling the other issues, there is nothing wrong with concise function syntax.

It might be easier to converge on a syntax after solving the other issues, though, and syntax always induces intense discussions, which leads others to fear that their work on other issues gets drowned and ignored among the flood of syntax threads.

I look at ECMAScript as serving four groups:

  1. The beginners for whom the language was designed.
  2. The web developers who owe their livelihoods to the language.
  3. The scientists who will use the language for greatness.
  4. Language designers and critics.

I want to improve the language for the first three groups. I don't believe it will be possible to please the fourth group, so we shouldn't even try.

Sorry to be the bearer of bad news, but if we contribute to es-discuss, we are involved in language design, acting as language designers. We can acknowledge this, and try to do the best we can, including profiting from previous design experience, or we can try to hide from this fact, probably resulting in a botched design job.

I don't understand your group 3, and I don't think denial of group 4 is helpful. Also, there are several groups missing, so let me try to start revising that list:

  1. beginners (also: casually interested web designers)
  2. professional web developers
  3. language implementers
  4. library/framework providers
  5. tool builders
  6. theory providers (static analyses, optimizations, ..)

I haven't listed language designers separately, both because most of what goes on here on es-discuss involves language design, and because language design is still mostly experience- driven, without direct formal foundations. Some day, there might be a science of language design, but for now, we have to make do with the fragments provided by all those groups.

And that still doesn't account for all middle men: eg, model-driven development and domain-specific languages seem to have reached the programming masses ("mass" in the Java sense, not the even larger Javascript sense of the term). One core aspect of these is that the "professional developer" group gets split into "abstraction builders" (using Allen's term) and "abstraction users".

That also means that support for language-design-in-the-small is now an important factor, too: if professional developers working as abstraction builders cannot embed their DSLs in Javascript, they are going to compile their DSLs to Javascript (or bypass Javascript alltogether, for instance, by generating native code for multiple mobile phone platforms from Java-backed DSLs).

The growing number of Javascript pre-processors in production use (not to mention the steady stream of experimental pre-processors) is another indication that the language is lacking the flexibility that professional developers need. Those abstractions should expressible as library code, not as bolted-on source transformations.

The language has difficult syntax due to its C/Fortran heritage which daily makes the use of the language unnecessarily painful. I would like to repair the traps and confusions so that the language can be practiced more productively.

That would be great. It isn't a popular task, needing solutions to difficult problems in the face of deployed-code inertia. It also does not advertize as well as fancy new features. But I agree that working out the kinks would be a very important contribution.

Some of the proposals and wishes for new syntax are alarming, in that they appear to be increasing the problem set, rather than reducing it. For example, the language has a confusion between blocks and object literals. Any new syntax should reduce or eliminate this confusion, not amplify it.

Again, an important consideration to keep in mind. Assuming the motivation is to provide alternative language constructs, in order to ease the long-term transition away from problematic existing constructs, it is essential to separate the consolidation aspects (how is this feature going to improve the language foundations) from the experimentation aspects (what else can we do with this feature?).

It is also worrying that the old features have taken so much of the available syntax, and that the new features are trying to fit into the gaps. If the new features are going to replace the old, we do not want to end up with a syntax that was build from left-overs; nor do we want to have to explain that JavascriptX looks the way it does because its features had to be built around the limitations imposed by oddities of ES5.

Which is another way to say that fixing those problems should have a higher priority: unrewarding and long-term it may be, but if the old problems keep interfering with the design of desirable new features, tackling the old hard problems first might be the only way to make progress.

I see this design problem as an intricate puzzle. There are many conflicting goals, and the solution is far from obvious. If we can solve it, and I am unreasonably optimistic that a solution is possible, then we will have obtained a language that is easier to read, easier to write, and more resistant to error. If we get it wrong, then we will have accomplished something far worse than having done nothing.

Which is what language design is all about!-)

I want to make the language easier to beginners to learn, streamlining the syntax, replacing automatic semicolon insertion with statements that are by design semicolon free.

I want to smooth over the language's rough areas so that web applications can be developed more effectively, with fewer nasty surprises.

And I want the language to help us better harness the power of the function. I think that is the best path for keeping this language viable for many years.

Claus

# Brendan Eich (14 years ago)

On May 11, 2011, at 8:52 AM, Claus Reinke wrote:

ECMAScript has a large set of problems. I think that the fact that 'function' has eight letters is at the bottom of the priority list.

  • fixing ECMAScript's oddities would be worth a language revision, even without adding anything new

This is a mistake. The Web does not permit "stop the world and fix all known bugs". Neither users nor competing browser or server-side software vendors will stop.

Worse, this is a big, defiant, boastful, and at the limit palpably false claim, against our own fallibility and partial knowledge, that we can "fix ECMAScript".

We do not all even agree on what the problems are. The ones that we agree on, we are successfully working on (modules, e.g.). Classes have had a rough time because we don't even agree on premises or problems, never mind conclusions or solutions.

I'm working on better syntax, to present at the next TC39 meeting. I don't think "perfect" is an option in this life. I'm aiming at "better".

More concise function syntax is important, as long as the deeper issues get resolved, too.

What deeper issue beyond |this| binding (lexical, dynamic, soft, etc.) do you mean, precisely?

We've already rejected lambdas, several times.

I'll keep it short by stopping here. Precision in stating problems would be appreciated.

# Brendan Eich (14 years ago)

On May 11, 2011, at 9:12 AM, Brendan Eich wrote:

On May 11, 2011, at 8:52 AM, Claus Reinke wrote:

More concise function syntax is important, as long as the deeper issues get resolved, too.

What deeper issue beyond |this| binding (lexical, dynamic, soft, etc.) do you mean, precisely?

I have another not-just-syntax issue beyond |this|-binding, already raised (brendaneich.com/2011/01/harmony-of-my-dreams "tail position"):

We already approved harmony:proper_tail_calls -- great. But you have to write "return expr" to put "expr" in tail position. Just "function f(){g()}" does not put the call to "g" in tail position.

Wherefore the controversial idea of strawman:completion_reform and the reformed completion value as the implicit return value of new-syntax (-> or whatever we decide on) functions.

This has syntax helping better semantics. It's not just one or the other. It is on the boards. Alas, some fear (perhaps justifiably) completion value leaks, including unintended capability leaks.

There's no perfect answer. Shorter return syntax ("^" with an ASI change, or my "empty label" idea, "function f(){:g()}") is ugly, adds overhead, and can still be left off by mistake (making for the opposite problem from the capability leak one: returning undefined instead of the intended result of an expression evaluation).

I still think the completion value leak problem is manageable with docs, tools, and resort to good old "function" long-hand syntax. Opinions?

# David Herman (14 years ago)

There's no perfect answer. Shorter return syntax ("^" with an ASI change, or my "empty label" idea, "function f(){:g()}") is ugly, adds overhead, and can still be left off by mistake (making for the opposite problem from the capability leak one: returning undefined instead of the intended result of an expression evaluation).

For example:

array.map(function(x) { x * 2 }) // oops!

Also, any explicit return syntax has a "Tennent" problem just like return does. Moreover, it forces programmers to write imperatively (return is a non-local jump), when so much of JS code makes effective use of expression-based programming -- for example, the popular "method chaining" style, which is essentially functional programming with methods.

I still think the completion value leak problem is manageable with docs, tools, and resort to good old "function" long-hand syntax. Opinions?

I agree. But I am sympathetic to Doug's concern about further overloading the curly-brace syntax.

# Brendan Eich (14 years ago)

On May 11, 2011, at 9:32 AM, David Herman wrote:

I agree. But I am sympathetic to Doug's concern about further overloading the curly-brace syntax.

That is purely a syntactic problem. More soon, tomorrow I hope.

# Douglas Crockford (14 years ago)

On 5/11/2011 9:19 AM, Brendan Eich wrote:

I still think the completion value leak problem is manageable with docs, tools, and resort to good old "function" long-hand syntax. Opinions?

We have observed that one of the world's best capability theorists and practitioners, intending to to write solid code with capability discipline, was tripped up by completion value leakage. I think it is a real problem, and I think it requires either some sort of declaration saying that no completion value should be returned from the function, or an explicit return as we have now.

# David Herman (14 years ago)

Evidence is good, but that's not exactly scientific. In particular, I'd wager there's a material difference in this phenomenon between a language in which all functions implicitly return and one in which this is only the case for a specific convenience form.

That said, we could also consider a variant that forces the function to return undefined. (For a semi-concrete example, the 'void' keyword might fit in the surface syntax somewhere.)

# Brendan Eich (14 years ago)

On May 11, 2011, at 9:39 AM, Douglas Crockford wrote:

We have observed that one of the world's best capability theorists and practitioners, intending to to write solid code with capability discipline, was tripped up by completion value leakage. I think it is a real problem, and I think it requires either some sort of declaration saying that no completion value should be returned from the function, or an explicit return as we have now.

Let's quote Mark fully, ok? I am pretty sure it is ok with Mark to cite his words in full (from private correspondence):

On May 3, 2011, at 1:43 PM, Mark S. Miller wrote:

In an earlier version of E, it was everywhere the case that returning an implicit last value was syntactically a bit more convenient than ensuring that no last value was returned. Although I took more pains to avoid accidental leakage than I think we can expect of the typical JS programmer ;), even in my own code, the desire for brevity led to several security holes which MarcS caught.

To fix this, current E has two function definition syntaxes, stylistically used very much like Smalltalk's distinction between methods and blocks. The method-like case is used for named functions, for methods, and for anonymous functions which were really thought of as first class values, whose lifetimes might exceed that of their creating context. For these, the briefer syntax no longer returns a value. The block-like syntax is used almost exclusively for control abstractions, as in the arguments to, for example, the higher order array methods. Outside the code defining new control abstractions, these blocks were rarely passed as first class values; and the control abstractions themselves AFAIK never leak them.

Under this discipline, the block-like syntax really feels like a generalization of conventional blocks, as they do in Smalltalk. E, being an expression language, already treated actual blocks as expressions with values, so treating these block-like functions this way seemed natural. Since switching to this discipline, I am not aware any of any further leakage bugs of that nature.

Several observations:

  1. E is an expression language. JS would need opt-in syntax to make a sub-language (e.g. arrow function bodies) an expression language, and you'd still have plausible objections that with statements on the outside and expressions on the inside, programmers would not mind the gap and make both capability-leak and undefined-return bugs.

  2. Based on (1), we don't know why it became conventional (but not mandatory) in E that "blocks were rarely passed as first class values; and the control abstractions themselves AFAIK never leak them." The E experience is suggestive but mainly due to (1), curse JS's Java/C patrimony, inconclusive.

  3. Blocks as implicitly quoted code could be like zero-argument lambdas, with break, continue, return, |this|, and |arguments| referred to any outer function or loop/switch statement. This suggests something like the Ruby-ish syntax Isaac sketched recently, mooted by various people in the past:

    array.map({|x| x * 2 }) // YAY!

Problems:

3a. Basis case is {}, an object initialiser. Patchable by requiring {||}, but ugh.

3b. The objection raised repeatedly when we discussed lambdas here, that return unwinding an outer function, or throwing an error if the outer function call has already returned, is as big a hazard and source of confusion as -- or bigger than! -- any completion-return downside.

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for harmony:parameter_default_values. We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good. Should we reconsider them?

# Dean Landolt (14 years ago)

On Wed, May 11, 2011 at 12:46 PM, David Herman <dherman at mozilla.com> wrote:

Evidence is good, but that's not exactly scientific. In particular, I'd wager there's a material difference in this phenomenon between a language in which all functions implicitly return and one in which this is only the case for a specific convenience form.

That said, we could also consider a variant that forces the function to return undefined. (For a semi-concrete example, the 'void' keyword might fit in the surface syntax somewhere.)

It fits nicely today:

void (function() { return 1 })() == null // true

That reads just as well with a sugared function/return, I'd wager. JSLint could even be configured to require it :)

# Brendan Eich (14 years ago)

On May 11, 2011, at 9:53 AM, Brendan Eich wrote:

  1. E is an expression language. JS would need opt-in syntax to make a sub-language (e.g. arrow function bodies) an expression language, and you'd still have plausible objections that with statements on the outside and expressions on the inside, programmers would not mind the gap and make both capability-leak and undefined-return bugs.

  2. Based on (1), we don't know why it became conventional (but not mandatory) in E that "blocks were rarely passed as first class values; and the control abstractions themselves AFAIK never leak them." The E experience is suggestive but mainly due to (1), curse JS's Java/C patrimony, inconclusive.

Beyond the muddy statement/expression JS waters, if I understand correctly, E has only convention on the side of blocks for control effects, whose completion results are the results of enclosing expressions, without capability leak bugs in practice.

It seems you want something less advisory, like always-on mandatory requirements that programmers annotate either return values or voided function calls. Do I have that right?

  1. Blocks as implicitly quoted code could be like zero-argument lambdas, with break, continue, return, |this|, and |arguments| referred to any outer function or loop/switch statement. This suggests something like the Ruby-ish syntax Isaac sketched recently, mooted by various people in the past:

    array.map({|x| x * 2 }) // YAY!

Problems:

3a. Basis case is {}, an object initialiser. Patchable by requiring {||}, but ugh.

3b. The objection raised repeatedly when we discussed lambdas here, that return unwinding an outer function, or throwing an error if the outer function call has already returned, is as big a hazard and source of confusion as -- or bigger than! -- any completion-return downside.

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for harmony:parameter_default_values. We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good. Should we reconsider them?

3c is really about how odd it is to put formal parameters inside anything other than (...).

3d. No |this| so no relief for functions as methods taking dynamic-|this| vs. functions with lexical |this|. We could work on 'function' syntax, and methods in extended object initialisers, but it seems to me the block syntax would be wanted for "methods" too, given how long 'function' is.

Adding something function-like, but not close enough, adds complexity. It's a bit odd that purely syntactic sugar is considered complex by some folks, but adding something new in both syntax and semantics is ok (if you come with the right history, e.g. Ruby). Well, maybe not odd, but not conclusive and something to be skeptical about, IMHO.

FTR I'm still in favor of shorter function syntax, working on better arrow-function grammar.

# Mark S. Miller (14 years ago)

On Wed, May 11, 2011 at 9:53 AM, Brendan Eich <brendan at mozilla.com> wrote:

On May 11, 2011, at 9:39 AM, Douglas Crockford wrote:

We have observed that one of the world's best capability theorists and practitioners, intending to to write solid code with capability discipline, was tripped up by completion value leakage. I think it is a real problem, and I think it requires either some sort of declaration saying that no completion value should be returned from the function, or an explicit return as we have now.

Let's quote Mark fully, ok? I am pretty sure it is ok with Mark to cite his words in full (from private correspondence):

It's perfectly fine this time. But please do check in the future. Thanks.

More later when I have time.

# Jorge (14 years ago)

On 11/05/2011, at 18:53, Brendan Eich wrote:

(...)

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for harmony:parameter_default_values. We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

I don't think it's a problem, after all that's what parenthesis are for.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good.

Yes, [ ... ].forEach( {| v, i, o | ... } ) would be awesome, and {| n | while (n--) buffer[n]= 0 }( buffer.length ) is even beautiful.

Should we reconsider them?

Yes. Ruby's blocks, pure win. :-)

# Brendan Eich (14 years ago)

On May 11, 2011, at 11:26 AM, Jorge wrote:

On 11/05/2011, at 18:53, Brendan Eich wrote:

(...)

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for harmony:parameter_default_values. We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

I don't think it's a problem, after all that's what parenthesis are for.

No, formal parameter list delimiting is what parentheses in function-like declarations and expression are for. In JS.

More below, but confirmation bias or assuming the Ruby conclusion seems a real problem in evaluating this idea qua JS.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good.

Yes, [ ... ].forEach( {| v, i, o | ... } ) would be awesome, and {| n | while (n--) buffer[n]= 0 }( buffer.length ) is even beautiful.

It's not bad but the || are a bit odd for JS. Not for Ruby, for JS.

Should we reconsider them?

Yes. Ruby's blocks, pure win. :-)

You skipped 3b.

Rubyists should view their pre-existing knowledge and experience through a skeptical lens. Pretend you're new to JS and you don't know Ruby (or Smalltalk). You do know languages with statements, including things like break, continue, and return.

# Allen Wirfs-Brock (14 years ago)

On May 11, 2011, at 7:40 AM, Garrett Smith wrote:

On 5/10/11, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

At a meeting today, the dichotomy we used in talking about this is the difference between "imperative programmers" and "abstraction builders". Imperative programmer know how to use basic imperative statements to manipulate predefined abstractions. Abstraction builders create such abstractions. I think that all of your #1 and much of #2 are "imperative programmers". While we need to continue to improve the language for this group we also need to start better serving the needs of the abstraction builders. Much of what we have promoted to proposal status seems to be oriented target on this latter group.

The mentality that "imperative programmers" and "abstraction builders" are non-overlapping is a thinking error that pissed me off to the end of my career as a javascript programmer.

Who said they are "non-overlapping". Obviously there is a continuum and at various times and for various tasks a single individual can be at different places along the continuum.

Abstractions aren't to be done by the ivory tower architect (or "js library author" or "javascript guru"). They're created out of need. The need comes from fulfilling the requirements. I recommend Domain Driven Design, by Eric Evans (and I have a copy for sale, in excellent condition).

I don't see where I said or implied anything about this either. Abstraction is tool for dealing with complexity. It is essential for deal with any sizable programming problem. It is a skill that has to learned. Many "imperative" programmers have not yet learned this skill and you can see it in the code they write when they try to deal with complex situations.

When you sell your copy of DDD I recommend you use the proceeds to get wirfs-brock.com/DesignBooks.html I know Eric did.

Please don't design Ecmascript based on categorizational false dichotomies.

Different language features exist to serve different use cases. The features you need to build good abstractions are not the same feature you need to easy express sequences of imperative actions. I don't think anybody would be very happy with a language whose designers didn't make an attempt to understand various categories of users and use case and how various features relate to them.

# Allen Wirfs-Brock (14 years ago)

On May 11, 2011, at 9:53 AM, Brendan Eich wrote:

...

  1. Blocks as implicitly quoted code could be like zero-argument lambdas, with break, continue, return, |this|, and |arguments| referred to any outer function or loop/switch statement. This suggests something like the Ruby-ish syntax Isaac sketched recently, mooted by various people in the past:

    array.map({|x| x * 2 }) // YAY!

Problems:

3a. Basis case is {}, an object initialiser. Patchable by requiring {||}, but ugh.

In practice, such null blocks would probably seldom occur. Particularly, if the convention was for functions taking "block" arguments to treat undefined/null as the do nothing block.

3b. The objection raised repeatedly when we discussed lambdas here, that return unwinding an outer function, or throwing an error if the outer function call has already returned, is as big a hazard and source of confusion as -- or bigger than! -- any completion-return downside.

I can't speak to Ruby usage, but such errors are a rare occurrence in Smalltalk where such blocks are the only way to express control abstractions. Don't know if the same would be true for JS. Would people try to use such blocks as event handlers?? The actual runtime test that is needed to test for already returned can be pretty cheap. It would probably be possible to add a way to test whether a block contains any non-local exists. Any code that wants to make sure it doesn't see should errors could test their block arguments before stashing them way. Of course, that just replace on error with a different earlier error.

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for harmony:parameter_default_values. We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good. Should we reconsider them?

I think this is an area that really cries out for an experimental design and implementation.

# Claus Reinke (14 years ago)

ECMAScript has a large set of problems. ..

  • fixing ECMAScript's oddities would be worth a language revision, even without adding anything new

This is a mistake. The Web does not permit "stop the world and fix all known bugs". Neither users nor competing browser or server-side software vendors will stop.

Ideals are like stars - out of reach, but good for orientation.

The fixes alone would be worth a revision, and a competitive advantage (for language implementers and programmers, though the both would be limited by code having to work with other browsers). That ideal does not mean that language changes should not be introduced incrementally (refactoring beats rewriting). It only means that fixes can be as valuable as new features.

We do not all even agree on what the problems are. The ones that we agree on, we are successfully working on (modules, e.g.). Classes have had a rough time because we don't even agree on premises or problems, never mind conclusions or solutions.

Douglas will speak for himself, I'm sure, but my own interpretation of his remarks was that most current work seems focused on extensions to the house, while there are some concerns about the foundation (not limited to functions).

It wouldn't be too bad if some people work on the foundations and others on the extensions, but since the extensions are so much more immediately rewarding, it is easy to get carried away. In particular, one might worry about extensions introducing more problems and complexity, together with new features.

Removing unnecessary complexity will also make it easier to add new features (fewer interactions to consider).

Another way to look at it: independent of the concrete problems which you are working on, there seem to be some meta-level problems that keep coming up and get in the way of designing solutions. If that happens often enough, it may be worth stepping back and solve the meta-level problem first (no matter how horribly difficult to handle that elephant looks;-).

I'm working on better syntax, to present at the next TC39 meeting. I don't think "perfect" is an option in this life. I'm aiming at "better".

Better is the road to perfect.

More concise function syntax is important, as long as the deeper issues get resolved, too.

What deeper issue beyond |this| binding (lexical, dynamic, soft, etc.) do you mean, precisely?

I don't yet have a complete enough overview for detailed language criticism, but I've been posting my concerns here as I encountered them.

It would be good to have a process for registering information and suggestions with the committee and get feedback about the official reactions to such suggestions (an es-discuss bug tracker perhaps, separate from the spec bug tracker?).

At this stage of my exploration, the main items seem to be:

  • expressions vs statements this is well-known and would be hard to fix (too big a change for javascript), beyond simplifying workarounds (such as parameterless functions as block "values");

  • grammar too many details are hard-coded here: that makes the language complex and inflexible for the language design process (syntax should not get in the way as often as it does here), and limits language expressiveness for programmers (especially for abstraction providers); more of the changes that occupy TC39 should be possible at the level of libraries, not language;

  • program equivalences what equivalences hold for js code? Language implementers, tool builders, and programmers depend on being able to reason about code (optimizations, refactorings, code reading, maintenance, bug fixing);

    language-level equivalences are the most practical side of semantic tools: no need to reason about abstract machine details, or machine code, or mathematical constructs, just "this high-level code fragment is equivalent to that one"/ "we can replace this with that and nothing will go wrong";

    obviously, reflection breaks all equivalences (which is one reason why mirrors and the like have been introduced: to delimit the code affected by reflection); but even without reflection interference, it seems difficult to find valid code equivalences for javascript;

    the more each instance of code has to be understood on its own -rather than by relation/equivalence/simplification, the more complex the language gets;

    it is great to have a detailed language spec (really! not all languages have one), but if we have to keep looking there, to understand why obvious code equivalences fail in javascript, the language becomes arcane (which is good for consultant experts, bad for everyone else);

There are smaller items (some are instances of the above):

  • objects vs blocks; grammar ambiguities;

  • ASI coupling to combination of linebreak, error, restricted productions serves neither full-ASI nor no-ASI proponents, and complicates language extensions;

  • mixing numeric indices and string properties (every object is an array, only Array instances have proper array methods); dynamic typing is much less problematic without implicit conversions muddying the waters;

  • var initializers shadow bindings in their rhs (similar to 'this' and 'arguments' shadowing, but worse through 'undefined'); do we really need a different solution to each instance of shadowing problems? differences make for language complexity, extracting common solutions to common problems simplifies understanding;

  • argument lists as arrays (instead of arrays as arguments) [this seems to be worked on];

  • ephemeral nature of References; leads to syntactic junk in the language (syntactically valid code that predictably leads to runtime errors); also limits object methods as first-class values (they lose their base reference), breaks a dozen of "obvious" code equivalences (is this also behind direct vs indirect eval? I haven't checked yet);

  • hardcoding of binary ops/precedences/associativity in grammar; these are much too variable to be written in stone, or be discussed by a language committee; for javascript to be adapted quickly to new domains, these should be in the hands of library authors and other abstraction providers;

    much too valuable a tool to ignore; if combined with lightweight function definition and application syntax, it helps in defining readable domain-specific languages;

    commonalities in embedded domain-specific languages feed back into general purpose control abstractions, which again should be provided in libraries (moving more quickly than language committees);

Perhaps there were other items I don't recall right now (with a tracker, I could just look up my tickets, you could assign priorities, milestones, and committee members for those items you would want to adopt, and we'd all know where our suggestions stand).

I'll keep it short by stopping here. Precision in stating problems would be appreciated.

I hope this helps? Claus

# Brendan Eich (14 years ago)

On May 12, 2011, at 7:42 AM, Claus Reinke wrote:

ECMAScript has a large set of problems. ..

  • fixing ECMAScript's oddities would be worth a language revision, even without adding anything new This is a mistake. The Web does not permit "stop the world and fix all known bugs". Neither users nor competing browser or server-side software vendors will stop.

Ideals are like stars - out of reach, but good for orientation.

Bodies were heaped by the millions over the last few centuries in the name of ideals. I detest a priori systems that ignore empircal results. I don't buy "ideal" without "real". Your message is woefully lacking in "real".

The fixes alone would be worth a revision, and a competitive advantage (for language implementers and programmers, though the both would be limited by code having to work with other browsers). That ideal does not mean that language changes should not be introduced incrementally (refactoring beats rewriting). It only means that fixes can be as valuable as new features.

This is all vague sermonizing. Please stop.

There's a dream syntax Doug can glimpse (maybe I can too; working on it still) that might be called a "fix". It relieves us of semicolons and ASI without creating runtime migration traps.

Ok, show it. Or show a way to find it, a concrete method. The endless ideal-mongering and vagueness don't cut it, and they are actually adding noise and making trouble.

If we keep this up, we will have neither fixes (including the ones in hand, e.g. lexical scoping) nor new features in ES.next.

We do not all even agree on what the problems are. The ones that we agree on, we are successfully working on (modules, e.g.). Classes have had a rough time because we don't even agree on premises or problems, never mind conclusions or solutions.

Douglas will speak for himself, I'm sure, but my own interpretation of his remarks was that most current work seems focused on extensions to the house, while there are some concerns about the foundation (not limited to functions).

Vague words, and where testable, precisely wrong. Lexical scope all the way up, modules, let, const, some of the object initialiser extensions, and (I argue) paren-free and the for-in reform it enables -- these are all fixes.

Another way to look at it: independent of the concrete problems which you are working on, there seem to be some meta-level problems that keep coming up and get in the way of designing solutions. If that happens often enough, it may be worth stepping back and solve the meta-level problem first (no matter how horribly difficult to handle that elephant looks;-).

For me to keep parlaying here, you need to be specific or else stop injecting so many generalizations which are either useless, or actually false when applied to specifics I've listed above.

I'm working on better syntax, to present at the next TC39 meeting. I don't think "perfect" is an option in this life. I'm aiming at "better".

Better is the road to perfect.

No, there is no perfect. Get this right, or you are in dreamland (and I am elsewhere).

More concise function syntax is important, as long as the deeper issues get resolved, too. What deeper issue beyond |this| binding (lexical, dynamic, soft, etc.) do you mean, precisely?

I don't yet have a complete enough overview for detailed language criticism, but I've been posting my concerns here as I encountered them. It would be good to have a process for registering information and suggestions with the committee and get feedback about the official reactions to such suggestions (an es-discuss bug tracker perhaps, separate from the spec bug tracker?).

At this stage of my exploration, the main items seem to be:

  • expressions vs statements this is well-known and would be hard to fix (too big a change for javascript), beyond simplifying workarounds (such as parameterless functions as block "values");

Ok, so you say this is not realistically solvable. Why bring it up?

Next:

  • grammar too many details are hard-coded here: that makes the language complex and inflexible for the language design process (syntax should not get in the way as often as it does here), and limits language expressiveness for programmers (especially for abstraction providers); more of the changes that occupy TC39 should be possible at the level of libraries, not language;

You're arguing we can't improve the syntax of the language, even by extension? False: let, const (already in browsers in a form that can be fixed), lexical scope to get the global object off of the scope chain (this is an important security fix), and modules.

Also: libraries are many and evolving, TC39 design-by-committee is about the worst way to invent and evolve a library. We're de-facto standardizing (ES5 did the Array extras, which still have some flaws we cannot fix).

  • program equivalences what equivalences hold for js code? Language implementers, tool builders, and programmers depend on being able to reason about code (optimizations, refactorings, code reading, maintenance, bug fixing);

    language-level equivalences are the most practical side of semantic tools: no need to reason about abstract machine details, or machine code, or mathematical constructs, just "this high-level code fragment is equivalent to that one"/ "we can replace this with that and nothing will go wrong"; obviously, reflection breaks all equivalences (which is one reason why mirrors and the like have been introduced: to delimit the code affected by reflection); but even without reflection interference, it seems difficult to find valid code equivalences for javascript;

(It's not that bad in practice once you [the refactoring entity] buy into having to lex and parse everything. This seems a formal objection.)

the more each instance of code has to be understood on its own -rather than by relation/equivalence/simplification, the more complex the language gets;

it is great to have a detailed language spec (really! not all languages have one), but if we have to keep looking there, to understand why obvious code equivalences fail in javascript, the language becomes arcane (which is good for consultant experts, bad for everyone else);

This is long-winded and vague still (also badly formatted). What is your specific, actionable point?

We can't lose statements with control effects without a big compatibility break, and you ruled out new syntax above. Are you arguing against changing JS, and for inventing a wholly new language?

Just yesterday I re-raised the {|a,b| a+b} Ruby/Smalltalk-inspired block-as-lambda idea recently. It has the advantage of being concrete. It preserves certain program equivalences at the price of creating new runtime error conditions (return from an outer function call that has already returned, e.g.). Please address it specifically, or make a competitive alternative proposal.

There are smaller items (some are instances of the above):

  • objects vs blocks; grammar ambiguities;

This is a glitch JS hackers I've surveyed informally simply learn and get past. They don't even complain about it much, compared to lack-of-ASI (lack of significant newline) traps. I've talked to many over the years.

Anyway, it is not going to be fixed without a new grammar, which you seem to have ruled out above.

  • ASI coupling to combination of linebreak, error, restricted productions serves neither full-ASI nor no-ASI proponents, and complicates language extensions;

Yes, this is true and we've had proposals, including Mark's concrete proposal for a better ASI and Harmony parsing both ways, declaring an early error on disagreement. Unfortunately this requires backtracking and error recovery in a "forked parser", so it looks too complicated for implementors and users, but it was a concrete proposal in the right direction. Please do likewise and stop rehashing the problem statement.

www.mail-archive.com/[email protected]/msg05606.html

  • mixing numeric indices and string properties (every object is an array, only Array instances have proper array methods); dynamic typing is much less problematic without implicit conversions muddying the waters;

I proposed tuples. They got a mixed reaction at the last tc39 meeting, and they are not likely to get into ES.next at this point. Do you have anything to add to this specific proposal, or another alternative specific proposal to make?

strawman:tuples

  • var initializers shadow bindings in their rhs (similar to 'this' and 'arguments' shadowing, but worse through 'undefined'); do we really need a different solution to each instance of shadowing problems? differences make for language complexity, extracting common solutions to common problems simplifies understanding;

This is a topic for let and const in blocks, which is still being debated on-and-off. IIRC most of TC39 agreed to make let and const start a new implicit scope, so an outer name could be used in the initialiser.

Again, we can't change var unless you want us to make incompatible changes, which you seemed to advise against above. Which is it?

  • argument lists as arrays (instead of arrays as arguments) [this seems to be worked on];

It is being worked on, you should know that -- rest and spread are in harmony -- yet you rehash and inject noise again here. Why? To channel Nancy Kerrigan: WHYYYYY???? :-|

harmony:rest_parameters, harmony:spread

  • ephemeral nature of References; leads to syntactic junk in the language (syntactically valid code that predictably leads to runtime errors); also limits object methods as first-class values (they lose their base reference), breaks a dozen of "obvious" code equivalences (is this also behind direct vs indirect eval? I haven't checked yet);

This is not only a minor issue, truly small potatoes -- it is required for web compatibility due to VBScript-tainted JScript of this kind:

d.items(i) = j;

That kind of crap exists in IE-only branches of JS on the web, so it must parse.

Let's focus on real problems affecting real users.

  • hardcoding of binary ops/precedences/associativity in grammar; these are much too variable to be written in stone, or be discussed by a language committee; for javascript to be adapted quickly to new domains, these should be in the hands of library authors and other abstraction providers;

    much too valuable a tool to ignore; if combined with lightweight function definition and application syntax, it helps in defining readable domain-specific languages;

    commonalities in embedded domain-specific languages feed back into general purpose control abstractions, which again should be provided in libraries (moving more quickly than language committees);

Sorry, we're not turning JS into Haskell or making the syntax, particularly the operators, have adjustable precedence and associativity. This is not something developers or implementors want. It has never been on the agenda, even for value types/proxies. You are barking up the wrong tree here.

Perhaps there were other items I don't recall right now (with a tracker, I could just look up my tickets, you could assign priorities, milestones, and committee members for those items you would want to adopt, and we'd all know where our suggestions stand).

I'll keep it short by stopping here. Precision in stating problems would be appreciated.

I hope this helps?

Not really.

I'm being rough on you here because we have a serious (serous enough, for a discussion list I care about not going in ideal-mongering circles or filling with useless noise and posturing) problem. We have real proposals for ES.next on the table. They aren't all necessarily going to make it, but trying to reset the discussion from them to vague ideals or non-issues like programmable operator precedence does a disservice to our common effort here.

We need to get back to discussing the live strawman proposals, and refining the proposals in harmony but not quite spec'ed fully. Will you help?

# Brendan Eich (14 years ago)

On May 11, 2011, at 4:01 PM, Allen Wirfs-Brock wrote:

On May 11, 2011, at 9:53 AM, Brendan Eich wrote:

...

  1. Blocks as implicitly quoted code could be like zero-argument lambdas, with break, continue, return, |this|, and |arguments| referred to any outer function or loop/switch statement. This suggests something like the Ruby-ish syntax Isaac sketched recently, mooted by various people in the past:

    array.map({|x| x * 2 }) // YAY!

Problems:

3a. Basis case is {}, an object initialiser. Patchable by requiring {||}, but ugh.

In practice, such null blocks would probably seldom occur. Particularly, if the convention was for functions taking "block" arguments to treat undefined/null as the do nothing block.

Unlike functions taking function arguments, since null() and undefined() are inevitable errors. Do we really want to fork the funarg world in two?

When I rant against idealism and perfect being possible, I'm not just waxing philosophical. We live in a world of trade-offs. There is "better" but it rarely comes without something, however marginal or minority-share use-case, getting "worse".

Rubyists may cheer blocks in JS but we need to avoid making things strictly more complicated, in fork-the-subset-of-functions-taking-function-arguments terms, e.g.

3b. The objection raised repeatedly when we discussed lambdas here, that return unwinding an outer function, or throwing an error if the outer function call has already returned, is as big a hazard and source of confusion as -- or bigger than! -- any completion-return downside.

I can't speak to Ruby usage, but such errors are a rare occurrence in Smalltalk where such blocks are the only way to express control abstractions. Don't know if the same would be true for JS.

Evidently not unless we model existing control flow statements as magic functions taking blocks. E.g., if is a function taking its condition, then outside the parenthesized (or paren-free if we do that!) condition, one or two blocks.

Would people try to use such blocks as event handlers??

I suggested they would, because the syntax is so much shorter.

The actual runtime test that is needed to test for already returned can be pretty cheap. It would probably be possible to add a way to test whether a block contains any non-local exists. Any code that wants to make sure it doesn't see should errors could test their block arguments before stashing them way. Of course, that just replace on error with a different earlier error.

Right, and a testing via code reflection onus.

Ruby is far from simple, btw. Check out

samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby

and the wikipedia page it references.

Looks like Proc.new but not lambda can return from its caller.

3c. The use of {| (possibly with space in between) is an unambiguous extension, but formal parameters inside |...| delimiters creates a problem for harmony:parameter_default_values. We would need the default value expression to be parenthesized if its precedence were | (bitwise-or) or looser.

Other than these, AFAICT blocks as lambdas offering shorter function-like syntax are pretty good. Should we reconsider them?

I think this is an area that really cries out for an experimental design and implementation.

User testing is hard, lots of confounders, hard to control. We'd need scale. We could try experimental annexes in ES.next for better function syntax, classes, other hard nuts to crack. Advise that if implemented they must track the annexes (or separate TRs, don't care). Only after some consensus emerges (if it does) do we standardize.

I don't see a quantitative way to decide, but this might be worth the overhead. Thoughts?

# Claus Reinke (14 years ago)

Would it be possible for you to follow basic netiquette?

If you do not want to look for useful information in my posts, there is no need for you to reply with unproductive aggression. If you do want to reply to my posts, please do so when you are calm and able to focus on making productive contributions, preferably after spending more than one second on reading and trying to understand what you reply to, just as we do with your posts.

If you do want to restrict this list to certain topics, such as discussing proposals made only by committee members, you could simply state so on the list page. Clarification of list aims and options for non-members to contribute to the proposal process have been asked for here often enough.

Whatever it is you want - it is not acceptable that you leave the burden of trying to keep discussions civil to others.

Claus

PS. I am tooling up to making more concrete suggestions, by reviving jsparse and moving its grammar to ES5. I have the technical background to implement my suggestions but, coming from another language community, I need to get a feeling for what is possible here, politically (preferably without the personal attacks).

It was my understanding that the TC39 had internal
communication channels for refining its proposals, and
that this list was a public-facing add-on. Hence my talking
about suggestions and directions before investing time
implementing anything in detail.

If this isn't the right list to talk about Javascript language
design, please state so on the list page and clarify the
community page entry for es-discuss.

http://www.ecmascript.org/community.php

From: "Brendan Eich" <brendan at mozilla.com>

Sent: Thursday, May 12, 2011 7:06 PM To: "Claus Reinke" <claus.reinke at talk21.com>

Cc: "Douglas Crockford" <douglas at crockford.com>; <es-discuss at mozilla.org>

Subject: Re: Function Syntax

# Brendan Eich (14 years ago)

On May 12, 2011, at 11:27 AM, Claus Reinke wrote:

Would it be possible for you to follow basic netiquette?

I'm trying. Are you? We've been around this block before.

Either there is substance or there isn't. If there's no substantial proposal to discuss, then many paragraphs of generalizations are not welcome.

If you do not want to look for useful information in my posts, there is no need for you to reply with unproductive aggression.

I read all your posts. I found useful information in some (reply coming on one in particular, still recent).

I don't want to ignore your messages, although they are taxing to read (and I'm not alone in remarking on this). You can call my style aggressive if you like, or blunt, but it remains to be seen whether it is "unproductive". Many people ignoring your messages while you keep on writing them would be less productive than the better outcome: cutting the padding and generalities and getting to specifics when you are ready.

If you do want to reply to my posts, please do so when you are calm and able to focus on making productive contributions, preferably after spending more than one second on reading and trying to understand what you reply to, just as we do with your posts.

My posts are notably shorter and I try to avoid generalizing and "preaching".

If you do want to restrict this list to certain topics, such as discussing proposals made only by committee members, you could simply state so on the list page.

No, that's a straw-man argument, easily knocked down. This list exists for non-committee members as well as committee members. My objections are specific and you shouldn't duck them (again, with too many words!).

Clarification of list aims and options for non-members to contribute to the proposal process have been asked for here often enough.

Whatever it is you want - it is not acceptable that you leave the burden of trying to keep discussions civil to others.

I believe I was civil.

Claus

PS. I am tooling up to making more concrete suggestions,

Please do, and until then don't rehash problem statements, generalize about ideals, or sermonize about the perfect. Am I clear and civil? I think so!

# Brendan Eich (14 years ago)

On May 12, 2011, at 10:55 AM, Brendan Eich wrote:

Ruby is far from simple, btw. Check out

samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby

and the wikipedia page it references.

Looks like Proc.new but not lambda can return from its caller.

From en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls it should be clear I was missing the "block" target. Blocks are syntactically restricted to being downward funargs. Only if reified as Procs do they potentially escape to be called later when their lexical parent method could have already returned.

IOW, blocks are restricted to being downward-funargs by syntax at their expression site, and by default in the callee (without the & before the corresponding formal parameter).

When we considered lambdas (the "Allen's lambda syntax proposal" thread from late 2008 to early 2009), we did not try to confine them syntactically to actual parameter lists. Did we miss a key restriction or feature of Ruby? I'm not sure, I'm too much a Ruby n00b.

# Brendan Eich (14 years ago)

On May 12, 2011, at 1:06 PM, Brendan Eich wrote:

On May 12, 2011, at 10:55 AM, Brendan Eich wrote:

Ruby is far from simple, btw. Check out

samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby

and the wikipedia page it references.

Looks like Proc.new but not lambda can return from its caller.

From en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls it should be clear I was missing the "block" target. Blocks are syntactically restricted to being downward funargs. Only if reified as Procs do they potentially escape to be called later when their lexical parent method could have already returned.

IOW, blocks are restricted to being downward-funargs by syntax at their expression site, and by default in the callee (without the & before the corresponding formal parameter).

To say a bit more about this, here's a demo of the downward-only-funarg nature of blocks passed as extra trailing arguments, with no matching &parameters:

def say puts yield "world" end

def say_hello say {|x| "hello #{x}" } end

say_hello

The output is "hello world" of course, but Ruby's yield calls the block without it escaping as a reified Proc that could be invoked later, after the downward flow. Neat!

(Rubyists, please correct anything wrong here.)

I'm not suggesting we copy any of this, just passing along my Ruby-n00b knowledge.

When we considered lambdas (the "Allen's lambda syntax proposal" thread from late 2008 to early 2009), we did not try to confine them syntactically to actual parameter lists. Did we miss a key restriction or feature of Ruby? I'm not sure, I'm too much a Ruby n00b.

If blocks could not escape to be called after their enclosing function had returned, then we would overcome the objection raised last time, articulated best by Maciej:

esdiscuss/2008-December/008390

But Ruby went all the way, allowing a block to grow into a Proc and outlive the method in which the block was expressed. I expect similar "ecological pressures" to apply if we added blocks only as downward-funargs.

Plus, we'd still want shorter function syntax, not just blocks as downward-only funargs (however nice for map, forEach, etc.).

I will write up a block strawman, to give it a fair shake along side strawman:arrow_function_syntax.

# Dmitry A. Soshnikov (14 years ago)

On 13.05.2011 1:25, Brendan Eich wrote:

On May 12, 2011, at 1:06 PM, Brendan Eich wrote:

On May 12, 2011, at 10:55 AM, Brendan Eich wrote:

Ruby is far from simple, btw. Check out

samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby

and the wikipedia page it references.

Looks like Proc.new but not lambda can return from its caller.

From en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls it should be clear I was missing the "block" target. Blocks are syntactically restricted to being downward funargs. Only if reified as Procs do they potentially escape to be called later when their lexical parent method could have already returned.

IOW, blocks are restricted to being downward-funargs by syntax at their expression site, and by default in the callee (without the & before the corresponding formal parameter).

To say a bit more about this, here's a demo of the downward-only-funarg nature of blocks passed as extra trailing arguments, with no matching &parameters:

def say puts yield "world" end

def say_hello say {|x| "hello #{x}" } end

say_hello

The output is "hello world" of course, but Ruby's yield calls the block without it escaping as a reified Proc that could be invoked later, after the downward flow. Neat!

(Rubyists, please correct anything wrong here.)

If the block is described explicitly in the method definition (that is, the last parameter with &) then it can be returned back as a result:

def foo &block

if block_given?

 yield 10 # call the block implicitly

 block.call 20 # the same, but explicitly

 block # return the block back

end

end

pass the block downwards,

and get it back (upwards) as a result

returned_block = foo { |i| print i }

and call it again

returned_block.call 30

Though, there's no much practical sense in this, since the block lexically is created in the global context of (in this case particular case) and captures its bindings, it, obviously isn't related with bindings of callee.

Brendan, take a look at this detailed source-article explanation of closures in Ruby innig.net/software/ruby/closures-in-ruby.rb (it's executable file, so a good tutorial). There all this stuff with blocks, etc is explained well.

P.S.: damn, it's so sorry that I haven't much time now to be involved deeply into the recent discussions of shorter function syntax. I hope I'll read carefully those threads later. A one thing I'd like to mention, we should not afraid of changes even if they syntactically aren't so familiar and habitual as were in Java.

P.S.[2]:

-> syntax is / was long time before CoffeeScript. It's just a standard

math definition of a function, it's used as a type of a "function"

# Axel Rauschmayer (14 years ago)

Claus Reinke wrote:

Would it be possible for you to follow basic netiquette?

If you do not want to look for useful information in my posts, there is no need for you to reply with unproductive aggression.

I’m sorry, but I agree with Brendan: If you send emails to this mailing list, you have a responsibility to be brief and concrete. You wrote a very long email and he took the time to write a response. It does not sound aggressive to me, just agitated (which I always prefer to people not caring about an issue or ignoring me). Note that it finishes with “I'm being rough on you here because [...]”.

I know of no other language whose creators take as much time and patience to listen, discuss, and explain as JavaScript/ECMAScript.

It is true that you cannot do design by committee (which I’m not accusing TC39 of, BTW). But you cannot do design by public poll, either (you must have noticed the variety of opinions on this list alone!). Someone has to make the hard decisions: Fred Brooks says that (the core of) good design can only be done by a team of one (two if one of them is dominant).

Axel

# David Foley (14 years ago)

You know what? As a pragmatic programmer, one who tries their best to translate problem domains into normative business logic in a language with a sufficient level of expressiveness to accommodate manageable adaption to moving goals, the language should not be the problem domain.

As far as I have so far understood it, this list is about the evolution of JavaScript. (Personally I prefer it's original designation as LiveScript, and the affordances it allowed to move from scratch code to mature application delivery).

I am most likely going to regret saying this, but I would feel (yes, actual emotion') like a coward if I didn't make this point.

There appears to me, to be too much focus on the interpretation of the language, and the technical challenges therein, rather than than the business hours affordances of the language to deliverables and developer experience of the language.

However, what if, rather than trying to consolidate legacy with emerging (naive or otherwise) expectations of the languages evolution, that focus is put instead upon a polysemetic interpreter, a common VM, which language authors can utilise to their own ends (within constraints), whereby the principles of JavaScript dynamism define it's operational boundaries.

In essence, what I'm proposing, is rather than JavaScript being the sole glue of the web, that instead focus is put upon a programmable standardised vm design, which can accommodate JavaScripts evolution.

That way we can focus on interpreter specifics, and language design, without the politics.

As I said, I know I will probably regret this, and Brendan, I know I wouldn't survive a point by point break down (really, this is a high level philosophical proposal, not a technical one), but at least this path could (potentially) be a sound vehicle to distinguish the natural evolution of this particular language, from the needs of developer teams producing sophisticated highly interactive client side web applications (JavaScript could be the Rosetta stone).

I am genuine trying to be constructive here, for better or worse, and I know that casual subjective opinions are not necessarily welcomed here, but that's my tuppence all the same.

If this mentality is anathema to the group, and if anyone is open to discuss this strategy lest we pollute this list, feel free to get in touch

Best

Dave

David Foley | Senior Software Architect

+353 87 667 4504 Skype: david.d.foley

# Mikeal Rogers (14 years ago)

However, what if, rather than trying to consolidate legacy with emerging (naive or otherwise) expectations of the languages evolution, that focus is put instead upon a polysemetic interpreter, a common VM, which language authors can utilise to their own ends (within constraints), whereby the principles of JavaScript dynamism define it's operational boundaries.

You lost me at "common VM".

We currently have some of the fastest VMs in the world as a direct result of strong competition between VMs. Even better, the VMs are healthily stealing good ideas from each other as all of them are open source. So far we've had the best possibly outcome and I wonder what there could possibly be to gain from consolidation.

# Brendan Eich (14 years ago)

Don't worry, no fisking (bottom-citing instead :-P).

This topic of "let's switch to bytecode" or "let's abstract a VM" has come up before:

apps.ycombinator.com/item?id=1893686

IMHO Java's bytecode did not help, it hurt. It hurt Java's evolution, in big ways -- often just by keeping compatibility when breaking compatibility was required (and compatibility was broken later anyway). It hurt VM implementation and optimization.It hurt users who had to compile and package all the time -- during development in particular (yes, people minify JS when deploying, but that's not the javac/jar pain point). I think bytecode helped kill Java on the client.

In similar big ways, and others that I won't rehash (see brendaneich.com/2007/03/the-open-web-and-its-adversaries), the opacity (at least until recently) and even multi-generation VM bytecode sub-formats of SWF has hurt Flash.

Some think Native Client will save us. I read cananian.livejournal.com/63325.html and see great research, but nothing any browser save Chrome might ship, let alone standardize. DLL hell, libc version hell, svn branch feature-conflict hell, ARM vs. x86 etc. hell (PNACL has not saved us; LLVM bitcode is not always arch-independent), and on and on. This stuff is 10x to 100x more complex than JS to specify in a standard and implement interoperably.

And that's the main argument for JS over bytecode, beyond the distortions of lowering to bytecode, freezing the bytecode, trying to evolve languages and VMs thereafter: that JS is strictly much simpler, orders of magnitude simpler, than a language VM. Especially a language-"neutral" VM.

(ECMA-334 and -335? Don't even try those on me.)

# David Foley (14 years ago)

Sorry about that, what I meant in relation to a common vm, and admittedly I was implicitly referring to browser contexts, was a standardised vm responsible for interpretation potentially multiple languages, as opposed to just one (personally I think v8 JIT Vm rocks, but that's a language specific interpreter, I was thinking more in line with the philosophy of JVM DaVinci)

David Foley | Senior Software Architect

+353 87 667 4504 Skype: david.d.foley

# David Foley (14 years ago)

Hey Brendan,

don't know what fisking or bottom-citing means, but respek for the links, and I'll check them out.

Wasn't trying to present an 'original' idea, merely a high level strategy to cope with what I for one, well, perceive as a WTF for daily work in the coming years!

I agree with you in relation to the JVM and the AVM, but surely there has to be another way? That's a research question I would certainly like to engage with, but not one for this list (noise!).

Anyhow, in terms of the language design principles, rather than technical specifications, are there any formal use case definitions in effect for EcmaScript, in the sense of a formal documentation describing how language users and their requirements are idealised?

Best

Dave

David Foley | Senior Software Architect

+353 87 667 4504 Skype: david.d.foley

# David Griffiths (14 years ago)

I agree with John, here, and think his sentiment is probably the most appropriate of all I've read. For all the talk about what's "usable" and "readable", I haven't seen much mention of empirical testing done with ordinary people... (My sincere apologies if there's some usability test lab for middlingly intelligent JavaScripters that I'm not aware of). It's worth remembering that nobody, no matter how well-intentioned, can ever really imagine what it's like to be more stupid or more ignorant than they currently are.

# Bob Nystrom (14 years ago)

On Thu, May 19, 2011 at 8:46 AM, David Griffiths <dxgriffiths at gmail.com>wrote:

For all the talk about what's "usable" and "readable", I haven't seen much mention of empirical testing done with ordinary people... (My sincere apologies if there's some usability test lab for middlingly intelligent JavaScripters that I'm not aware of).

That data is out there in the context of C#. C# 2.0 used this syntax for local functions:

delegate(int x, int y) { return x + y; }

In C# 3.0, they added:

(x, y) => x + y

Aside from the type annotations, those almost perfectly mirror the current discussion for JS. A motivated person could do some archeology of open source code to find out how much each is being used. I was doing a lot of C# when 3.0 came out and watched a number of people learn the new syntax. It generally went like:

  1. Lambdas? Never heard of them.
  2. What is this weird arrow thing? I don't like it.
  3. Eh, I kind of understand what's going on, but it seems fishy.
  4. Hey this is pretty terse.
  5. OMG, working with collections is a breeze now! I just chained five maps and filters!
  6. How did I ever live without this?
# Kam Kasravi (14 years ago)

I also tend to agree with this sentiment, despite having loved operator overloading in C++.  My reasoning is that javascript has no current operator overloading to speak of and adding    recent proposed operator syntax variations would seem to be better delegated to a transpiler of your choice.  IMHO a better approach would be to minimize operator overloading in the current grammar  and standardize an extensible grammar model/framework so that coffeescript, traceur and cousins  are more easily produced and transpiled to a simple (if not verbose) target. Having a common grammar  framework based on PEG's or something with similar characteristics (closed under composition, scannerless,  ordered choice) and standardized among browser vendors would allow far more developers to innovate  at the grammar level with the most popular or innovative grammar dialects being crafted by many rather than a few.

# Nathan Stott (14 years ago)
# Nathan Stott (14 years ago)

(Sorry for the previous empty message)

Having worked a lot with C#, my experience was that very very few people used the C# 2.0 delegate syntax and now a large portion of the community learned and uses the C# 3.0 syntax. Syntax matters.

# Peter Michaux (14 years ago)

On Thu, May 19, 2011 at 12:44 PM, Nathan Stott <nrstott at gmail.com> wrote:

Having worked a lot with C#, my experience was that very very few people used the C# 2.0 delegate syntax and now a large portion of the community learned and uses the C# 3.0 syntax.  Syntax matters.

JavaScript functions have not suffered neglect due to the length of their syntax. Function expressions are already wildly popular in JavaScript. So this C# data does not really support the necessity for change in JavaScript.

Peter

# Alex Russell (14 years ago)

I'm sorry, this this argument is entirely circular:

  • we have something that works
  • it could be better
  • but it works, so we don't need anything better

?

On May 21, 2011, at 10:08 AM, Peter Michaux wrote:

On Thu, May 19, 2011 at 12:44 PM, Nathan Stott <nrstott at gmail.com> wrote:

Having worked a lot with C#, my experience was that very very few people used the C# 2.0 delegate syntax and now a large portion of the community learned and uses the C# 3.0 syntax. Syntax matters.

JavaScript functions have not suffered neglect due to the length of their syntax. Function expressions are already wildly popular in JavaScript. So this C# data does not really support the necessity for change in JavaScript.

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

# Peter Michaux (14 years ago)

Alex,

That is not what I wrote at all because I didn't write the "it could be better".

The analogy that Nathan was making does not apply to JavaScript. He wrote that C# delegates were not popular in C# 2.0. Functions are already popular in JavaScript.

Peter

# Alex Russell (14 years ago)

On May 21, 2011, at 10:32 AM, Peter Michaux wrote:

Alex,

That is not what I wrote at all because I didn't write the "it could be better".

The analogy that Nathan was making does not apply to JavaScript. He wrote that C# delegates were not popular in C# 2.0. Functions are already popular in JavaScript.

So you were only arguing that his analogy was flawed in that the cause of the current proposal isn't under-use but rather problems borne from over-use? Fair enough. It's not an argument against the proposal, then, and I misread it. Apologies.

On Sat, May 21, 2011 at 10:25 AM, Alex Russell <alex at dojotoolkit.org> wrote:

I'm sorry, this this argument is entirely circular:

  • we have something that works
  • it could be better
  • but it works, so we don't need anything better

?

On May 21, 2011, at 10:08 AM, Peter Michaux wrote:

On Thu, May 19, 2011 at 12:44 PM, Nathan Stott <nrstott at gmail.com> wrote:

Having worked a lot with C#, my experience was that very very few people used the C# 2.0 delegate syntax and now a large portion of the community learned and uses the C# 3.0 syntax. Syntax matters.

JavaScript functions have not suffered neglect due to the length of their syntax. Function expressions are already wildly popular in JavaScript. So this C# data does not really support the necessity for change in JavaScript.

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

# François REMY (14 years ago)

I personnaly agree that "it works, we don't need to change it" is a bad pattern, but you still have to prove your propo- sal is really better. Based on the number of mails we have seen in this mailing list saying they didn't want to see this implemented as-is, I think we can say it is (or, at least, we can't say there'sn't something even better).

BTW, it's not because they introduced the arrow syntax that delegates have been used more in C#. It's because at the same time a lot of extensions methods have been added (similar to the current array extras). Before that, delegates were already used to add event handlers, which was the only place where they were really helpful at that time. The problem is that the "delegate" syntax forced you to type the argument' types (a problem we don't have in ES at this time) whereas the arrow syntax computed them.

As a good way to prove my point, we can see that in VB.NET the same feature was added at the same time with a more traditonnal syntax + type infering and it's also used a lot since then.

[[ VB.NET Syntax: Function(X) X.Property ]]

-----Message d'origine---

# Brendan Eich (14 years ago)

On May 21, 2011, at 10:32 AM, Peter Michaux wrote:

Alex,

That is not what I wrote at all because I didn't write the "it could be better".

It could be shorter.

The analogy that Nathan was making does not apply to JavaScript. He wrote that C# delegates were not popular in C# 2.0. Functions are already popular in JavaScript.

Because there's no alternative. C# had alternatives including classes.

Saying JS has function expressions that are wildly popular is jumping to a conclusion. JS is "popular" in that it's the only built-in browser language, but let's say it is popular on its own these days (NodeJS, e.g.).

It still does not follow that function expressions are popular enough that shorter syntax would not make the language more usable for enough developers that shorter syntax is worth adding.

# Peter Michaux (14 years ago)

On Sat, May 21, 2011 at 10:46 AM, Brendan Eich <brendan at mozilla.com> wrote:

Saying JS has function expressions that are wildly popular is jumping to a conclusion.

How is that jumping to conclusions? All the JavaScript code that I read uses function expressions.

JS is "popular" in that it's the only built-in browser language, but let's say it is popular on its own these days (NodeJS, e.g.).

Not sure how this relates to the success of functions in JavaScript code.

It still does not follow that function expressions are popular enough that shorter syntax would not make the language more usable for enough developers that shorter syntax is worth adding.

JavaScript function expressions are not suffering neglect due to their length. I doubt shorter syntax will increase their popularity because function expressions seem to be used where the concept is appropriate even. Separately from that I don't think JavaScript needs shorter function syntax but that is up for debate.

Peter

# Brendan Eich (14 years ago)

On May 21, 2011, at 11:01 AM, Peter Michaux wrote:

On Sat, May 21, 2011 at 10:46 AM, Brendan Eich <brendan at mozilla.com> wrote:

Saying JS has function expressions that are wildly popular is jumping to a conclusion.

How is that jumping to conclusions? All the JavaScript code that I read uses function expressions.

I answered this in my post. Did you read it? Let's try logic:

"English is wildly popular" does not imply "English irregular verbs are wildly popular".

"JS is wildly popular" does not imply "JS function expressions are wildly popular".

It's simply not the case. JS may be popular in spite of the verbosity of 'function', indeed I hear this directly from developers. They like the functional/prototypal multi-paradigm semantics. They do not like the overlong 'function' keyword.

JS is "popular" in that it's the only built-in browser language, but let's say it is popular on its own these days (NodeJS, e.g.).

Not sure how this relates to the success of functions in JavaScript code.

Because there's no other way to build abstractions than by using functions. I explicitly cited C# classes as an alternative that left delegates in C# 1 and 2 with fewer problems to solve. Java did without anything but classes for too long, then added anonymous inner classes as a poor substitute for first class functions.

It still does not follow that function expressions are popular enough that shorter syntax would not make the language more usable for enough developers that shorter syntax is worth adding.

JavaScript function expressions are not suffering neglect due to their length.

You are not responding to my point. JS has a lock on the browser, and even ignoring that, its popularity is not demonstrably due to 'function' being the right length. Indeed NodeJS is winning in part because of V8's performance, in part because JS's closures (not the 'function' keywords length!) make async programming easier than OOP-only languages.

In other words, there's no choice but to use JS in the browser, and its emergence elsewhere has been for explicitly cited benefits other than the length of 'function'. This proves nothing about whether that keyword length is too long, too short, or just right.

Now, independent of this lack of proof about 'function', we hear developers complain about that keyword's length. That's direct user feedback. I do not think you should ignore it.

I doubt shorter syntax will increase their popularity because function expressions seem to be used where the concept is appropriate even.

This is pointless speculation. JS popularity does not prove 'function' or 'function' + 'return' maximum usability. Programming language usability is an art, not a science.

Meanwhile, direct user feedback says to consider shorter function syntax. So we in TC39 are considering it.

Separately from that I don't think JavaScript needs shorter function syntax but that is up for debate.

Obviously -- can you get past this?