Elevate Software


Login Login

ProductsBulletSalesBulletSupportBulletDownloadsBulletAbout





Home  Elevate Software Blog

Icon Elevate Software Blog

Tags Showing all blog entries tagged with "JavaScript"

Why Limit Web Development to JavaScript ?
Posted by Tim Young on Fri, Aug 7 2015

I've been doing some browsing and reading recently, catching up on the current state of affairs in software development, and I came across several mentions of a quote by Anders Hejlsberg from the 2012 Lang.NEXT conference, where he was part of an expert panel on web/cloud development. You can watch the discussion yourself here:

Lang.NEXT 2012 Expert Panel: Web and Cloud Programming

I don't get as much chance as I'd like to keep up with what's going on in the industry, so at the time I missed this particular quote. In case you've been living in an even deeper cave than myself and don't know who Anders is, he created Turbo Pascal, was the chief architect of Delphi, is/was (?) the lead architect for C#, and is now working on the TypeScript language at Microsoft. As one can imagine, he definitely has some insights into the requirements of a successful development language.

During the discussion, he was asked the direct question:

"Are you saying you cannot write large programs in JavaScript?"

and he replied:

"No, you can write large programs in JavaScript. You just can't maintain them."

I won't profess to speak for Anders, but I would assume that he was talking in broad strokes with this response, and was not saying that all large JavaScript programs are un-maintainable. Rather, given a typical organization with typical resources and the typical amount of screw-ups and craziness that accompanies software development, one will typically find that large applications written in JavaScript are difficult-to-very-difficult to maintain. I'm sure that Google has no issues with throwing enough resources at flagship properties like GMail or YouTube to get them to work. But, it's probably a bad idea to predicate the success of a large segment of the software industry on always having Google-like resources at our disposal.

Of course, various blogs lit up with indignant responses, and the biggest pushback appeared to be coming from who you would expect: JavaScript developers.

Now, when I read the quote my first reaction was "duh !". This was one of the primary reasons that I started developing Elevate Web Builder in 2010-2011. Elevate Web Builder compiles Object Pascal into JavaScript, but this is not a unique idea and there are many compilers/transcoders that do the same for many different languages:

List of languages that compile to JS

Let's start out with some self-evident observations:
  • There's definitely something amiss with a language if there's a list that long of compilers/transcoders whose sole purpose is to avoid writing code in the target language.


  • JavaScript development can't be that bad, otherwise we wouldn't see the millions of web sites/web applications that are powered by JavaScript code.


  • The JavaScript engines in the various modern browsers are very good. Performance is spectacular on desktop, and normally acceptable on mobile.
So, the question is not really "Is JavaScript, the language, any good ?", but rather "Should we use only JavaScript for web development ?".

Of course, once you start getting into "should" territory, you're normally talking about very subjective arguments. But, I think it's easier than that, and I'll try to demonstrate that the arguments against using only JavaScript are not subjective at all, and are easily recognized with an objective eye. But, please don't mistake the following points for a claim that other languages are perfect, or that you cannot do stupid, awful things with them. You can, and we all do. At issue here is whether we are moving forward or backward by using only JavaScript. I also think it's important to note here that much of JavaScript's maintainability problems stem from the fact that it's a very flexible language. In fact, in many ways it's similar to much lower-level languages in the sense that it lets you do just about anything. Unfortunately, flexibility is often the converse of maintainability. It is often the case that the languages we choose to use for development are as much about preventing us from doing bad things, as they are about allowing us to do good things.

Code Size
Because JavaScript is shipped to the browser as textual source code, there has traditionally been a size limit forced upon JavaScript developers that is derived from the bandwidth of a typical user's Internet connection. In the early days of browser development, connections were so slow that even a 30-50k source file would have been considered suicide. This resulted in source code that tried to keep identifiers as short as possible, which should not be necessary and is completely contrary to good software engineering practices. JavaScript minification was developed to ease this burden, but I'm probably not the only person in the world (or maybe I am) to wonder: if one needs to post-process their source code prior to deployment, then perhaps we should use this as an opportunity to recognize that shipping readable source code to a remote execution environment is probably not a wise choice. It's simple logic. If we don't ever want to ship source code because it's too large or there are IP issues involved, and the resulting minified source code isn't readable by a human, then why are we arbitrarily restricting ourselves to one language ? Shouldn't we just compile to web assembly ?

One can also imagine that this problem will only get worse as single-page web applications that load as pure JavaScript, such as Elevate Web Builder, become more and more prevalent, and as SAAS continues to replace traditional desktop/LAN applications.

This code size issue also plays into the problems with modularization and packaging of deployed code. Minification is great for monolithic source files, but is a non-starter for any identifiers in library source files. One can work around this by providing mappings in the library source code between the "real" identifiers and the minified identifiers, but once you start going down that road you will eventually discover that it's simply easier to just keep non-minified identifiers for any "public" objects/functions. Of course, if you're doing what you're supposed to and re-using code, then probably 80-90% of your code is in, or should be in, such library source files, and there goes any benefits of minification. This is why I just said "screw it" with Elevate Web Builder and had it generate a single monolithic JavaScript source file for each application. The reduced code size from aggressive minification/compression across the entire identifier space, including the component library, far outweighs any downsides from including more code. And, I removed any dependency issues in the process. Proper signed/versioned module support in the browser, combined with web assembly (above) that supports exporting symbols, could be a solution for these issues.

