Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
ECMAScript 6 looks promising (kishorelive.com)
153 points by karterk on Nov 24, 2011 | hide | past | favorite | 88 comments


Let keyword: good. The function scoping of vars is gruesome.

Default arguments: good. Clearly useful and already used a lot with the if (foo === undefined) foo = 'default' pattern.

Non-strict destructuring: bad. It's neither destructuring-bind nor pattern matching... If I destructure a 3-list to 2 vars, I want it to fail, dammit!

Multi-line strings: good, obviously.

Templating: hello, PHP! I thought we already know better.

List comprehension: useful.

My humble opinion: it's hopeless. A mix of useful and terrible features means it'll still be made out of "the good parts" and the awful rest.


To me this spec itself is a step in the right direction. There has been no major work towards improving JavaScript in a long long time. I left out in my post the part about modules (which will hopefully solve all the crazy 3rd party JS issues), because I have no idea when they will actually get implemented by the browser vendors. But, I am hoping that this will continue to evolve in future, instead of getting stagnated.


> It's neither destructuring-bind nor pattern matching... If I destructure a 3-list to 2 vars, I want it to fail, dammit!

Yeah I agree with that one completely: unless I tell you I don't care for it, you don't get to ignore it.

It's in line with JS's non-strict handling of arguments though (missing args are `undefined`, extra args are in the `arguments` object), which makes it hard to argue against)

> Templating: hello, PHP! I thought we already know better

Meh. Ruby also lets you do that, it's OK. String formatting is a good idea and interpolation is no worse than sprintf-style or C#-style.


>If I destructure a 3-list to 2 vars, I want it to fail, dammit!

Why should that fail any more than:

    var a = foo[0];
    var b = foo[1];
    // rest of foo unused
Destructing is just another way to access into a list. There's no notion of completeness here, and there's nothing necessarily erroneous with not referring to all the elements. What would you do if you need just the first 5 elements of a 100-element long list?

That said, if they're going to include destructuring, it'd be nice if they also included a way to bind the tail.


> What would you do if you need just the first 5 elements of a 100-element long list?

Depending on the language, either you don't or you use a "everything else" operator to an unused variable:

    a, b, *_ = list
You could even alter the syntax slightly to put a "Don't care" placeholder:

    a, b, * = list
same as above but does not require serializing the [2:] array slice.


Ruby unfortunately has non-strict destructuring, but it also has LHS splatting:

a, *, c = list

And people often use _ as a placeholder when not using splatting:

a, _, _, c, d = list


> What would you do if you need just the first 5 elements of a 100-element long list?

I like Python solution there:

    list = [1,2,3,4,5,6,7,8,9,10]
    a,b,c = list[0:3]
Also when I do

    a,b,c = list[0:4]
I get "ValueError: too many values to unpack" as it should be - you can always catch the exception and ignore it, if your code really don't care.


FWIW, Python 3 improves case 1 to:

    a, b, c, *_ = list
better, you can put the slice at at any point of the left hand, so if you want the first and last elements of your list (and want to ignore everything else) you can write:

    a, *_, b = list


Catch an exception of something that isn't exceptional? isn't that the anti-case for exception handling?

I don't get why strict restructuring is a bad thing... as long as it's consistant, it's just a nuance of the language.

Am I missing side effect of this? What are potential pit-falls of this pattern?


I was arguing that non-strict destructuring is bad, so this code IMHO should throw exception:

    a,b,c=[1,2,3,4]
The reason for this is - if you assume array has 3 elements, but it has more, your code will silently ignore the rest. You'll have to write your assertion every time you destructure, to be sure that destructuring don't ignore data. The exceptional case IMHO is when you need to ignore data, and so code for this case should be uglier, not the other way around. You are right that catching exception for regular code path isn't the best way, but at least programmer intention is clear then.

You could also do

     a,b,c = list.slice(0,3);
which copies the array, but at least it's clear what it assumes about the array. And it can be easily modified to get last 3 values, or 3 values from the middle of list. So no need for 2 idioms depending on which items you want to get from the array.


