My TXJS talk (Twitter remix)

TXJS 2011 A6 – Brendan Eich – Ecma TC39: The Good, The Bad, and The Ugly.

[Main slides] [Paren-free]

I spoke at TXJS, a really excellent regional JS conference, in June. Thanks to @SlexAxton, rmurphey, and everyone else involved. My talk was concerned with the good, bad, and ugly of Ecma TC39 (and I mean those words in the best possible way!), mixing philosophy with historical events from the last 14 years.

After describing the standards process and its history in Ecma, I presented the good stuff that’s going into ES6 (I gave a remixed version of this part of the talk at an SFTechTalk hosted by Twitter last month — thanks to @valueof and @chanian for hosting). As a bonus, I closed with a paren-free update, whose punchline slide is included at the bottom.

TXJS Talk.001

I am not Tuco.

TXJS Talk.002

We don’t smoke, but the rest is pretty much right.

TXJS Talk.003

Here I praised Jan van den Beld, former S-G, Ecma — a raconteur and polymath, for his stewardship of Ecma.

Yes, Netscape picked ECMA (now Ecma, pay attention ;-)) as standards body to which to submit JS mainly to give Microsoft grief, since ECMA had bravely standardized some part of the Windows API. But Jan and the entire TC39 TG1 group played fair on ES1, the first ECMA-262 Edition. Microsoft was so happy they standardized early C# and CLI metadata specs at Ecma.

TXJS Talk.004

Not Bruce Campbell, so not me. That means I’m the Bad.

TXJS Talk.005

Here is something that the Google leak about Dart (née Dash) telegraphs: many Googlers, especially V8 principals, do not like JS and don’t believe it can evolve “in time” (whatever that might mean — and Google of course influences JS’s evolution directly, so they can put a finger on the scale here).

They’re wrong, and I’m glad that at least some of the folks at Google working in TC39 actually believe in JS — specifically its ability to evolve soon enough and well enough to enable both more predictable performance and programming in the large.

There’s a better-is-better bias among Googlers, but the Web is a brutal, shortest-path, Worse-is-Better evolving system.

I’ve spent the last 16 years betting on the Web. Evolving systems can face collapses, die-offs, exigent circumstances. I don’t see JS under imminent threat of death due to such factors, though. Ironic that Google would put a death mark on it.

TXJS Talk.006

TXJS Talk.007

Here I propose that Crock is Plato and I am Aristotle, and that while we need to “keep it real”, we must also hew to high ideals.

TXJS Talk.008

The ideas I cite here, represented by the Hermenuetic Circle, definitely apply to TC39’s understanding of the text of ECMA-262, as well as various canonical texts in Computer Science. The committee works best when it spirals in on a solid design, avoiding local and premature optimizations and pessimizations.

TXJS Talk.009

TXJS Talk.010

Every one of these “Bad Parts” has been on parade in TC39 in recent years, including 2011. I’ve been tempted by the second one, horse-trading, so I’m not innocent (no one is).

The “Scenario Solving” one is particularly subtle in that the Scenario proposed to be solved is quite often a very real developer problem. But a complex, ad-hoc solution to it, especially when rushed, too often is unsound. We would do better to take the Scheme lesson to heart, and develop sound and valid orthogonal primitives. Higher-level libraries built on them can be standardized post hoc.

TXJS Talk.011

TXJS Talk.012

These meta-discussions are sometimes quite funny in light of the vendor whose representative is making them. I note that C# can now be written to look like JS. Why shouldn’t any particular extension to C# be at least considered (not rubber-stamped of course) for JS standardization?

TXJS Talk.013

TXJS Talk.014

TXJS Talk.015

TXJS Talk.016

TXJS Talk.017

These slides provide a glimpse of ES6, still under construction but already full of good stuff.

TXJS Talk.018

The Harmony Goals are not just lofty abstractions.

TXJS Talk.019