Structure
JavaScript lacks any formal structure whatsoever, other than the ability to organize code into functions and "objects" via prototypes. It has no formal modules or namespaces, and there are two implicit scopes: function and global (I'm including constructors in the "function" category). Object instances are essentially hash tables, which means you can do things like this with them:

// Declare the Car prototype

function Car (type) {
    this.type = type;
    this.color = "red";
    this.drive = function() { return "Vrroommm !!!!!" };
}

// Create a Car instance

var car = new Car('Ferrari');
car.color = "red";
car.engine = "V8";
alert(car.engine); // where did that come from !

car.drive = function() { return "Wrrrrrrrr !!!!!" }
alert(car.drive()); // that's not a sound a Ferrari makes

You can define methods for any object, but they are simply references to functions that can be overwritten just like any other property. Namespaces and certain types of class scopes can be fudged using nested object literals, and the language is making progress towards proper classes with configurable properties and sealing/freezing objects, but these are all features that are not implicit/enforced and must be consciously used by the developer. One gets the distinct sense that the JavaScript (ECMAScript, officially) language committee is trying to "close the barn door after the horse has left".

Type System
Conversations about formal types in JavaScript tend to get very heated, and many JavaScript developers vehemently deny that the lack of a formal type system is an issue for the language. I've read comments from developers that blame other developers for their inability to always write perfect JavaScript code without runtime type errors. To me, this is just nuts. When, God forbid, an airliner crashes due to pilot error, or a surgeon amputates the wrong limb, we don't dwell on the fact that a human being made a mistake. No, in fact we immediately begin to examine the systems in place that allowed the human error to be introduced in the first place. I don't mean to diminish the gravity of such real-life horrors by comparing them to a UI bug in a browser application, but there is something to be learned here in how such errors are handled.

So, let's start out with the simplest question: why ? Why would you want to be forced to worry about creating unit tests and other automated tests to catch simple bugs that compilers with formal type systems have been catching for many years ? Isn't it the entire purpose of computers and software to process huge amounts of information in an error-free way, over and over again, so that we don't have to ?

A JavaScript developer might reply: yes, but then you have to declare types for everything and do things like casting to satisfy the compiler.

Again, a simple question: are you writing completely undocumented code ? If not, then I can pretty much guarantee that you're specifying a type for that variable or parameter, and there's a very good chance that it's located in a documentation comment block right above the actual function. Go take a look at the Google Maps API, or documentation for the built-in browser DOM objects and functions. What you'll find is that almost all of the function parameters, variables, and properties are documented as using a specific type. A formal type system would a) make in-source type documentation unnecessary, and b) make the source code self-documenting. In addition, documentation skeletons can be automatically created directly from the source code (this is what we do here at Elevate Software) and IDE productivity features like code completion and refactoring can be used.

An easy thought experiment is this: what would you rather step in to maintain ? An application built in a language that had no formal type system, or a language that does ? Anyone that indicates the former is not being 100% honest. It's just a plain fact that its easier, relatively speaking, to read source code that has formal type information. This does not account for other aspects of the code, of course.

Finally, let me put forth the most important question when deciding to use a language like JavaScript with no formal type system: what exactly are you gaining by not having types ? The ability to define a function parameter that can accept any type of value ? Many modern languages with formal type systems have variant types for things like this, so that's not a plus, and removing all types just for this one capability amounts to "throwing the baby out with the bathwater". Apart from that, I'm hard-pressed to come up with a reason why one would want to not have types, other than it saves some additional keystrokes. I think that when you start selecting a language based upon the number of keystrokes required, you're using the wrong productivity metric. Typing is easy. Typing error-free code is not.

Case-Sensitivity
Ugh. There's not much need to say any more, other than this: case-sensitive languages are a forest-for-the-trees nightmare that work against the way that the human mind works. Especially a tired human mind that's been writing code for hours. They're a waste of time with no tangible benefits. Combining case-sensitivity with runtime compilation of source code, as JavaScript does (it's not alone in this regard), is a recipe for creating bugs that would normally be easily caught by the developer or the compiler.

Summary
I'll wrap things up with what I think is the most compelling argument against using only JavaScript for web applications. The web browser today has grown way beyond just a documentation presentation environment. It is no longer just being used for minimally-functional web sites. As evidenced by Elevate Web Builder, and products like it, you can build entire full-featured front-end applications that rival the functionality in desktop client applications. Application execution environments like operating systems and browsers should be language-agnostic for the simple reason that many different languages already exist, and have existed for many years prior to JavaScript, and there are millions of developers in the world that have many years of experience in these other languages. It makes much more sense, in time and money, to leverage these existing skills than to force every developer on the planet to code in the JavaScript language "just because". Furthermore, by excluding these existing language skills, you're excluding a whole host of IDEs, libraries, frameworks, etc. that could be written (or modified) to target this web execution environment. Windows languished in the development arena until developers like Anders Hejlsberg and the team at Borland started creating easy-to-use Pascal compilers and IDEs in the 90's that provided a better, more productive abstraction for the Windows API. Imagine what would have happened with Windows if you were forced to use C or C++ to write applications that target it ? Forcing a single language on a powerful application execution environment like the browser is just limiting its potential and stifling innovation. There are many different types of code, and many different types of developers that write that code. Some code should be low-level, while other code should be high-level. Forcing everyone into the same language, or trying to make one language be all things to everyone, simply does not make sense.

So, there you have it. Tell me what you think in the comments.


Tags: JavaScript, Elevate Web BuilderPermanent Link 8 Comments


Image