They are:

    var [ a, b, ...rest ] = foo


I don't know much about PHP, what's wrong with it regarding templating?


Automatic interpolation of variables into string literals is a bad idea IMHO.

Couple that with variable hoisting (function scope) and hilarity can ensue when variables defined further down a function influence the value of another variable that looks like it just contains a string literal.


It's not really automatic interpolation. You have to very explicitly place the variable name inside ${var}. I'm puzzled in how you would think this will happen accidentally, or more accidentally than writing "+var+".

I've used Ruby quite a while and never experienced any problems with the very same construct in there.


You can also get away with doing just "$var", though, which is the problem. We encountered a strange bug the other day where having a string containing "$3" meant it never appeared on the page after (with it being converted to null).


It's syntactic sugar for string concatenation. The same bugs would happen today if you were concatenating strings. I don't see the problem, honestly.


Somehow you have to get those values into the String, though. How do you propose doing it? Seems to me you can either concatenate Strings ("hello "+name) or interpolate ("hello #{name}")? Interpolating actually looks cleaner to me.

Or of course create_string("hello $1", name) or something like that.


> Interpolating actually looks cleaner to me.

Definitely. It can't be used for i18n though, which is problematic (interpolation usually uses full expressions, so it's essentially a vector of code injection).

> Or of course create_string("hello $1", name) or something like that.

There are already string formatting minilanguages, no need to make up your own: you can use printf's format or C#-style string formats (I think the C# one is rather nice, especially its extensions in Python which allow for implicit positional and named formatting)


Strings with interpolation look different in ES6. They don't just look like string literals. You can easily see where the variable substitutions happen.

Also, I don't know what your argument about PHP is all about. I don't agree with the idea that string interpolation is going to lead to people writing code vulnerable to SQL injection, for example. You can just as easily write "select * from foo where name=\"" + name + "\"" as `select * from foo where name="${name}"`.


> You can just as easily write

No you can't. You've got 8% more character and 2 switches between string context and expression context. It does not "flow" it's something which is forced on the user by limitations of the language.


Every time I try Ruby, this features seems odd, yet I never see much discussion of it. It feels unnatural to me, coming from a python background, and the only real advantage I can see is the fact that you do not have to type `.format(foo")` after the string, or some similar construct.

What advantages did I miss? I doubt that the creators of ruby did not put any thought into this, and I'd be interested in their justification.


I don't believe it's the rationale, but it does have a tiny advantage in readability compared to old style format strings, e.g

    "hello $name we welcome you in hour team '$teamName' of ${members.size}"
vs

    "hello %s we welcome you in hour team '%s' of %d" % (name, teamName, members.size)
While, comparing it to modern python's str.format, which would be (i believe please correct me if I'm wrong)

    "hello {name} we welcome you in hour team '{teamName}' of {members_size}".format(name=name, teamName=teamName, members_size=len(members))

...I guess my question would be the opposite: why is that better than string interpolation (which has also been around for decades)?


> why is that better than string interpolation (which has also been around for decades)?

For my money, you can't use string interpolation for i18n alongside a semi-arbitrary access site (e.g. Transifex or Launchpad's Rosetta) and it's riskier for logging (for performance-related reasons, as it forces an eager interpolation where the logging API can provide for lazy formatting)


these are good reasons for having a string templating system in a library, but I was referring to the 90% use case of having a script that outputs something it computes.

The things don't seem mutually exclusive to me.


> The things don't seem mutually exclusive to me.

Sure but now you have two very different ways to format your strings and language users need to realize they should be using the one they're not used to for these specific tasks, even though there's pretty much nothing helping make them realize it.

That significantly increases the user's cognitive load, and the risks of misusing APIs unless your language is able to express (and safegard against) the danger of string interpolation in specific contexts.


>> I doubt that the creators of ruby did not put any thought into this, and I'd be interested in their justification.

I don't know what Matz's thinking was, but it may just be that Ruby owes a great deal to Perl. Interpolation in double-quoted strings is present in Perl (and used constantly).


I think the bad part of string interpolation is that it encourages to use it constantly, in place, instead of extracting it to method.

Gluing strings together is the weak point of application, and should be hard to do, to encourage people to wrap it in functions, that can also validate input, escape what needs to be escaped, etc.

Maybe that's my "discipline and bodage" part talking :)


I'm a very small-scale, amateur programmer, but that sounds like over-engineering to me. Getting variable values into strings is often necessary. A programming language shouldn't make something common hard, just to enforce a particular view of best practices. Note: I'm not saying that "make it a method" is a bad idea - in general or in the case of a specific project or a specific size of codebase. But I don't like the idea of the language enforcing such a restriction.

Having said that, my first language was Perl, and I'm still a fan of TMTOWTDI and making common things easy.


Does anyone know what the rationale was for choosing this instead of printf or python3-style interpolation (where you explicitly specify the variables to be interpolated)?


I guess that's what happens when a language becomes this popular. All the immigrants from other languages start sticking their fingers in and trying to make JS the way they think it should be.

The main issue is that half of these features don't solve any real problem. They should look to libraries like underscore that add features and solve problems that JS currently doesn't. It's almost like they just want to eliminate libraries altogether and have everything work out of the box.


Eliminating libraries has adventages - it eliminates dependency. When you have to integrate 2 projects using different basic libraries, it's painful.

In one of C++ programs I've worked on, we've had 4 different classes for string used (along with char* of course).


It does have some advantages, but the author of a library creates a library to do a specific thing and to do it well. When it gets added to the language, as we've seen with the horrible module proposal, lots of people all disagree on how it should be implemented so you end up with a much worse implementation than if you just let individuals create the feature how they think is best.

With libraries, you are free to switch to other ones if you don't like the way it does a specific thing. Don't like CommonJS? Don't use browserify, and instead try RequireJS. Don't like how Prototype extends the prototype of objects? Try jQuery.


I think it would be slightly more consistent to re-use the multi-line quite like Python does:

var foo = /* Hello there How are you? */;

But less typing is good too.


So does that string literal include the spaces between "/ * [space]" and "Hello", and "you?" and "[space] * /", or not?

By the fact that you included spaces in your example, does that imply it doesn't include the surrounding spaces in the string? Maybe your example implies that spaces are not included, but maybe they are or maybe they aren't, since comments don't require them, but usually have them and look ugly without them.

I think it's a bad idea to use C-style comments as multi line strings, because it's ambiguous and/or ugly because of the surrounding spaces. If the leading and trailing spaces are included in the string, then it looks "/ * [nospace] ugly [nospace] * /", and it drops the surrounding spaces like your example implies, then "/ * [nospace] what does it mean [space] * /" if you omit one or both spaces? Messy and ambiguous.

It looks like something the C++ committee would come up with when they ran out of punctuation characters, and decided to abuse existing syntax instead. Comment overloading, an extension of Generalized Overloading for C++2000: http://www2.research.att.com/~bs/whitespace98.pdf

[I can't format an example of what I mean literally and had to add extra spaces, because of hn's stupid formatting rule: "Text surrounded by asterisks is italicized, if the character after the first asterisk isn't whitespace."]


Sorry, I read the part about HN making it difficult to format your post, but I still don't quite get your point. I think it's pretty simple what was proposed: everything between the stars is included.


I doubt. /* */ is already used for commenting.


That's the idea. Python uses the same syntax for multi-line strings as for comments.


This is completely wrong. Triple quotes in Python indicate a string. It happens to be able to be used for a multi-line comment because it officially leaves no artifact in the AST if it's not assigned to anything (can't find the documentation for this atm).

/ * ... * / is a comment in Javascript. Changing it to mean multi-line string is a terrible idea.

This list of changes to Javascript borrows so much from Python I'm surprised they didn't also borrow Python's multi-line string syntax.


> Python uses the same syntax for multi-line strings as for comments.

No it does not. Triple-quoted strings are still strings, all comments in Python are prefixed with `#`.

There are two situations where triple quoted strings are used as "comments":

* Multiline comments for lazy people, as Python has no multiline comment syntax

* docstrings. As the name indicate, they're strings, they're not comments and should not be confused by more ad-hoc systems such as javadoc comments. Python lets you write `help(name)` and get the docstring associated with the object


Damn, I just got comfortable with functions being first class constructs, now I have to get used to the idea of comment meta-programming.


I think it will be really sad if we end up with a module system that's incompatible with CommonJS, which is the only such system that has gained any real traction.


Do you have reason to think that's likely?


Nice to see many of CoffeeScript's constructs coming to ECMAScript.


True-- but it's frustrating that there's so much resistance to the idea of making the syntax prettier and more concise, which is one of the primary benefits of CoffeeScript.

(Almost?) all of these features can be added to JavaScript with libraries-- that's exactly what CoffeeScript demonstrates. The only thing missing is a contemporary syntax.


The syntax is one of the things that keeps me from using CoffeeScript.


Because it is badly designed? Or because it is too different from js?


Because it's kind-of a mish-mash, and syntactic elements imported from other languages (I know) tend to behave differently in subtle ways, usually making them worse or weird. Also having a single token change so much meaning (fat vs thin arrow) feels icky and hard to read/notice.


That's a fair perspective, although what you call a "mish-mash" I'd call borrowing the best syntax for every feature :) The syntax came out of a community effort over the course of many months, and a lot of thought went into the decisions that were made. (And of course it's still under development!)

Since you mentioned the => operator in particular, I'll defend it briefly-- it's a feature JavaScript sorely needs, and in the situations where it's useful it's a godsend, turning a pile of ugly JS into a single operator. The thing it describes is a little complex semantically, but in practice it's very straightforward, and in the cleaner environment of CoffeeScript it stands out well. It does seem like a small difference, but do you mix up == and -= much? Same deal. Visually speaking it actually makes a lot of sense: -> indicates a vanilla, unbound function, while => indicates a bound function whose context equals the one it's defined in.

I know I'm a bit of a fanboy, but if you do a lot of JavaScript I'd encourage you to at least give CoffeeScript a second chance over a weekend sometime; it's the same, normal JS semantics you know and love, but you get to use all the futuristic shortcuts and clean syntax of a modern scripting language, and it outputs nice, readable, compliant JavaScript. (Say goodbye to JSLint!) That's well worth the minimal learning curve, in my opinion of course.


> Since you mentioned the => operator in particular, I'll defend it briefly-- it's a feature JavaScript sorely needs, and in the situations where it's useful it's a godsend, turning a pile of ugly JS into a single operator.

Oh I understand the need for it, my issue is not with the fat arrow in and of itself, but in the fat arrow and the thin arrow.

> It does seem like a small difference, but do you mix up == and -= much? Same deal.

Well...

1. I rarely if ever use either, and

2. they're generally used in different contexts, I would never use `-=` as part of a wider expression (unless I wanted to fuck with the reader of the code, who is usually me) whereas `==` is not very useful outside of a conditional expression (or at least as a parameter to something else, like a function).

The thin and fat arrows, by comparison, are used in the exact same contexts. This makes them much more error prone.

> That's well worth the minimal learning curve, in my opinion of course.

I don't mind the learning curve, I mind that I don't really like the way the syntax fits together (or does not). Though, to be fair, I also don't like the extra tooling or having to debug different code than was written.


> The thin and fat arrows, by comparison, are used in the exact same contexts. This makes them much more error prone.

You can say that, but in practice it doesn't really happen. They look somewhat different, they do somewhat different things. It's programming, ya know?

Not that I'm trying to make you like it or anything-- of course you have the right to your own aesthetic sensibility.


What's any language, if not a mish-mash of its predecessors?


You've obviously never used CoffeeScript.


You're also a Go user are you not? If you're not, you should start, you've already got the reaction down pat.


Because it looks like the type of syntax a Haskell developer might create...


Downvoted for giving an honest answer to the question I was asked. Classy. This place is becoming more and more like Reddit.


But, how are we going to migrate? Compile down to the current version and serve two files? I feel like this migration process will take way too long.


For some web apps it will probably take long. But with all the developments in browser land there is often more then one reason to develop against the latest anyway. Hopefully this will motivate corporate IT to move faster also.


That's one good thing about using a feature like WebGL :)

By forcing my users to use the latest versions of Firefox and Chrome I get access to a lot of nice new functionality.


Either that or wait until last version of IE which doesn't support it has died. Might happen in time for HTML5 becoming W3C recommendation in 2022.


Using the ` (backquote) character for multiline strings isn't a wise choice (probably inherited from Go) cause it's difficult to reach that character on non-english keyboard layout. In the italian layout it's alt+\ or alt+9 on the Mac but you can't reach it using Windows; you need to press alt+96.


What other character would you suggest? At least multi line strings arent super common (nor essential) so extra difficulty isn't a major problem.


> What other character would you suggest?

Fixing the language so newlines in strings are legal, Python-style triple quoting or some sort of string modifier prefix (similar to Python's rawstring modifier)


I don't think that there is the need for a new character. The problem here is that JS has automatic semicolon insertion. This:

  var a = "abc
   def";
generate a "unterminated string literal" syntax error cause a semicolon is inserted after abc. Why not using C/C++/ObjC syntax?

  var a = "a very "
   "very long string";


The only thing about the C syntax version is you still end up with a bunch of double quotes all over the place. The #1 reason I have for using multi-line strings currently is when writing full-out SQL or Javascript code inside C#; using C#'s @-prefixed strings make the whole thing a lot prettier to look at IMO.

For me personally I'll probably never have to write multi-line JS strings more than once a year so I don't really care about the feature, but I do agree with their way of implementing them.


Friends don't let friends use layouts other than QWERTY (glares at the AZERTY keyboard her employer gave her that was rapidly replaced with a QWERTY from home).


I just press shift+´ to get `


Except for the inclusion of "let", it is looking like Python with braces.


Yes, and David actually mentioned openly in that talk that they try to borrow good ideas from other languages if possible! There are templates from PHP too :)


