ECMAScript 6 looks promising
kishorelive.com
kishorelive.com
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.
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.
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 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).
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 :)
Having said that, my first language was Perl, and I'm still a fan of TMTOWTDI and making common things easy.
"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)?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)
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.
Or of course create_string("hello $1", name) or something like that.
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)
I've used Ruby quite a while and never experienced any problems with the very same construct in there.
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}"`.
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.
var foo = /* Hello there How are you? */;
But less typing is good too.
/ * ... * / 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.
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
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."]
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.
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.a, *, c = list
And people often use _ as a placeholder when not using splatting:
a, _, _, c, d = list
var [ a, b, ...rest ] = fooI 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. 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 = listI 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?
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.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.
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.
In one of C++ programs I've worked on, we've had 4 different classes for string used (along with char* of course).
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.
(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.
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.
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.
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.
By forcing my users to use the latest versions of Firefox and Chrome I get access to a lot of nice new functionality.
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";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.
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)
let callback = function(a, b) {
// ...
} in
object.registerCallback(callback);* 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`.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.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.
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.
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.
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.
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.
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 !
Python has had real generators (using the yield keyword) for a long time... See http://www.python.org/dev/peps/pep-0255/ .
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)