Non-string values are not valid hash keys. Operations that should be type errors fail silently and return nonsense. The prototype system is less powerful than the OO system of basically every other scripting language. The language will never have continuations, so people who want real control flow are stuck using preprocessors to generate callback spaghetti. Encoding a particularly rigid mix of dynamic and lexical scope into the language specification, such that everyone must be exposed to dynamic scoping much of the time, is one of the worst ideas I can imagine.
Non-string values are not valid hash keys. - ES6 Maps
Yes, this is a good thing :)
The prototype system is less powerful .. - No. Just different
Javascript let you use prototypes to cause map lookups for absent keys to fall back to a different map. Lua lets you use prototypes to override every operator, make the object callable, override map lookups for absent keys, and override assignment of new keys. All of these operations can be made to call into arbitrary functions the user provides. Python, an OO scripting language, provides all of the same features.
It seems to me that among these three languages there is a greater difference between the more powerful systems and the less powerful system than between the prototypal systems and the OO system.
The language will never have continuations.. - Generators help here. We use them with node --harmony
Python also has generators, but you still need greenlet or stackless if you want to use coroutines. The inability to suspend from a subroutine is a deal breaker. Generators are probably nice for writing generators. For writing control flow, Continuation.js seems like a better choice.
Scoping. - Fat arrows and block scoping coming in ES6.
=> lets you use a lexically scoped this, which is likely a dynamically scoped this from an enclosing lexical scope. This sounds useful, but it doesn't really make things less messy.
Sure if you prefer static typing then JS is not for you.
I did not say anything about static typing. Most dynamic languages are not forced by their specs to coerce disparate types into utter garbage. I invite you to type the examples in the Wat talk into a REPL for any other dynamic language and see how many of them produce exceptions.
Continuations seem to be rare among other languages you could choose. Personally I have only seem them in LISP, what else is out there?
Before answering, I will point out that coroutines are equivalent to one-shot continuations, and coroutines that can be copied are equivalent to multi-shot continuations. Then, I am familiar with continuation implementations in the following languages: Python [1][2], Scala with any JVM runtime[3], Any JVM language with a particular runtime[4], C[5], Lua[6], Julia[7], and C++[8]. Of these, the ones for the JVM, C/C++, and Lua[9] are multi-shot continuations or equivalent to them, while Julia and Python are a bit more limited. I am not familiar with many languages, so I'm sure I've missed a lot of instances of this sort of feature.
I would love to use LISP, but the libraries simply aren't there. Last time I tried Racket, there wasn't even a library for JSON.
I can't really speak to this because I haven't spent time trying to build real software using lisp.
Comments
Non-string values are not valid hash keys. Operations that should be type errors fail silently and return nonsense. The prototype system is less powerful than the OO system of basically every other scripting language. The language will never have continuations, so people who want real control flow are stuck using preprocessors to generate callback spaghetti. Encoding a particularly rigid mix of dynamic and lexical scope into the language specification, such that everyone must be exposed to dynamic scoping much of the time, is one of the worst ideas I can imagine.
Non-string values are not valid hash keys. - ES6 Maps
The prototype system is less powerful .. - No. Just different.
The language will never have continuations.. - Generators help here. We use them with node --harmony
Scoping. - Fat arrows and block scoping coming in ES6.
These features can be used today in node, by enabling the harmony flag. Otherwise wait until next year.
Yes, this is a good thing :)
Javascript let you use prototypes to cause map lookups for absent keys to fall back to a different map. Lua lets you use prototypes to override every operator, make the object callable, override map lookups for absent keys, and override assignment of new keys. All of these operations can be made to call into arbitrary functions the user provides. Python, an OO scripting language, provides all of the same features.
It seems to me that among these three languages there is a greater difference between the more powerful systems and the less powerful system than between the prototypal systems and the OO system.
Python also has generators, but you still need greenlet or stackless if you want to use coroutines. The inability to suspend from a subroutine is a deal breaker. Generators are probably nice for writing generators. For writing control flow, Continuation.js seems like a better choice.
=> lets you use a lexically scoped this, which is likely a dynamically scoped this from an enclosing lexical scope. This sounds useful, but it doesn't really make things less messy.
Sure if you prefer static typing then JS is not for you.
Continuations seem to be rare among other languages you could choose. Personally I have only seem them in LISP, what else is out there?
I would love to use LISP, but the libraries simply aren't there. Last time I tried Racket, there wasn't even a library for JSON.
I did not say anything about static typing. Most dynamic languages are not forced by their specs to coerce disparate types into utter garbage. I invite you to type the examples in the Wat talk into a REPL for any other dynamic language and see how many of them produce exceptions.
Before answering, I will point out that coroutines are equivalent to one-shot continuations, and coroutines that can be copied are equivalent to multi-shot continuations. Then, I am familiar with continuation implementations in the following languages: Python [1][2], Scala with any JVM runtime[3], Any JVM language with a particular runtime[4], C[5], Lua[6], Julia[7], and C++[8]. Of these, the ones for the JVM, C/C++, and Lua[9] are multi-shot continuations or equivalent to them, while Julia and Python are a bit more limited. I am not familiar with many languages, so I'm sure I've missed a lot of instances of this sort of feature.
I can't really speak to this because I haven't spent time trying to build real software using lisp.
[1] https://pypi.python.org/pypi/greenlet
[2] http://www.stackless.com/
[3] http://jim-mcbeath.blogspot.com/2010/08/delimited-continuati...
[4] http://oss.readytalk.com/avian/javadoc/avian/Continuations.h...
[5] http://en.wikipedia.org/wiki/Setcontext
[6] http://lua-users.org/wiki/CoroutinesTutorial
[7] http://docs.julialang.org/en/latest/manual/control-flow/
[8] http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/c...
[9] http://lua-users.org/lists/lua-l/2006-01/msg00652.html
That's changed since then: http://docs.racket-lang.org/json/index.html