February 23, 2013

As promised before, I will be saying some more things about the different approaches to cross platform development. As we know, the current state of the industry is happy in a way that we have a lot of competing operating systems and software development platforms. It is sad only because it is somewhat difficult for software developers to cope with a lot of different platforms, but this should not be a cause for permanent concern: Cross platform development is supposed to be the key to solving the issue. And when I say cross platform development, I am talking about having a single codebase that can be used to develop applications for different platforms.


As I mentioned in my previous post, there are different ways to create tools or solutions that make such a cross platform development approach possible. In fact, we have identified a total of six such approaches, based on the products currently available in the market. In this post I'll discuss perhaps the most popular of them, the one we call the "scripted" approach.

We have named it the "scripted" approach because the idea is to enable cross platform functionality through the use of a scripting language. There are many tools like this in the market, usually the main difference between them being the choice of the language, which is usually an existing open source language, and the source code of the interpreter / runtime is readily downloadable. In the scripted approach, the application developer writes their application using the chosen scripting language, which can be (for example) JavaScript, Lua or Ruby. The cross platform development tool then takes the scripts as-is, and copies them over to the installer package without modification. At the same time, the tool also adds a copy of the scripting language interpreter to the package, and rolls it all in a bundle and oftentimes calls it a "native" application. The way to make this work on several platforms is by providing a specific version of the interpreter for each supported platform.

I usually define the term "native" as something that does not require interpretation. In this sense, while these applications may look native, actually they are not. During execution, the bundled runtime / interpreter executes (interprets) the scripting language and executes it on the processor. And while it may in some instances work OK, it is still not native, but it is interpreted.

The beauty of this approach is its simplicity. It is somewhat straightforward to get a scripting interpreter and bundle it together with the scripts, although finding suitable versions of the interpreter for some platforms may prove to be tricky. Especially problematic would be running these applications on the web (with the potential exception of having chosen JavaScript as the cross platform language), as scripting language interpreters written in JavaScript are very much rare to nonexistent. The main difficulty in this approach, however, is not that, but probably the matter of piping the underlying native API into the scripting language, since the two are inherently not compatible. This is probably where a bulk of the work goes when making a tool like this, and this is also one of the main limitations of this approach: The scripts can only access those parts of the native API that the tool vendor has made available. If the tool does not pipe a specific function call to the realm of the scripts, then the developer is out of luck, and cannot use that particular feature. This is somewhat inherently so, as a Ruby script or a JavaScript program cannot really talk to C or Java APIs without having some kind of a pipe in between. And the pipes come from the tool, and if the tool does not give you one, then you don't have it, and you'll have to live without it.

Another issue associated with this approach includes the installer size, which may grow quite large due to the inclusion of the interpreter. The bigger the interpreter, the bigger the installer. In the worst case that I've heard of, a "Hello world" application installer on Android ended up being 8MB in size! But the interpreter does not only contribute to the size: It also needs to execute. And during execution, the interpretation obviously takes CPU cycles and takes away processing power from the application logic. And it takes memory as well, and in some cases it takes a lot of it. And it just so happens that in a mobile environment, all those things contribute to the negative effect that we always would want to try to avoid: The battery will end up draining more quickly, and it all contributes to it: Transferring more bytes to the device uses more battery; allocating and manipulating larger blocks of memory uses more battery; and running heavier CPU cycles also uses more battery.

It does not really matter which scripting language was chosen, or how well the interpreter may have been written. On a conceptual level, architecturally, this is inherently so. While one may argue that by writing the best possible interpreter ever written in the history of programming, this would not be so. But still: An interpreter is an interpreter. Not having an interpreter is still better, at least in terms of performance, memory use, installer size and power consumption.

I always mention this approach first because this is the most popular approach to cross platform development (perhaps due to the relatively straightforward nature of the approach). So much so that people unconsciously seem to sometimes equate the "scripted approach" and "cross platform development". I am guessing that is why I see those posts in forums where people say that they've "tried cross platform tools", but the applications were "too slow", "used too much memory", and generally "were not usable for anything but prototyping". I would tend to agree that this is true, but not of cross platform development. This would be true for the "scripted approach", as indeed these problems inherently grow straight out of the design and architecture of the solution.

Of course the scripted approach may just have its valid place in applications where performance is not of critical importance, and/or if the chosen language otherwise has some exceptional merit (eg. in the case where all developers working on a project happen to be Lua enthusiasts, etc.). But architecturally I would want to encourage all serious software engineers to try to look elsewhere. And one thing I would like to make perfectly clear: The "scripted approach" is NOT the same as "cross platform development". There are better ways to do this.


Share this article: