This is more of a rant against dynamically typed languages than against javascript itself, and making the argument that dynamically typed languages are not suitable for large web apps is a difficult (not impossible) one to make. The author also complains about some javascript projects being split up into enough files, which is hardly a side-effect of using javascript. The author inherited what sounds like a pretty disorganized javascript application and is using it as their real world example for why javascript shouldn't be used to write large web apps. In fact, almost everything in the post is anecdotal or subjective.
The OP seems to be very willing to draw general conclusions when none are warranted.
When faced with a project in which code modularization was a problem, his proposed solution was to port the code? Seriously? Port Javascript to Actionscript because the .js was organized into too few modules?
Yeah, this doesn't add a whole lot to the debate imo. I'm vaguely sympathetic to the argument that languages with more/better static analysis are better for large-scale development, but that particular argument has a whole lot written about it, and is probably still inconclusive.
And it's an Adobe blog. Their employees are quite likely to be biased in favour of their statically-typed variant, ActionScript 3 (well, it has a lot of changes, but it's essentially a JS variant at heart)
No. The problem with ES4 was that JavaScript is at heart not a traditional procedural OOP language. It's a functional language, and ES4 was trying to change that, a huge step in the wrong direction. They wanted more Java and less Script, but thankfully ES5 has gone the other direction, and given use more Script and less Java.
I find it very difficult to swallow anything written by the OP from the obstructed view at Adobe. After spending nearly every billable hour for more than three years buried in AS3's woeful inconsistencies, undocumented (or un-addressed) compiler issues, seemingly infinite application-crippling bugs, schizophrenic deprecation- any dev who had the misfortune of being relegated to work primarily in AS3 (and god help you if you had to support AS2 and AS3 applications simultaneously) the mere suggestion that Adobe has an opinion that is anything but a head up its own ass probably makes you break out in hives like i just did.
I also find objections like the "createBunnyOrToaster" antipattern to be really, really uncompelling. You don't need a static type system to make sure that your functions are sane and consistent, and you don't have to be John Resig either.
First of all, put a comment at the top of your function that says what to expect about the return value. You should be doing this anyway because the return type alone is often not sufficient for future programmers reading your code.
Secondly, every time you write the word "return", look up at the top of your function and make sure you are in accordance with what you said the function would do. If you end up with a paragraph comment about what the return value will be like, refactor.
> You don't need a static type system to make sure that your functions are sane and consistent, and you don't have to be John Resig either.
Right, and you can do structured programming in assembly. But when the language or tools don't help you do that, there are examples like the one the author points out where developers don't.
Don't mistake utility (what can be done) for usability (what is easy to do). Usability always matters.
> First of all, put a comment at the top of your function that says what to expect about the return value.
I want a language that gives me a nice pleasant syntax for doing that.
> Secondly, every time you write the word "return", look up at the top of your function and make sure you are in accordance with what you said the function would do.
As a programmer, you should be trained that when you see "every time", you think "automate this". If you and everyone on your team and everyone who has ever been on your team has to remember to do something every single time, your code will accumulate a pile of instances of forgetting.
Fixing that is exactly what tools and languages are for. It's a hell of a lot easier to make a disciplined tool than a more disciplined programmer. (And when you have made a more disciplined programmer, they typically evidence that by asking for more disciplined tools.)
Unfortunately static typing doesn't really fix the automation problems that are most common in software development any better than anything else. I wouldn't mistake a personal preference for static type systems and large complex IDEs for superiority of language or productivity.
I wouldn't mistake an appreciation for static types with a preference for large complex IDEs or a statement of language superiority. I work mostly in a text editor in a language whose static type system is far from mandatory.
> First of all, put a comment at the top of your function that says what to expect about the return value.
I want a language that gives me a nice pleasant syntax for doing that.
And I want a magic pony; but as I said, declaring the return type doesn't tell users anywhere near all they need to know in many cases. Truly self documenting code doesn't exist, and will probably never exist. And since you can't usefully discuss the return value without implicitly disclosing its type in the comments, declaring the type in the code is redundant.
Now granted, there are a few nice features that you get in terms of debugging by declaring the type in a way that the computer can read. But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
Conversely, there are some nice things you can do when the compiler isn't breathing down your neck to make sure that all of your types are consistent. If we had a static type system that allowed me to do elegant, type-agnostic things without getting in my way, that would be lovely. Haskell comes close, but even it falls short of the ideal. Ultimately I have never found the trade off to be worthwhile.
As a programmer, you should be trained that when you see "every time", you think "automate this".
I think that's pretty specious. You do need to consistently check to make sure that your code matches your comments and documentation. You simply can't automate that because humans and computers do not speak the same language.
This magic pony exists. That's what the author is trying to say. You can write magic pony code, and it can be run as JavaScript. Magic Pony -> JS Conversion!
Also, the OP doesn't have an issue dynamic languages as much as weak typed languages. It just happens that JS is weak and dynamic, while AS is strong and static.
Having switched between Java, ActionScript and JavaScript for the last four years, I can assure you that bugs happen all the time in weakly typed languages that wouldn't compile in strongly typed languages. Sure, it doesn't make it past refreshing the browser, but it's not uncommon for a coworker to check in changes to a JavaScript class that completely breaks a part of the application that the dev wasn't thinking about.
For instance, I've seen return objects switch from strings to ints because of how the strings were concatenated (return "Item " + x/returns string/; -> return x/returns int/;). Somewhere else in the function it returns early with "". Now you have other functions in other classes that check someFunction().length... error... sometimes...
The point is, you now have to write unit tests to check the TYPE of each value, and in many cases, it's not easy to tell. To check if an item is an array in JS, you have to do: Object.prototype.toString.call(obj) === '[object Array]'...
Since this checking needs to be done anyways, I'd rather it be done by the compiler rather than by a dev remembering to write a test for each possibility.
That's unreliable for client-side work because each frame has its own Array.prototype object which disavows instances that were created by code from different frames. It's a lot like Java classloaders, where if you aren't careful you can end up with several distinct and incompatible classes with identical names and (often) bytecode.
> but it's not uncommon for a coworker to check in changes to a JavaScript class that completely breaks a part of the application that the dev wasn't thinking about
You don't need to write unit tests to check the type of each value, you just need to have a decent set of integration tests to make sure you aren't breaking other parts of the app. If errors in the browser after a refresh don't help you catch it, failing integration tests will. This is how we do things on my large scale javascript project and it works out just fine; we have development challenges, for sure, but weak/dynamic typing issues is not one of them.
The point still stays. Why having to write even integration test for something that can be easily checked by compiler. Better focus on writing tests that cover functionality instead of making sure return types are correct.
Note that the comment didn't redundantly point out that "from" is a File and "to" is a String.
> But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
I actually get to perform this experiment all the time. I work on Dart. Dart has fully dynamically-typed runtime semantics, but also an optional static type checker that the Dart Editor uses to give you static warnings.
Up until recently, I've mostly write my code in a plain text editor. I do write type annotations, but I get no static checking whatsoever. They're basically comments.
Now that I'm using the Editor more, I can open up codebases I've written that were blind to static type checking and see what kinds of warnings it finds. I get some false positives (i.e. the bug is in the type annotation, not the code), but I also find a disheartening number of legit bugs, and this is in code with good test coverage.
I like dynamically-typed languages, but it turns out the static typing people aren't crazy: it really does find bugs.
>And I want a magic pony; but as I said, declaring the return type doesn't tell users anywhere near all they need to know in many cases.
Then you're doing it wrong. Write types that encapsulate all the information you need. Don't allow construction of invalid instances. It's not rocket science.
I've often had to work with code where the comments indicated an entirely different intention than the implementation. As a result, I'm a little paranoid and skeptical, that's all.
I also don't like the idea of having to comment each and every single function. If you have to write a comment to explain what it does, maybe you haven't named it properly?
There are a few people who are cautious and methodical enough to specify all types in comments and keep them correct. But you need an entire team of them, because type comments which are only mostly correct would be worse than useless. And an entire team wouldn't choose a dynamically-typed language that makes those showstopper bugs more likely.
Glad you wrote it so I didn't have to. If you have programmers making bad decisions in any language a project quickly becomes unmaintainable. I say take it back.
>making the argument that dynamically typed languages are not suitable for large web apps is a difficult (not impossible) one to make
Is it? And even if it is, why? Because dynamically typed languages are in vogue? Java does fine as a server-side webapp language, as does Dart (on the client too!), as does Go, etc.
As I read more of these arguments, it makes me think a lot about whether I should switch to CoffeeScript before my web app gets any larger. Has anyone switched to CS or another language that compiles to JS, and regretted it?
It's hard to imagine having much regret about a switch to CS since it would be so easy to convert your code back to JS if you ever needed to (and since you could do so incrementally).
I haven't used coffee script myself, but I think you'd be hard pressed to find someone that wrote something in CoffeeScript and regretted it. The biggest arguments against using CoffeeScript (or any language that compiles to JavaScript) that I seem to keep hearing are:
1. JavaScript isn't a very readable language. (I think this is untrue. I've seen some incredibly well written / structured JS)
2. Not everyone knows CoffeeScript, so when you put a project up on GitHub and it's written in CoffeeScript, it's difficult for people who only know the syntax of native JS to understand what's going on. (To counter this - a lot of projects that are written in CoffeeScript are bundled with the compiled JS code as well - which also happens to be very readable IMHO).
3. (biggest problem IMO): debugging in CS sucks right now. It would be a no-problem with SourceMap though, so we have to endure it just a few more months.
I hear this a lot, but seriously, have you ever had any real problems with debugging CS? The output is clear enough for anyone to know exactly where to go for the error.
It's a pain, still. I don't generate js files. When something like that happens, I have to go back to command-line, type 'coffee ...coffee', open generated js file and see where the problem was.
That's your problem right there ;) When you're using CoffeeScript, you're absolutely supposed to generate all of your JS files. -- For the same reason why you don't run all of your JavaScript via eval() while you're developing.
OK then. I have already 7-8 tabs in my terminal open all the time (a few for servers, some for redis, some for mongod, some for vi, some for other tools, some for debugging, etc.), so I guess another tab wouldn't hurt (I'm not a fan of running processes in the background).
doubtful. As a JS dev, I often find myself in situations where I wish I was working with CS instead.
However, this article isnt advocating CoffeeScript (well it is, but it doesnt actually make a case for it), its advocating using a statically typed language. CS gives you classes, but thats not a big deal (module pattern makes it trivial to implement classes in JS).
To scale your web app, the author is advocating writing your apps in Java, C# and actionscript.
Now that I think of it, this is a really poorly laid out argument. It spends most of the time arguing for static typing, then throws in CoffeeScript as a sop to the people who will flame him for advocating Java/C#/AS.
I haven't switched to coffeescript but I have worked on several coffeescript codebases. Its not the end of the world, but I don't prefer it. It is an unnecessary level of abstraction and is fragmenting js. It also seems the coffeescript users tend to use haml and sass as well. When I am working on those projects I feel like I am drowning in preprocessors and frequently encounter cryptic errors as a result.
I can't speak for haml, but sass is certainly a welcome tool in dealing with CSS, since it mostly uses CSS syntax, with sensible nesting to keep things orderly. sass takes what you already know and kicks it up one notch (perhaps two, if you want to use variables).
Coffeescript has a very similar object model, but it does alter (fix) the semantics of variable binding and expression statements and some unusably broken operators, and those involve treating Javascript more like a compilation target than an equivalent dialect.
I've used Coffeescript on a couple large Rails projects, and I'd rather stick with Javascript. I haven't encountered any terrible debugging hurdles, but it just seems like obfuscation. And unlike one of your other respondents, I love Sass and Haml. I have nothing against preprocessing per se, but I haven't yet figured out what value CS adds. I appreciate easier iteration, but that's about it. But considering how many people rave about it, I'm willing to learn....
This article doesn't really look like it's worth my time to read in depth so I won't comment on it directly. But as far as javascript goes Coffeescript makes a lot of the idiosyncracy of javascript that create constant cognitive friction go away. I personally can't find any good reasons to not use coffeescript.
I switched to CoffeeScript and continue to use it for 90% of my projects. CS shines in the application domain, but don't use it when writing modules or a complicated application where you'll be debugging lots of logic errors.
I don't know what this article is about (looks like it's not worth reading), but I've switched to CS (IcedCoffeeScript, to be precise) for my Node.js app (a behemoth of an app!), and am much much happier. Sure, it has problems too, but they are more tolerable than having to do (if typeof(x)=='function' && x!=null) over and over again IMO, and the vast majority of them will be gone when we have SourceMaps (which shouldn't take long, maybe a couple more months).
There's no contradiction in saying don't use javascript, use something that compiles to javascript. It's exactly the same as saying don't use C, use something that translates to C (i.e. C++ once). As for his example being anecdotal, almost all code snippets posted in a blog post can be attacked for that, and while it might be valid, it is pretty much impossible for the writer to give _any_ negative example without it being dismissed as "bad code is bad code" etc.
When combined with the assertion that "JS is the browser's assembly language", one can't quite say it's identical, because C isn't the OS's assembly language. Assembly language is.
Hear hear. He does have a point about that well known low level language 'javaScript'. Must be similar to the high level one of the same name. Also he makes the valid point that bad developers make for a bad project, what a genius. judging by the comments on the actual blog he must be the second coming of Christ.
Except Javascript isn't assembly, no matter how much the author would like to think so. It's a reasonably well featured, multi-paradigm high-level language.
...but it's got warts and gotchas which will catch out even experienced coders. It does make sense to use a language without the same problems which you know is guaranteed to generate "good" JS.
you might consider going back to slashdot. i didn't miss his point at all, try reading my comment again, but this time, try to read the statement "but Javascript isn't assembly" a little less literally.
While I agree that JavaScript can be better but suggesting to compile your code to JavaScript as default is something that I cannot feel comfortable with. Doing it once or twice if the need be so makes sense but phasing out JavaScript and writing code in high-level language only to compile it back to JavaScript does not feel right to me. Why add another layer (compilers) of code conversion only to increase the surface area for critical bugs?
I am aware of that, but I personally use JavaScript to mean the browser language, and all the browser's features (DOM, WebSocket, etc.), but node.js to mean JS in the node.js environment. Same core language, but different environments, so not the same in practise.
Actually a pretty decent part is in JS since most of the standard libraries are purely written in JS. Github claims that nearly 70% of the node repository is in JavaScript.
This article only proves the author's incompetence to develop and maintain large JavaScript projects, nothing more.
> I don’t know why but JavaScript programmers tend to put all of their code into few files. That’s not so useful, though, if you want to have multiple developers work on the same project. Splitting up the code into multiple files enabled us to scale the project.
Let me rephrase that:
"I don’t know why but incompetent programmers tend to put all of their code into few files."
Last time I checked JavaScript does not have a file count limit.
The author should learn to talk in first person. I'm pretty sure I could write a horrible ActionScript app, if I wanted to, but that would not make ActionScript horrible in general.
Ok, seriously, I'm sort of sick of the file-stew meme in software development these days. Our editors aren't particularly designed for the one-file-per-function method of development that's been ohh-so-common. Serious, if a file is under a hundred lines of code, it probably doesn't need to be a separate file, it only undermines the grouping value that files are useful for.
I know exactly why they do it- to cut down on HTTP requests. But then it's trivial to minify and compact your JS into a single file. It sounds like he's just worked on bad projects.
And also because browser-side JavaScript does not have standard modules, where one is able to 'import' another. So even in the development phase, pre-minification, one is discouraged from making new files because of the pain of adding corresponding <script> tags in the HTML file or files and then getting them in the right order, and the larger the project the less you want to be tracking those dependencies manually.
While you can use a module loader library you still have to choose one, learn it and its quirks and adapt other external libraries to use it (some of which might be written for another module loader or - horror of horrors - use their own half-arsed module system).
As for "file-stew" mentioned by the sibling comment, small units are good if you like code reuse. For example, I get sick of writing very basic classes like 'Rect' and 'Vector' (for graphics) over and over again.
In my opinion "That’s not so useful, though, if you want to have multiple developers work on the same project." is much more revealing. Has this guy never heard of VCS? If you use a modern VCS it does not make any difference if you split your source into lots of different files or have it all in one. At least not regarding the number of developers working on the project.
I do not like language {X}, but I do like language {Y}. Everyone should agree to write in language {Y}, so that we can all pretend that language {X} does not exist, and maybe then browsers will just start using {Y} natively.
The title of this article is very misleading. There's nothing wrong with the language itself. If you don't separate your application into layers, then of course it's going to be hard to maintain and bring new developers up to speed.
GWT? Seriously? I cannot think of any large, significant web app that has been written in GWT.
I thought it would be clear by now that we do not need Java Enterprise in our web browsers. The web seems to be moving the other way - we have lightweight libs such as jQuery, underscore, backbone etc... and they seem to provide JS with the necessary building blocks for larger, maintainable systems.
AdWords, AdSense, Flights, Hotel Finder, Offers, Wallet, The New Blogger, Chrome Webstore, Product Search, Public Data, New Google Groups, Orkut, Google Takeout, Google Pagespeed, Google WebFonts, Google Tables, Google Health (discontinued), Google Wave (discontinued), PlayN (basis of Angry Birds)
GWT doesn't get the fair share of respect it deserves. It's not enterprise java (j2ee and such), it's a toolkit that (amongst other things) lets you write and debug java, that gets compiled to javascript in the end. GWT is not modular in the same sense as jQuery/underscore/backbone/any other js library, that's its weakness but also its strength. Also, the same modularity of those libs is simultaneously its strength and weakness. You plug jQuery mobile and backbone, you have to hack the router. You plug backbone with rails, you have to hack backbone.sync; but that's okay, we're all hackers.
If you want to dismiss GWT because it's java that's ok, but there are alot of good reasons (some non-technical) to choose java instead of CS or whatever. In fact, if you look at the history of GWT, they had all these "enterprise" patterns such as EventBus or Composite Views, or any other thing that the backbone/spine/etc camps are re-writing right now.
No, simply no. GWT is everything we should be running screaming from, and yes because its Java and yes because it lets programmers be lazy and not go out of their comfort zone and fucking learning JavaScript
GWT's RequestFactory feature particularly stands out as a huge productivity win for CRUD apps. Also, many of the weaknesses commonly associated with Java are diminished now that Google's excellent Java libraries (Guava, Guice) have become more widespread (with GWT versions also avaiable).
But I think people try GWT once, realize that the built-in widgets and panels look terrible and never look back. But some of the features that they don't get to trying are the features that really makes GWT worth using (the EventBus, RequestFactory, UiBinder, the excellent localization support, etc.).
GWT also doesn't preclude using any other JavaScript libraries. JSNI (writing native JavaScript within GWT Java source) is relatively easy -- I don't think it is uncommon to pull in JQuery in a GWT app for its effects, for example.
I know what GWT is. I agree that it provides out of the box certain functionalities that require a bit of "glue code" when using other frameworks.
However, the whole "just write a desktop app and we will turn it into a web app" philosophy doesn't seem very web-oriented to me. Yes, it works, it's easy, but if one day you want to change your client-side code (i.e. use a different framework or something) you'll most likely have to change the server side as well. It just seems to be too RPC-centered and too monolithic. But maybe I'm wrong.
You can do standard REST, or whatever you want with GWT. IMHO what really sucks with GWT is the language; Java really sucks sometimes and its full of ceremony. Also, I think they made the same mistake that the Swing guys did: they provided for a toolkit but they didn't provide a framework, ie, a standard way of putting it all together.
Anyway, you can check what the jBoss guys are doing with GWT, looks good even for Java: http://www.jboss.org/errai I think that if Java ever gets proper closures it will may be more of an acceptable solution for some cases.
Like many commenters here, I'm not sure I can agree with the author's position. Plenty of in-browser apps go awry, but that's most often because the tools people start using (notably jQuery) just don't work well once you have a large collection of UI components on the page.
That said, the bulk of Google's web applications, for instance, are not written in GWT or Dart, but rather in JavaScript using Closure Library, and compiled using the Closure compiler. So I don't think the answer here is to not use JavaScript (although I can understand why people at Adobe would argue for that), but rather to use tools like Closure or Angular that make the process more straightforward.
Did they lint or unit test their code? Without having a way to verify that parts of your app work at a smaller level, of course it's going to get hairy when it starts to grow. Although a compile step verifies types, unit tests do that plus check against runtime errors. This is not a language problem.
For a certain definition of "large" and for certain domains ( especially finance ) his argument is very, very valid. 200 average developers working with GWT->JS are anyday going to be more productive than coding native JS to get the same functionality. This isn't anti-JS...end of the day if you are on the web your code is JS. Thing is, how do you get there - do you hire 20 pricey smart JQuery guys, or 200 average Java pgmmers. Pls go to a bank or any large finance shop - TONS of Java programmers, very familiar with navigating through verbose boilerplate Java code, very familiar with coding up some risk function or pricing algorithm in Java...mostly by abusing the heck out of the optimized collections library and its search & sort algos :) But so long as the damn pricing function prices corectly, eveybody's happy. So now all that stuff has been built & is sitting there as desktop apps with dirty swing UIs. 1000s of Java classes. Literally tens of 1000s. Nobody is going to rewrite it in JQuery/JS/coffeescript => No money, no mandate, no manpower, no expertise, but primarily no need to do so. GWT has captured precisely that sweet spot. First get rid of the fancy swing widgets - stick to simple GWT textareas & lists & panels & checkboxes & stuff. Then get rid of Java collections - replace with GWT lightweight collections. Then check some corner cases. Then compile to JS & optimize & you are done. The same shit now works on the web, & if its buggy you just debug your desktop app because they are essentially using the same logic. This is just how it is done in large financial shops. You are simply not going to hire JS folk & teach them financial algos & then get them to code those up in idiomatic jquery...takes too long. Just train the existing Java folk who already have the domain expertise to move from fullblown Java + swing to lightweight collections + GWT. It doesn't have to be pretty. We are not web shops or consumer frontends...this will still be accessed by people inside the bank...only not by downloading applets & standalone java apps, but via native JS.
Anyone who thinks they are going to do nothing but hire above-average programmers at any scale is downright naive. Design your system around an "average" employee, and you'll be far happier.
So so true. If you are hiring "pricey smart [sic] jQuery guys" then you're probably doing it wrong. You need to be looking for solid software engineers that know javascript well. If the developers you are hiring think (jQuery === javascript) and can't explain the difference between classical and prototypal inheritance , then you're screwed before you even begin.
I dislike the term frontend engineer or frontend anything because people use it to mean a whole range of things between JavaScript programmer, web designer, and HTML/CSS scripter. And while some people possess all three of those very different skills they are not at all the same thing.
Funny, the exact same question came up today. I'm curious what the actual difference between the two is as it's not apparent. (I use a mixture of function prototype with the extends pattern and CoffeScript which exports a function exporting a function.) From what I can see they behave the same as long as you follow the same pattern when writing a subclass.
Prototypal inheritance is native to JavaScript while, simply because JS doesn't have classes, you have to go through quite a lot of troubles to make classical inheritance work.
The main difference in many cases is memory usage. When cloning in prototypal inheritance, you point back to the prototype's function, unlike classical inheritance where you are copying methods on every instantiation.
Instead of comparing '20 smarty JQuery guys' with '200 average Java programmers', how about comparing '20 average JQuery programmers' with '20 average Java programmers'? Or comparing '20 smart JQuery guys' with '20 smart Java programmers'.
There are lots of jQuery programmers. They know (how to read the docs of) the whole API and close to nothing about low-level JS. jQuery is a powerful and useful tool but it has grown to "replace" JS in the minds of many.
Just to be clear: I don't like this situation at all.
200 developers of any kind simultaneously working on the same code base sounds like a nightmare to me. I sincerely hope they have many separate projects that communicate via APIs or something.
I guess I am not understanding why you would be compelled to re-write massive Java apps in JavaScript. Especially anything to do with heavy finance algos.
Replacing swing UI's seems like a reasonable thing to tackle using HTML/CSS/JavaScript. You could just pass data back and forth over HTTP if you are talking remote client/server or bundle a local webserver if running host only.
In the case of a platform like Windows 8, you can write actual apps using JavaScript (no server) but you can also write libraries in native code and access them directly from the JS.
I think this is just a classic case of "use the right tool for the job".
I am serious: Don’t write large web apps in JavaScript."
I don't know how the first flows from the second. Certainly I wouldn't write a large web app in Javascript! I might write Javascript in a large web app though.
So I agree and think the original article overreached.
Why exactly would one run financial pricing functions inside the browser? Doesn't this stuff belong in the backend and far out of the users reach? Isn't that insecure or gives up secret stuff?
I think your example of an Enterprise Finance app and TONS of Java programmers is over generalizing things a bit, of who can benefit from things like GWT.
I would contest, GWT is used by some people who sort of already grokked some of the points made by this article, some years back. For example, coding in JS giving a feel of coding in assembly, particularly without the help of any good editors.
Another example to break the Enterprise only narrative: 'Google Flights' is done in GWT. And you and me can guess, there won't be 200 avg developers coding that product.
I came from an Enterprise background before our Internet Startup. Few of us coded up our app, in 3 months flat out using mainly Java and GWT.
One of the reasons we chose GWT was that, when we started out IE 6 still had a considerable share, and GWT generated JS which ran on it very well (although slowly).
You fail to make a general point about JS. Instead you make the point that jQuery is inadequate for large apps, and I agree. Just because you failed with jQuery dosent mean JS can't be used. I've seen Big JS projects go horribly wrong, but I've alse seen big C# projects go horribly wrong (And COBOL and ...). Every time the projects didn't have good tests, a CI server, nightly builds, structured code reviews, a modular and simple design etc. If you use all the good practices available, big JS projects become maintainable.
It shines through in your post that you didn't do it close to right.
>Splitting up the code into multiple files enabled us to scale the project.
I really don't get this at all. More files == more scalable? Someone more knowledgeable about ... whatever topic is relevant here care to explain this to me?
I tend to like having discrete modules of code split up into separate files when I'm building large JavaScript apps (which is really all I do). It helps keep me organized. And I think it also makes version control run more smoothly.
Generally, I'll write a little build script in Node that concatenates and minifies all my JS and CSS before actually deploying to production to keep the number of HTTP requests down.
He means "scale the number of people working on the project at one time."
He's basically saying that if you have 10 files and 2 developers the chances of collision (or merging issues) is small, but having 20 developers working from 10 files makes things more sticky.
To some degree, he's not incorrect, in that over time, you'll spend more time managing the merging and conflict process than you will writing code.
Obviously, there are modern tools that will help alleviate this problem, but the deeper you go, the worse it is. This was the reason that "old" VCS had exclusive locks.
If you change an interface, and someone else adds a new client to the interface locking does not help. So file based locking does not guarantee that merge conflicts won't occur.
Managing essential merge issues relates to success at dividing work up into highly cohesive, loosely coupled units. The accidental merge issues are not a big deal in good environments.
Poorly written Javascript is not suitable for large web applications. This goes for any language. Competent Javascript developers will have many files that are concatenated into just one or two files as part of their build environment. Competent Javascript developers will use code quality tools such as jslint or jshint to find potential problems.
It’s too bad that you inherited a poorly written Javascript project, but that doesn’t mean the language you’re most familiar with was the best language for the job. This is a common response. “I know X, let’s use X!!!”
"Help! I don't know how to organize code in intelligent ways! This is the fault of the language we originally decided to use!"
I have to say after writing "large" web apps in PHP and also in 100% JS, I much prefer JS for front-facing stuff. I've not found organization to be a big issue...but maybe this is due to the fact that I use a JS framework for most of my larger apps (but then again, I did in PHP as well).
Like C "feels" like a language for low-level programming and PHP "feels" like it should be running on a webserver, javascript "feels" like it's right at home in the browser. And now that browsers are powerful enough to be the entire front-end, I've come to completely embrace JS for this task.
Javascript is not a bad language. It's a very powerful language. Just like any other language, if it's poorly organized it's going to be a mess. I can tell you, from my experience, it is suitable for large web apps!!
Also, you can't ignore that this is hosted by Adobe...
"Help! I don't know how to organize code in intelligent ways! This is the fault of the language we originally decided to use!"
The problem might not be you. Once you are done with your organized code and are moved to another project, some 'junior' dev gets a hold of your stuff and makes simple mistakes that static-typed languages could've avoided.
I'm not anti-JS btw, just throwing out one possibility.
It might be ad hominem out of context, but I don't feel it's improper to question the motives of someone working for a company that would most likely benefit from a decline in javascript in the app space.
To illustrate his point let me show you my cross-compiled and optimized JavaScript code of SpriteExample, which is included in Adobe’s online documentation about the Sprite class. As you can see the JavaScript code is extremely dense and no longer readable.
This contains some minified JavaScript... Of course it looks dense & no longer readable. Run the ActionScript Sprite class through gzip compression and I'm sure it'd look funky too.
The author also advocates the use of CoffeeScript - which would have the vast (all?) of the same complaints he's raised against JavaScript.
I'm not a specialist on this topic (i.e. I'm only a programmer, not a computer scientist), but I don't seem to remember any links posted to relevant such studies in any of the "static vs. dynamic typing" flame wars.
Also, a little bit OT, I've been a professional programmer for 7 years now (i.e. getting paid to write code) and to this day I'm not sure 100% what's the difference between "0", "NULL", "None" or an empty string. What type does "None" belong to? Can I compare it to the integer 0?
"I've been a professional programmer for 7 years now (i.e. getting paid to write code) and to this day I'm not sure 100% what's the difference between "0", "NULL", "None" or an empty string. What type does "None" belong to? Can I compare it to the integer 0?"
Yes. A couple of weeks back on either hacker news or reddit (I just searched, and could not find it quickly), there was a seemingly well conducted experiment, with a large number of students randomized to static and dynamic languages, that found no statistically significant difference.
Actually, the study found that static languages were worse. They tested students on two problems. In one there was no significant difference, and in the other the static language performed worse.
Here is that study: "An Experiment About Static and Dynamic Type Systems", by Stefan Hanenberg, University of Duisberg-Essen, 2010.
However, they didn't use existing languages; they created a brand new language and IDE that had a typed and untyped variant. Whether this confounds or strengthens the case is unclear to me.
In any case, I think any survey of static type systems that doesn't include a language with type inference is very flawed. Java's type system is an annoyance in the small, and is a mixed bag in the large. Haskell's type system is a totally different story.
If you look at the HN thread where that paper was discussed, people on both sides were shooting holes in it. That's partly why I'm asking, is there anything solid on this out there at all? People are just repeating the same beliefs over and over. We've all heard them a zillion times and we all divide them into two categories: "shit I agree with" and "bullshit".
What experiments could be done to test these beliefs?
I think one would need to start by testing a different question first : "With everything else being equal, should your language choice be affected by the level of competence of the developers?".
It seems discussions on topics like this all boil down to clash between the idealist and the pragmatist. Idealist: "I want to use language X because it is powerful and lets me to Y". Pragmatist: "but that feature will be abused by the average developer and your project will suffer". So you can't win. Either you have to work in a mediocre language that the mediocre developer knows how to use, or you will work in a great language that the mediocre developer will use to shoot you in the foot.
If the answer to the above question is no, then we can put this discussion to rest - otherwise we will need to probe further and understand how developer competence should guide your language choice.
Obviously there may be different requirements in different contexts, but I don't understand why anyone writes large web apps entirely in one language.
I, too, once believed the mantras that "multiple languages present a maintenance nightmare" and "it's better to keep a common language for the sake of acquiring new hires" and on and on... But after some years, I disagree with that rationale.
In my experience, it's been more productive to have some sort of service-oriented architecture, built around your preferred protocol and data format. Then you can choose the languages that best suit your project needs (a decision most often based on the best available libraries). Popular languages are very similar, and it's easy to cruise between them...
I recognize the need to strike some balance in an organization. You don't want 50 services each in some emerging/obscure language, but I think that most folks (at least those who frequent this site) are savvy enough to know when you've hit that threshold. In our organization, we have developers who are globally distributed, and we write services in a variety of languages. We tend to standardize on the JVM: Java, Clojure, Groovy, but we've got some C# services, a lot of XSL, PowerBuilder (yuck), and even VB. I typically have discretion to use the language of my choice.
ASIDE: I always emphasize the "script" in JavaScript and rarely use it in any type of OOP style (except for the occasional lightweight library); the examples in the OP link made me cringe.
yes, "spaghetti code is not suitable for large web apps" nor apps in general.
that is why things like Ember.js are springing to life - to give the structure necessary to build large web apps without them devolving into spaghetti.
RequireJS or one of its AMD cousins would have been all that you needed to handle the "too few files" problem that prevented you from scaling the project's development.
217 comments
[ 2.9 ms ] story [ 215 ms ] threadWhen faced with a project in which code modularization was a problem, his proposed solution was to port the code? Seriously? Port Javascript to Actionscript because the .js was organized into too few modules?
mmmm-okay.
First of all, put a comment at the top of your function that says what to expect about the return value. You should be doing this anyway because the return type alone is often not sufficient for future programmers reading your code.
Secondly, every time you write the word "return", look up at the top of your function and make sure you are in accordance with what you said the function would do. If you end up with a paragraph comment about what the return value will be like, refactor.
Right, and you can do structured programming in assembly. But when the language or tools don't help you do that, there are examples like the one the author points out where developers don't.
Don't mistake utility (what can be done) for usability (what is easy to do). Usability always matters.
> First of all, put a comment at the top of your function that says what to expect about the return value.
I want a language that gives me a nice pleasant syntax for doing that.
> Secondly, every time you write the word "return", look up at the top of your function and make sure you are in accordance with what you said the function would do.
As a programmer, you should be trained that when you see "every time", you think "automate this". If you and everyone on your team and everyone who has ever been on your team has to remember to do something every single time, your code will accumulate a pile of instances of forgetting.
Fixing that is exactly what tools and languages are for. It's a hell of a lot easier to make a disciplined tool than a more disciplined programmer. (And when you have made a more disciplined programmer, they typically evidence that by asking for more disciplined tools.)
I want a language that gives me a nice pleasant syntax for doing that.
And I want a magic pony; but as I said, declaring the return type doesn't tell users anywhere near all they need to know in many cases. Truly self documenting code doesn't exist, and will probably never exist. And since you can't usefully discuss the return value without implicitly disclosing its type in the comments, declaring the type in the code is redundant.
Now granted, there are a few nice features that you get in terms of debugging by declaring the type in a way that the computer can read. But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
Conversely, there are some nice things you can do when the compiler isn't breathing down your neck to make sure that all of your types are consistent. If we had a static type system that allowed me to do elegant, type-agnostic things without getting in my way, that would be lovely. Haskell comes close, but even it falls short of the ideal. Ultimately I have never found the trade off to be worthwhile.
As a programmer, you should be trained that when you see "every time", you think "automate this".
I think that's pretty specious. You do need to consistently check to make sure that your code matches your comments and documentation. You simply can't automate that because humans and computers do not speak the same language.
This magic pony exists. That's what the author is trying to say. You can write magic pony code, and it can be run as JavaScript. Magic Pony -> JS Conversion!
Also, the OP doesn't have an issue dynamic languages as much as weak typed languages. It just happens that JS is weak and dynamic, while AS is strong and static.
Having switched between Java, ActionScript and JavaScript for the last four years, I can assure you that bugs happen all the time in weakly typed languages that wouldn't compile in strongly typed languages. Sure, it doesn't make it past refreshing the browser, but it's not uncommon for a coworker to check in changes to a JavaScript class that completely breaks a part of the application that the dev wasn't thinking about.
For instance, I've seen return objects switch from strings to ints because of how the strings were concatenated (return "Item " + x/returns string/; -> return x/returns int/;). Somewhere else in the function it returns early with "". Now you have other functions in other classes that check someFunction().length... error... sometimes...
The point is, you now have to write unit tests to check the TYPE of each value, and in many cases, it's not easy to tell. To check if an item is an array in JS, you have to do: Object.prototype.toString.call(obj) === '[object Array]'...
Since this checking needs to be done anyways, I'd rather it be done by the compiler rather than by a dev remembering to write a test for each possibility.
You don't need to write unit tests to check the type of each value, you just need to have a decent set of integration tests to make sure you aren't breaking other parts of the app. If errors in the browser after a refresh don't help you catch it, failing integration tests will. This is how we do things on my large scale javascript project and it works out just fine; we have development challenges, for sure, but weak/dynamic typing issues is not one of them.
It doesn't declare all they need to know, but it covers a good fraction of it. As a really nice bonus, it's machine checkable.
> And since you can't usefully discuss the return value without implicitly disclosing its type in the comments
I don't seem to have this problem. I have lots of comments that are like:
Note that the comment didn't redundantly point out that "from" is a File and "to" is a String.> But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
I actually get to perform this experiment all the time. I work on Dart. Dart has fully dynamically-typed runtime semantics, but also an optional static type checker that the Dart Editor uses to give you static warnings.
Up until recently, I've mostly write my code in a plain text editor. I do write type annotations, but I get no static checking whatsoever. They're basically comments.
Now that I'm using the Editor more, I can open up codebases I've written that were blind to static type checking and see what kinds of warnings it finds. I get some false positives (i.e. the bug is in the type annotation, not the code), but I also find a disheartening number of legit bugs, and this is in code with good test coverage.
I like dynamically-typed languages, but it turns out the static typing people aren't crazy: it really does find bugs.
Then you're doing it wrong. Write types that encapsulate all the information you need. Don't allow construction of invalid instances. It's not rocket science.
Great, so now the documentation for the function will promise to return a motorcycle, but instead return either a bunny or a toaster.
There are lies, damn lies, and boilerplate code comments.
Not if you follow the second part of my above advice.
>There are lies, damn lies, and boilerplate code comments.
Since when is a comment that explains what a function does "boilerplate"? I think you are confused.
I also don't like the idea of having to comment each and every single function. If you have to write a comment to explain what it does, maybe you haven't named it properly?
Is it? And even if it is, why? Because dynamically typed languages are in vogue? Java does fine as a server-side webapp language, as does Dart (on the client too!), as does Go, etc.
This resource has been invaluable: http://js2coffee.org/
1. JavaScript isn't a very readable language. (I think this is untrue. I've seen some incredibly well written / structured JS) 2. Not everyone knows CoffeeScript, so when you put a project up on GitHub and it's written in CoffeeScript, it's difficult for people who only know the syntax of native JS to understand what's going on. (To counter this - a lot of projects that are written in CoffeeScript are bundled with the compiled JS code as well - which also happens to be very readable IMHO).
Try using `coffee --watch` instead.
However, this article isnt advocating CoffeeScript (well it is, but it doesnt actually make a case for it), its advocating using a statically typed language. CS gives you classes, but thats not a big deal (module pattern makes it trivial to implement classes in JS).
To scale your web app, the author is advocating writing your apps in Java, C# and actionscript.
Now that I think of it, this is a really poorly laid out argument. It spends most of the time arguing for static typing, then throws in CoffeeScript as a sop to the people who will flame him for advocating Java/C#/AS.
His arguments have to do with the semantics of JavaScript, which are identical to the semantics of CoffeeScript.
His main example of why javascript isn't suitable is an anecdote about a badly developed code base written in javascript. Seriously?
Yknow, most every language ever.
If you had read the article, you'd see that the author made this comparison.
Sure, it's the "assembly language of the web," but Javascript certainly cannot be compared to assembly language in this way.
I thought ActionScript was a specialization of JavaScript, which is ECMAScript. Is this not right?
ActionScript, Dart, Java, PHP, node.js, Ruby, Go... ;)
> I don’t know why but JavaScript programmers tend to put all of their code into few files. That’s not so useful, though, if you want to have multiple developers work on the same project. Splitting up the code into multiple files enabled us to scale the project.
Let me rephrase that:
"I don’t know why but incompetent programmers tend to put all of their code into few files."
Last time I checked JavaScript does not have a file count limit.
The author should learn to talk in first person. I'm pretty sure I could write a horrible ActionScript app, if I wanted to, but that would not make ActionScript horrible in general.
- if function A and B are always used together, than they are one file.
- if linecount gets to big, split A and B into separate files
- if function C is shared between modules than it belongs in it's own file
So far it worked out great.
While you can use a module loader library you still have to choose one, learn it and its quirks and adapt other external libraries to use it (some of which might be written for another module loader or - horror of horrors - use their own half-arsed module system).
As for "file-stew" mentioned by the sibling comment, small units are good if you like code reuse. For example, I get sick of writing very basic classes like 'Rect' and 'Vector' (for graphics) over and over again.
I thought it would be clear by now that we do not need Java Enterprise in our web browsers. The web seems to be moving the other way - we have lightweight libs such as jQuery, underscore, backbone etc... and they seem to provide JS with the necessary building blocks for larger, maintainable systems.
I would consider the AWS management console to be significant.
Wait, you don't work for Amazon, so I'm confused...
http://gwtreferencelist.appspot.com/#AboutPlace:
If you want to dismiss GWT because it's java that's ok, but there are alot of good reasons (some non-technical) to choose java instead of CS or whatever. In fact, if you look at the history of GWT, they had all these "enterprise" patterns such as EventBus or Composite Views, or any other thing that the backbone/spine/etc camps are re-writing right now.
But I think people try GWT once, realize that the built-in widgets and panels look terrible and never look back. But some of the features that they don't get to trying are the features that really makes GWT worth using (the EventBus, RequestFactory, UiBinder, the excellent localization support, etc.).
GWT also doesn't preclude using any other JavaScript libraries. JSNI (writing native JavaScript within GWT Java source) is relatively easy -- I don't think it is uncommon to pull in JQuery in a GWT app for its effects, for example.
However, the whole "just write a desktop app and we will turn it into a web app" philosophy doesn't seem very web-oriented to me. Yes, it works, it's easy, but if one day you want to change your client-side code (i.e. use a different framework or something) you'll most likely have to change the server side as well. It just seems to be too RPC-centered and too monolithic. But maybe I'm wrong.
Anyway, you can check what the jBoss guys are doing with GWT, looks good even for Java: http://www.jboss.org/errai I think that if Java ever gets proper closures it will may be more of an acceptable solution for some cases.
That said, the bulk of Google's web applications, for instance, are not written in GWT or Dart, but rather in JavaScript using Closure Library, and compiled using the Closure compiler. So I don't think the answer here is to not use JavaScript (although I can understand why people at Adobe would argue for that), but rather to use tools like Closure or Angular that make the process more straightforward.
This is the problem, and as you implicate, the exact sort of thing we need to stop doing.
Hint: the best developers aren't the ones who can recite the API off hand.
Anyone who thinks they are going to do nothing but hire above-average programmers at any scale is downright naive. Design your system around an "average" employee, and you'll be far happier.
It's easier to grow them.
See, this is how I knew you knew nothing about JavaScript.
My bets, you're a manager that manages shitty Java coders who "used to code" and is an obnoxious know-it-all.
Scale of 1-10, how close am I?
Edit:
From your website: "currentlly: BofA" (sic).
Feeling pretty warm on my bet so far.
This is why I don't ask for a "jQuery" guy, I ask for a frontend engineer who's a solid programmer and likes working on interesting products.
What's your point about JavaScript?
I'm not happy that somebody who very evidently doesn't have a clue what they're talking about is the top comment.
When people stop upvoting complete and utter tripe (which is nutritious btw), my response stops being necessary.
I'd react the same way to any sort of ignorant pontification on clearly foreign (to them) material.
Raise a fool on a litter and I'll tackle the people carrying the litter.
I'm quite open to being proven wrong, but I don't expect to be.
Just to be clear: I don't like this situation at all.
Replacing swing UI's seems like a reasonable thing to tackle using HTML/CSS/JavaScript. You could just pass data back and forth over HTTP if you are talking remote client/server or bundle a local webserver if running host only.
In the case of a platform like Windows 8, you can write actual apps using JavaScript (no server) but you can also write libraries in native code and access them directly from the JS.
I think this is just a classic case of "use the right tool for the job".
"JavaScript is not suitable for large web apps.
I am serious: Don’t write large web apps in JavaScript."
I don't know how the first flows from the second. Certainly I wouldn't write a large web app in Javascript! I might write Javascript in a large web app though.
So I agree and think the original article overreached.
I would contest, GWT is used by some people who sort of already grokked some of the points made by this article, some years back. For example, coding in JS giving a feel of coding in assembly, particularly without the help of any good editors.
Another example to break the Enterprise only narrative: 'Google Flights' is done in GWT. And you and me can guess, there won't be 200 avg developers coding that product.
I came from an Enterprise background before our Internet Startup. Few of us coded up our app, in 3 months flat out using mainly Java and GWT.
One of the reasons we chose GWT was that, when we started out IE 6 still had a considerable share, and GWT generated JS which ran on it very well (although slowly).
I really don't get this at all. More files == more scalable? Someone more knowledgeable about ... whatever topic is relevant here care to explain this to me?
Generally, I'll write a little build script in Node that concatenates and minifies all my JS and CSS before actually deploying to production to keep the number of HTTP requests down.
He's basically saying that if you have 10 files and 2 developers the chances of collision (or merging issues) is small, but having 20 developers working from 10 files makes things more sticky.
To some degree, he's not incorrect, in that over time, you'll spend more time managing the merging and conflict process than you will writing code.
Obviously, there are modern tools that will help alleviate this problem, but the deeper you go, the worse it is. This was the reason that "old" VCS had exclusive locks.
Managing essential merge issues relates to success at dividing work up into highly cohesive, loosely coupled units. The accidental merge issues are not a big deal in good environments.
It’s too bad that you inherited a poorly written Javascript project, but that doesn’t mean the language you’re most familiar with was the best language for the job. This is a common response. “I know X, let’s use X!!!”
Also, Javascript is a high level language.
I have to say after writing "large" web apps in PHP and also in 100% JS, I much prefer JS for front-facing stuff. I've not found organization to be a big issue...but maybe this is due to the fact that I use a JS framework for most of my larger apps (but then again, I did in PHP as well).
Like C "feels" like a language for low-level programming and PHP "feels" like it should be running on a webserver, javascript "feels" like it's right at home in the browser. And now that browsers are powerful enough to be the entire front-end, I've come to completely embrace JS for this task.
Javascript is not a bad language. It's a very powerful language. Just like any other language, if it's poorly organized it's going to be a mess. I can tell you, from my experience, it is suitable for large web apps!!
Also, you can't ignore that this is hosted by Adobe...
The problem might not be you. Once you are done with your organized code and are moved to another project, some 'junior' dev gets a hold of your stuff and makes simple mistakes that static-typed languages could've avoided.
I'm not anti-JS btw, just throwing out one possibility.
This may be true, but it's an ad hominem attack.
http://en.wikipedia.org/wiki/Ad_hominem#Questions_about_the_...
To illustrate his point let me show you my cross-compiled and optimized JavaScript code of SpriteExample, which is included in Adobe’s online documentation about the Sprite class. As you can see the JavaScript code is extremely dense and no longer readable.
This links to http://jsfiddle.net/bparadie/cbU2X/
This contains some minified JavaScript... Of course it looks dense & no longer readable. Run the ActionScript Sprite class through gzip compression and I'm sure it'd look funky too.
The author also advocates the use of CoffeeScript - which would have the vast (all?) of the same complaints he's raised against JavaScript.
All in all, a pretty terrible article.
Also, a little bit OT, I've been a professional programmer for 7 years now (i.e. getting paid to write code) and to this day I'm not sure 100% what's the difference between "0", "NULL", "None" or an empty string. What type does "None" belong to? Can I compare it to the integer 0?
been doing PHP by any chance? ;)
Here is that study: "An Experiment About Static and Dynamic Type Systems", by Stefan Hanenberg, University of Duisberg-Essen, 2010.
http://www.cs.washington.edu/education/courses/cse590n/10au/...
However, they didn't use existing languages; they created a brand new language and IDE that had a typed and untyped variant. Whether this confounds or strengthens the case is unclear to me.
In any case, I think any survey of static type systems that doesn't include a language with type inference is very flawed. Java's type system is an annoyance in the small, and is a mixed bag in the large. Haskell's type system is a totally different story.
What experiments could be done to test these beliefs?
I, too, once believed the mantras that "multiple languages present a maintenance nightmare" and "it's better to keep a common language for the sake of acquiring new hires" and on and on... But after some years, I disagree with that rationale.
In my experience, it's been more productive to have some sort of service-oriented architecture, built around your preferred protocol and data format. Then you can choose the languages that best suit your project needs (a decision most often based on the best available libraries). Popular languages are very similar, and it's easy to cruise between them...
I recognize the need to strike some balance in an organization. You don't want 50 services each in some emerging/obscure language, but I think that most folks (at least those who frequent this site) are savvy enough to know when you've hit that threshold. In our organization, we have developers who are globally distributed, and we write services in a variety of languages. We tend to standardize on the JVM: Java, Clojure, Groovy, but we've got some C# services, a lot of XSL, PowerBuilder (yuck), and even VB. I typically have discretion to use the language of my choice.
ASIDE: I always emphasize the "script" in JavaScript and rarely use it in any type of OOP style (except for the occasional lightweight library); the examples in the OP link made me cringe.
that is why things like Ember.js are springing to life - to give the structure necessary to build large web apps without them devolving into spaghetti.