Alt. title: The Very Long Blog Post About Gnome and Javascript that Will Surely Put You to Sleep
I shall not hide the fact that I am pretty excited about the “Javascript enabled Gnome”-idea. It has the potential for greatness if executed with care and consideration and the potential for boring irrelevance if not given proper thought. In this post I will try and give you my vision of greatness.
If you have nothing else to do, sit tight for a long read.
The Old New Application Model
This has more ore less been explained before, especially if you read the comments on Alex’ post titled “Embeddable Languages, an Implementation”, but I will include my own short version of it for completeness.
The development model behind the whole Javascript-movement is “Core in native code and the rest in an embeddable language”. The “Core in Native Code” would be a core written in C, C++, Vala, or some other language compiling to native code. An “embeddable language” has the following traits in my mind:
- Comes with very slim or no platform library at all
- One can programmatically inject objects or modules into it from the embedding environment
- It is completely sandboxable
- The VM or interpreter is very light
These points makes it clear that Python, Java, and Mono are not “embeddable” in my book. The non-existing platform of the embeddable language is in fact a boon in our case because we already have a platform. Namely the collection of GObject based libraries in Gnome providing GObject-Introspection capabilities. This way different platform’s, I/O, networking, configuration and such don’t get mixed up, plus you automagically respect stuff like the Gnome proxy settings and such.
Also I would like to highlight that this does not suddenly make Python, Java, or Mono bad ways to write your applications. They are, and will continue to be, very good platforms, but they do not lend them selves that well to the Native Core + Embeddable Language application architecture.
The VM and the Language
We are fortunate enough to have at least three alternatives for choices of Javascript engine (henceforth JSE), SquirrelFish (WebKit), Trace/SpiderMonkey (Mozilla), and V8 (Chrome). Real VM-junkies could probably add a few more engines to that list. We already have GObject-Introspection-powered bindings for the WebKit and Firefox engines, respectively Seed and Gjs.
My (arguably not very thorough) review of the two Javascript bridges tells me that both are very strongly tied to their JSE-of-choice. While this definitely makes sense at the lower level I don’t think Gnome should tie itself to one single JSE. With all the massive work being poured into developing über fast JSEs these days I just think that it would be a very, very, bad call (or at the very least gambling with our performance).
Not having a blessed Javascript engine brings in host of problems the web developers among us probably know a lot more about than me. Reading Wikipedia’s article on ECMAScript should give you an idea of where I am going… Basically a portability problem that might be even trickier than porting good olde C code between different compilers and libc implementations. However I am confident that we can solve much of this by writing good coding-guidelines and assuring that the underlying Gnome technologies does not push developers in the wrong directions.
Writing a generic JSE bridge for Gnome would require that one carefully analyse our needs and intentions and write the interfaces for that. Any engine which API could not provide the needed functionality would not be eligible as backend. We can not accept the lowest common denominator just to make the developers of the RodentApe JSE happy.
The minimal requirements from a JSE would be the four points listed above for embeddable languages and add to that:
- Can run several parallel “sessions” also called “contexts” in the same engine instance
- Maybe: Security model that allows certain contexts to read and write to each other
Inheritance and Boiler Plate Code
It is important to realize that Javascript does not have the concepts of classes and inheritance. This means that you can not do sub-classing like you would in Java for example:
public class Base {
private int i;
public Foo (int i) {
this.i = i;
}
public void frobate () {
System.out.println("You have been frobated!");
}
}
public class Sub extends Base {
public Sub () {
super(27);
}
public void newMethod () {
System.out.println ("This was the new method");
}
} |
Javascript is a prototype based language this means that it is not based on classes and inheritance, but on “prototypes”. The way Gjs suggests one gets around this is like:
const Lang = imports.lang;
function Base(foo) {
this._init(foo);
}
Base.prototype = {
_init : function(foo) {
this._foo = foo;
},
frobate : function() {
}
};
function Sub(foo, bar) {
this._init(foo, bar);
}
// copy each method in Base.prototype to the new Sub.prototype
Lang.copyProperties(Base.prototype, Sub.prototype);
// replace the _init property in Sub.prototype
Sub.prototype._init = function(foo, bar) {
// here is an example of how to "chain up"
Base.prototype._init.call(this, foo);
this._bar = bar;
}
// add a newMethod property in Sub.prototype
Sub.prototype.newMethod = function() {
} |
If this makes you think of the standard GObject boiler plate in C code you are not completely wrong. When I first realized this I was totally flipping “No way we are going with another boiler-plate heavy language”. Likely you are too if this is your first confrontation with this fact.
However, after letting my emotions settle for a few days I became a little more open to the idea. While a more pure sub-classing scheme could probably be implemented with some ninja-hackery I am not sure that would be a good idea. The point is that we don’t want to end up with something that is basically a Javascript dialect. Outsiders should have a fair chance of applying their regular Javascript knowdledge and possibly even port some existing code to Gnome. The point of keeping the Javascript in Gnome close to that of “the Wild” will be further signified below.
In fact it can be seen as a plus that the prototype based approach is similar to the GObject implementation. Namely that the mapping can be quite close. If you switch often between native GObjects and, fx., Java, you will probably (like me) miss some of the really powerful aspects of GObjects that are not found in standard Java classes. This can be more naturally mapped to Javascript.
Integration. Deep Integration
If Javascript ends up as “just another language binding” it will quickly become irrelevant. There are simply languages better suited for that. It needs to run inside the guts of our apps and everywhere across the desktop.
I guess that Firefox+XUL is really my role model here. Consider Firefox extensions (or is it called pluxtensions or strap-ins these days?) like GreaseMonkey and Firebug. No I don’t mean “consider” – you have to experience them. Taking Firebug; it really transforms Firefox from a cool web browser into an über cool, full featured, website debugger. You have to fiddle about with it to fully realize what I am talking about.
What I dream about in the pitch black nights of Denmark is this level of integration across the Gnome desktop, from the desktop as a whole to the nitty gritty details of the applications. Firefox has proven that it is not impossible and recent developments in GObject-Introspection, DBus, GtkBuilder, and the desktop wide scene graph of Gnome Shell, all hints to me a brighter future (don’t hold your breath though!).
Absolute Theming
Something that routinely bring me down is the state of Gnome application theming (I am not talking about Gtk+ themes, but application theming). From my early Linux days I remember that my shiniest gem was the KJofol skins for XMMS. They litterally transformed the entire UI of XMMS to something completely different. It looked bloody awesome and turned a lot of heads of Windows users at the time.
I am not saying that each and every app should look totally unique (we have fought a lot for desktop unity!), but just that we should still provide that expressive power to entrepreneuring talents. We are very far from that right now. But it can change…
The Native Core + Embeddable Language design fits the bill perfectly in fact. If the UI and layout code is (entirely or mostly) written in Javascript and the core/model is imported into the scripting environment the game of “theming” will change completely. Either one can utilize a DOM-like access to a scene graph, which could be the role of a plugin, or one could completely rewrite the UI much easier than one can today – some progressive distributions might choose to do that.
A side bonus of this application architecture is that it will more or less force you to separate model and view in your application. Something Gnome sadly has not been very good at.
New Developers?
One argument that has been repeated in contexts such as this longish blog post is that Javascript also brings a horde of new developers to the table. I don’t think this will automatically become true unless we take the utmost care.
Firstly when you are thinking about a “Javascript expert” what do you think of first? I bet you think about a savvy young web-hacker who can integrate HTML, Javascript/DOM-scripting, and CSS, in mind blowing web-apps that’ll work on all browsers down to IE5. I know I do. If we want to pull these guys in we have to make the barrier to entry very small. Javascript alone wont cut it. Something like DOM-scripting and CSS should be waiting for them.
Next we also want to make it very tempting to jump on board. The ultimate power of adding a new sub-menu to Nautilus is simply not cool enough. This is why my sections about Deep Integration and Ultimate Theming are doubly important.
Thanks!
Wow, you just made it through my longest blog post ever!