I hope the way JS is developed and standardized, as much in the open as the existing standards process permits, and with developer feedback via es-discuss, twitter, and the various conference talks, helps. If not, we may as well wait for some single-source solution to descend from the mountain. And then hold our breaths waiting for Firefox, IE and Safari to implement!

TXJS Talk.020

paren-free.009

While paren-free in all likelihood won’t make ES6, the for-of loop will, and comprehensions and generator expressions in ES6 will be paren-free. Yay!

/be

26 Replies to “My TXJS talk (Twitter remix)”

  1. 1. do spreads work for array literals (i.e. {1, …a, 2, …b }) or destructuring let [a, …b, c] = foo()?

    2. btw the proposed @ syntax for private variables clashes with ASP’s Razor template engine which uses @ for transitioning from the html to code parser.

    3. one thing I would like to see is a way for a javascript translation unit to be fully compiled to code with no interpreter/jitter at runtime.

    This way large libraries like jquery, gmail, google maps, etc. can be compiled to disk in the cache folder and just be memory mapped into executable memory like a dll and run directly with no further jitting/tracing. This can significantly reduce memory usage and put a stop to all the jitting of large amounts of duplicate code per tab.

    The way this can be accomplished is to be able to remove all the top level dynamicism from javascript modules. I hope the Harmony team pays attention to this kind of optimization in its modules and classes proposal.

    Common Lisp’s EVAL-WHEN is the prototypical example here.

  2. @ASDF: thanks for the comment. Replies:

    1. Spreads in array literals are in the video, and in the https://wiki.ecmascript.org/doku.php?id=harmony:spread proposal. “Row capture” in destructuring (as in Successor ML) we definitely want, it has come up since ES4. Erik Arvidsson notes it in the https://wiki.ecmascript.org/doku.php?id=harmony:spread#discussion section.

    2. @ is not in ES6 for private variables, my slides color-coded to show it as controversial. It’s a coveted punctuator, used already by E4X as well as templating systems, Objective-J, etc. Possibly this means we shouldn’t use it. Right now there is no syntax for private name access in ES6. You must use this[myPrivateName] and the new [key]: syntax in object literals.

    3. If you mean full ahead-of-time compilation in the browser, that tends to waste space and power. Lots of downloaded code is cold, forever (for that user’s session) or for a while (until it gets warm). Plus the latency hit of compiling hurts first-run and progressive-rendering use cases. Competitive VMs still use interpreters and JITs for good reason.

    The module system removes dynamic scope in all forms, in particular it removes the global object from the scope chain.

    https://wiki.ecmascript.org/doku.php?id=harmony:modules

    If you mean by “remove all the top level dynamicism” that the module system is static or second class, that’s the design. Module objects reflect modules as sealed objects, and the module loader API allows extensive reflection and dynamic intercession, but the declarative module syntax is all about static binding. Yes, the designers are thinking about macros.

    We are still debating how let declarations at top level in <script> element content are scoped. See https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html, look for “matryoshka dolls”.

    /be

  3. Is there any plan for a standarized Javascript bytecode? So maybe javascript can be evolving to something more than just a language but an open platform alternative to java and cli.

  4. Question: Does javascript’s ‘health’ have as much to do with the lack of competition as it does it’s worthiness?

    Frankly, this is true of html and css. However, javascript ‘wins’ because it is a monopoly. (if you want to write web applications that run in the major browser’s consistently).

    I think coffeescripst’s buzz is evidence that people would like something better. That better may be an improved javasciript, but it may be something radically different. If it is a better way to program the web, then that is good for all of us. Finally, someone is kicking the various committees in the butt and making things happen. We wasted 10+years doing relatively little to improve the web. It took apple creating webkit and google writing chrome for us to see this thing move forward. More power to them.

  5. So, lots more syntactic sugar. Insert comparison to C++11. As someone who’s writing an ES5 compiler, I’m not super thrilled to think I’ll need to add support for all this (and more to come).

    Will you be removing the arguments object, removing the undefined value, fixing the semantic quirks of the primitive arithmetic/comparison operators, fixing typeof? If you’re going to make changes as drastic as removing the global object, and so obviously breaking backward compatibility, you might as well tackle some of the more basic semantic issues in JavaScript, in my opinion.

    I’d be happier to see you guys make the language progressively more robust rather than adding way more syntax. I think many people share this view.

  6. @Rizqi: see https://www.aminutewithbrendan.com/pages/20101122 — a bytecode standard is unlikely given the browsers. Source code standard is evolving. I argue the latter has long-term advantages over bytecode.

    @Richard: JS is not elegant in full, you have to subset. That’s true of all the web standards and inevitable given evolution. You don’t get to clean the slate or even remove features at will. Better cowpaths can be paved so bad old ones can be forested over.

    @Les: I agree 100% — JS has merits but it also has flaws and (this is two-edged) it can’t adapt as quickly given its browser embedding as other languages can. Other languages could do better with hindsight.

    But imagine if I had put C-Python in Netscape 2. Instant fork, a downrev and broken Python for the Web, a big upgrade problem (ignore other issues with that plan).

    Or let’s consider Dash: it won’t be perfect on day one, Google will want to evolve it. Doing so using a single VM implementation will require a Chrome-like update model. Other browsers (consider mobile) will stick on older versions (ignore browsers supporting no version, that’s what the Dash-to-JS compiler is for).

    Without rapid release and silent update, it will be hard for Dash to avoid moving slowly. That probably means it won’t be as competitive as a newcomer, let’s call it Jart ;-). Jart comes along with its “clean break” argument for better-is-better language design, and gets into one or more hot browsers. Rinse and repeat.

    This is why I think cooperating in standards bodies is critical for web interop and non-fragmentation. It necessarily implies less competitive content languages at any given instant, but with consequent widest reach.

    @Maxime: syntax is user interface, we work on it too. But I would like to point out semantic wins in ES6: modules, lexical scope only, private names, generators, proxies, weak maps.

    Removing arguments is a high migration tax. If you imagine ES6 used only for new code, then rest and spread are enough. But we want JS to migrate forward easily. This is why we also can’t remove undefined. It would mean subtle runtime errors not caught statically.

    Modules, lexical scope only, private names, generators, proxies and weak maps are all very much about robustness. Please look past the syntactic sugar.

    /be

  7. >@Richard: JS is not elegant in full, you have to subset. That’s true of all the web standards and inevitable given evolution. You don’t get to clean the slate or even remove features at will. Better cowpaths can be paved so bad old ones can be forested over.

    JS is neither elegant in full, nor in any reasonable subset. And then again subsetting a Language is never such a good thing. Take for example C++ where everyone subsets the language because it is so complex and huge, but nobody’s subset is the same, so the understandability of the code is always impaired. And I don’t call for cleaning the slate and start new. As I wrote, I think it would be better instead of stuffing more into the already conceptionally overburdened language, it may be better to reduce the problems, that persist and are adressed better in other languages.

    Removing undefined, objectifying nil, removing direct assignment (as well as adding weak references, yes), adding doesNotUnderstand: (aka method_missing, noSuchMethod or forwardInvokation:), clearing up the use of this and that would profit the language much more, than adding syntactic _sugar_, I believe. I go conform with Maxime.

    Did you take a look at Self? The inspiration for JavaScript?

  8. @Richard: what a patronizing comment. Yes, I’ve looked at Self. Have you thought at all about how the web evolves? Apparently not.

    Removing undefined, objectifying null (no “nil” and no, we’re not ever going to rename), removing direct assignment, all are compatibility breaks with no upside except to your hypertrophied sense of purity. Get over it.

    Weak references leak GC schedules, exposing attack surface and tending to reduce interoperation. They’d be a privileged API at best. See the strawman section of https://wiki.ecmascript.org/.

    I implemented __noSuchMethod__ in SpiderMonkey, I’ve proposed it in TC39. It’s out, Proxies are in. Have you taken a look at them?

    |this| binding is addressed concretely by two proposals I’ve worked on that aren’t yet approved, but I aim not to waste my time (and I have spent a lot of it) on these. They’re still live. I am talking about arrow function syntax and block-lambda revival, and if you don’t know them or how they address |this| binding, then why are you mouthing off about |this| here? Go find and read them, then we can talk.

    There, I think that addresses your farrago of grievances.

    One last point: we do not ever stop the world, break compatibility by changing the language to anyone’s dream child of Self, leaving developers with a huge migration cliff that few will climb, and only then consider making other improvements, both syntactic and semantic. That’s like the “stop the world, fix security first, then utopia” nonsense I addressed in comments at the end of my JSConf 2010 talk.

    Until you purists get into the muck of web evolution and development, you won’t be effective. Of course, you can feel clean and superior up in your high castles, but it’s lonely up there.

    /be

  9. @Brendan Absolutely. Javascript does a lot of things very, very well. I’m not intending to diminish those things by saying that it’s biggest advantage is being cross browser. I’m hoping that these alternatives will create the foot paths and the javascript will be able to learn from that and pave them. With the increased competition, whether from language or library, javascript should be able to evolve to simplify the best ideas from the various approaches. Frankly, the web programming model is wonderfully flexible, but it is too hard to teach and too framework dependent. I’m hoping this next series of iterations will lower the bar enough to make simple things simpler. Then again, I just ran into the combover metaphor(https://raganwald.posterous.com/javas-comb-over), I’d hate for javascript to go there! 🙂

  10. Long time reader, first time poster, I’ve also watched recently Waldemar Horwat’s talk on JavaScript future (and I’m trying to use his project written in CL, a part of Mozilla source, which is the grammar of JavaScript, basically). I browsed this article because I was reading about Google working on Dart (or Dash, however they choose to call it in the end).
    I can imagine the woes of disagreement in the standardization committee, as any large group of people holding different opinions would surely not be able to agree. However, as someone only able to observe the results of your work, unfortunately, I must state that it looks like an aggregation of contradicting ideas and impractical solutions, all in one 🙁 ES5 introduces more potential problems then solves. Here’s an example: you decided that a version (or strictness of the source code) could be stated by using a string literal somewhere inside the function body.

    This presents us with following problems in practice:
    – is a loitering string literal an error (maybe you should warn the programmer it forgot something, like declaration of a variable?).
    – if there will be an optimizing compiler, it will try to remove such thing as a piece of program that does nothing – you just added an exception, where none should be.
    – usually IDEs don’t look into string literals, as they believe those should contain some user data. So, if the programmer makes a typo when specifying version, the IDE will not warn her.
    – this feature isn’t really a solution, because, once in the future you will need to obsolete the ES5 code, this feature will get in your way, or, you will have to reuse it, continuing old errors…
    – is the placement important. If it is, can you `undo’ the strictness locally. If you can, then why give such an option (it’s a madness for interpreter), but if you can’t, then why is it technically possible?

    This said, I’m holding my fingers for Dart or Dash, or w/e it will be, because the lack of diversity in web has led the technology to almost stagnation (there is no real reason that things which were available to desktop application 10 years ago are still a challenge for web). You don’t recognize it, because there is nothing to compare it to.

    Not so long ago I saw a group of programmers from Google ported Quake2 to use WebGL/JS – it was served as an amazing breakthrough, even though… wait, I think I went to school, when this game was a break through… it is literary one generation late 🙂

  11. Sigh, maybe you’re right. Maybe I should get over this ‘quest’ for purity and accept that such change is neither possible nor wanted. But in my gut, I’m still disappointed. So the only possible change is addition?

  12. ES.next looks really good.

    But block lambda won’t make it?

    Any chance that using the Objective C precedent – which has been discussed i think – and going with caret might make it more palatable?

    // Inline block – like an anon function
    myFunc(10, ^(x) { return x * x; });

    // No implicit return
    let a = ^(x) { return x * x }

    // For simple expressions implicit return with parens
    let b = ^(x) (x * x);

    // Syntax for no params
    let c = ^{ alert(‘hello world’) }

    Also – maybe the caret could be used on function signatures to indicator a block:
    function myFunc(a,b,^c) { // c is a block – or a callable object
    // code
    }

    Or are the objections deeper than syntax – makes the runtime model/semantics more complex without sufficient payoff.

  13. ES Harmony is disappointing IMHO.
    I hoped for primitive types (like int8, int16, int32, int64, float32, float64 …). But Harmony adds it only for structs :/

    The single most important problem that Javascript has now is his snail execution speed. The rest can be largely alleviated with frameworks and transcompilers (jquery, coffeescript, …).

    Without primitive types support, Javascript will never be able to reach Java-like or C#-like speed.

  14. @wvxvw: you assert contradicting ideas and impractical solutions, but then go on to complain about ES5 and in particular its

    "use strict";
    

    directive hiding inside a string literal expression. ES5 (originally 3.1) operated under a “no new syntax” stricture.

    Harmony has no such restriction, and the pragma syntax allows programmers who have opted into the new edition to write:

    use strict;
    

    What’s more, Harmony is based on ES5 strict, so there is no need for even this. So it seems to me you completely missed your target.

    @Richard: change is wanted, but not for no gain except in the abstract. Harmony introduces plenty of changes to JS (too many for some people; not for me). The pain has to be worth the gain, though, and that’s not the case for the small fry you want to fish.

    @Kevin: ^ is bitwise-exclusive-or already, to make it a unary prefix operator would require newline sensitivity (frowned upon but already in ECMA-262, see the “restricted productions”). As with #, ƒ, λ, and other ‘function’ shorthands the committee does not want to break compatibility only for a seven-character savings. We want to reduce the ‘return’ tax as well, safely (without creating completion value leak hazards).

    We don’t need a Ruby-like & sigil for trailing formal parameters to do block lambdas, and it’s hard to retrofit in JS since unlike Ruby, JS does not match arity and throw if the wrong number of actual arguments compared to formal parameters is passed by a caller.

    @Jonathan: your gist shows two changes that I can see:

    1. ‘Point’ as method name instead of ‘constructor’. The counter-arguments are

    (a) We want to support anonymous classes — what to name the constructor then?

    (b) The class body defines prototype properties, which in JS always include ‘constructor’, referring back to the constructor function whose prototype contains this property (i.e., for function C, C.prototype.constructor === C). Why make two names for one thing? CoffeeScript also uses ‘constructor’, FWIW.

    2. Private variable references need no ‘this.’ for the receiving instance, and use dot (point.x) for accessing the private-named property of another object.

    This simply does not work in a dynamic language. We don’t know what the type of the other object might be. For common names (x and y in your example), we cannot assume the parameter is an instance of the same class as the receiver. We cannot make it impossible to refer to a public name spelled x or y, either.

    Putting private (and public? if not, why not?) properties of |this| on the scope chain is also problematic, since objects on the scope chain can inject dynamic bindings. We could avoid this for |this| but only by restricting method scope to consider only declared properties. And then if there were an outer x or y, you would have no way to access it.

    Hence my slide’s use of @ with the caveat that @ is not proposed or anywhere near Harmony.

    Note how Ruby, another dynamic language influenced by Smalltalk, does use @, but only as a prefix sigil, for instance-private (this-based) instance variables.

    @phi2x: you may be right that JS should have machine types, but what would the implicit conversion rules be? This is non-trivial. I spoke about this at CapitolJS this past weekend. I’ll post my slides with commentary and talk about it more.

    However, optimizing JS JITs, especially with typed arrays, can do a lot with just the current number primitive type. Some benchmarks already show C speed (see Dave Mandelin’s talk from Velocity 2011). When it comes to JS performance optimization, never say never.

    /be

Leave a Reply to Richard Durr Cancel reply

Your email address will not be published. Required fields are marked *