Don't know much about PHP, but the templates also exist in Python.


Python's string formatting is different though– it doesn't automatically have access to the variables in the current scope. You have to explicitly pass in the variables that you want to include, which seems to me like a cleaner way of doing things.


That bears more than a passing resemblance to coffeescript. Great stuff.


`let` is good but please, give me `let ... in` too:

    let callback = function(a, b) {
        // ...
    } in
    object.registerCallback(callback);


I don't know what they've selected for ECMAScript 6, but the `let` keyword as introduced in Firefox 2 has 3 different forms:

* Let definitions are equivalent to `var` but block-scoped, so

    if (x > y) {
      let gamma = 12.7 + y;
      i = gamma * x;
    }

  `gamma` is local to the `if` block and will not leak out. This form can be used to create bindings in `for` as well:

    for ( let i=0 ; i < 10 ; i++ ) {
      console.log(i);
    }

  here, `i` is only visible from the condition, incrementor and body of the `for` statement but not outside
* Let statement, mostly for side-effects, sufficient for what you need:

    let (callback = function (a, b) {
                // ...
            }) {
        object.registerCallback();
    }
* Let expressions, this works like the `let` statement but returns a value, just drop off the braces:

    let foo = let (i=42) doSomethingWith(i)

  will bind the result of `doSomethingWith(42)` to `foo`.


Let statement, mostly for side-effects, sufficient for what you need:

Sadly it's not. JS has some semantic foibles, but I find myself up against syntax more often than I'd like. Every time I write it I'm impressed at how ugly the syntax is vs for such a good language (modulo the standard library.)

The very thing I'm trying to avoid is the use of blocks within parentheses. (Aside: I changed my font to Monaco for JS because of the frequent appearance of `})`, and went to the trouble of fixing it up in Fontforge so gvim et al. would be willing to use it.)

I never want to see this:

    anything(block {
        // ...
    }) <--- this
    ^^____this 
but I still want the definition to be short-lived (more for self-documenting purposes than anything else, now that I think of it.) Your last example almost has it, but the parens are right there where I want them gone.


> The very thing I'm trying to avoid is the use of blocks within parentheses.

That, er, makes no sense at all. Javascript's function uses braces, having an anonymous function within anything will yield either a brace-and-parens or a brace-and-comma.

> Your last example almost has it, but the parens are right there where I want them gone.

Then there's no point in using javascript, go do something else because trying to get rid of this will just yield to an idiosyncratic and mostly unusable coding style.


Then there's no point in using javascript, go do something else

No need to be rude. Look, I know JS likes to do things in ugly ways. It has great strength in the consistency of its syntax. That's cool. But by the time you say the word "just" you're being ignorant.


> No need to be rude.

The statement was not intended to be rude and I'm sorry you took it this way, it was merely intended to be factual: you seem unhappy with javascript's core syntactic elements, you should use something else because they're not going to be changed.

> Look, I know JS likes to do things in ugly ways.

Uh... ok, whatever.

> But by the time you say the word "just" you're being ignorant.

Ignorant of what, of you trying to work around javascript's syntax in javascript for debatable reasons of personal aesthetics? No, I think I got that now, I was originally mistaken indeed in that I thought you were looking for an improvement to the language, not "fixing" an irrelevant syntactic pet peeve.


The statement was not intended to be rude

It comes off as a euphemism for much shorter phrase. Perhaps you didn't intend to be rude, but you failed to be polite.

Ignorant of what

(Exactly.) You've made assumptions and pinned them to me. I'd set you straight but I don't actually want to continue this conversation. Sorry it didn't work out.


> Perhaps you didn't intend to be rude, but you failed to be polite.

Considering your messages seem to be about misleading and avoiding spelling out your issues more than conversing, I had (and have) no reason to go out of my way to be polite.

> I'd set you straight but I don't actually want to continue this conversation.

And now you're plain and simply lying. You never intended to set anything straight (or you'd have done this in your previous comment instead of going for the pithy implication) and never intended this to be a discussion.

> Sorry it didn't work out.

It's not a relation, there's no "working out" to do.


The most interesting part to me is the "generator function", which basically allows for cooperative scheduling.

This would put an end to spaghetti callbacks when doing blocking I/O operations. Very similar to EM-Synchrony for EventMachine/Ruby and (I guess) Inline Callbacks in Twisted/Python.

This and the new module would be a blast for Node.JS !


and (I guess) Inline Callbacks in Twisted/Python

Python has had real generators (using the yield keyword) for a long time... See http://www.python.org/dev/peps/pep-0255/ .


Python has been having coroutine based, cooperative scheduled I/O for a long time.. go read about gevent and eventlet.


CoffeeScript is popular and there is Dart. Instead of using another language and translate to JavaScript, what are the hindrances to improve JavaScript so that the "bad parts" are removed? Maybe a 'half-clean' break from existing javaScript? Sorry for my ignorance.


There's a very high interia, as there are at least 5 major implementations still being developped (MSIE's Chakra, Mozilla's SpiderMonkey, Google's V8, Apple/Webkit's JavaScriptCore and Opera's Carakan).

Work has not stopped, but it's basically about cat-herding, and each player does his own additions. As an example, Mozilla has kept working on core Javascript with "internal" versions:

1.6 added Array Extras and String and Array generics (array extras have since then been adopted by everybody else) as well as E4X (literal XML syntax in JS) and a `for each` loop.

1.7 added generators and iterators, array comprehensions (listcomps), let definitions, statements and expressions and destructuring assignments

1.8 added a function shorthand (function (foo) { return bar; } => function (foo) bar), generator comprehensions (lazy listcomps) and two missing array extras (left and right folds)

1.8.1 and 1.8.5 mostly added ES5 and draft APIs (e.g. the Object.* stuff and the Proxy type)


You can already remove a bunch of the bad parts via "use strict".


64-bit integers and bitwise operations together with default arguments and destructuring would solve just about everything.


I cannot rightly comprehend what problems one must be having if the solution is a wider bit width and variable assignment sugar.


Does anyone know if this will get implemented into ActionScript? I want let so much.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: