I have quite some experience with most mainstream dynamic languages, and wouldn't do any large scale application with any of them.
The company I work for, does large scale enterprise consultancy projects.
This means:
- Multiple development sites;
- Some projects have up to 200 developers;
- Usually several megabytes of source code;
- Continuous Integration build systems with automatic unit and integration tests
- Usually distributed architecture
- High performance requirements
No way I would advise anyone to do develop such systems in a dynamic language, let alone in JavaScript.
Dynamic, weak typing makes writing static analysis/refactoring/etc tools extremely hard, but more importantly makes nearly any compile-time guarantees impossible. Having your app crash because of a small typo of a member name is impossible in C++/C#/Java. It happens to me almost once a day with Node/JS.
No-one should even be thinking about unit tests if they are not already using a language in which all code paths can be evaluated and type-checked at compile time. Why get a dog and bark yourself?
And you should do this with any language, typed or not.
On the other hand, pylint for Python is really good for static checking, even if it won't catch everything.
(I don't know anything about the GP, but I really haven't looked at Java development in 5++ years. (-: If nothing else, I might need to update my jokes :-) )
Annotations have the disadvantage of needing a recompile to reconfigure?
In any good development shop you make a change, your CI server picks it up, builds it, and creates a release candidate you deploy. Every change should be checked into source control and built by your automated build bot.
At that point the difference between changing an annotation and an XML configuration file should be moot. I'd think the annotation would be easier because you can still mess up the syntax of the XML file pretty easy (e.g. "Can you change the blahblah label to System & such?" That ampersand will hose your system when you get it to production).
But that's a tiny subset of what architecture astronauts try to label "configuration".
What I really miss from a maintainability point of view with javascript, on the other hand, is better development tools (ie IDEs and testing tools). I'm pretty sure there is a big opportunity there.
Not that javascript doesn't. It doesn't have the sugar around it, and it doesn't statically check them. But javascript's OO is not "prototype-based" (that doesn't even make sense, prototypes are not a unit of reuse in Self) and it's not anything even remotely close to Self's.
Javascript's OO is single-inheritance class-based with no `class` sugar but at the end of the day it behaves pretty much the same way (and offers no more features — less if anything) Python's or Ruby's class-based OO work (sans metaclasses).
The problem with JavaScript is not lack of 'classes', but a not just dynamic but also very weak type system.
Add to that the callback-hell caused by the async model of things like Node.js, and you end up with something very hard to maintain quite fast.
But to me its not really a critical issue, because OOP is very easy in CoffeeScript, which is my favorite language and happens to compile to JavaScript.