google
yahoo
bing

Javascript meet Gnome, Gnome meet Javascript

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!

Tags: , , , , , , ,

28 Responses to “Javascript meet Gnome, Gnome meet Javascript”

  1. Stuart Langridge Says:

    Yes please. Where do I sign up? :)

  2. Daniel Borgmann Says:

    I very much agree about the themeing part, I still have lots of thoughts related to this which I planned to blog about.

    This all sounds very promising, but I am not convinced yet that it’s a good idea to abstract the VM. The fierce performance competition is benefitting everyone, and it seems unlikely to me that one of the major engines will considerably and permanently fall behind. This slight risk doesn’t seem worth the cost to me, and I can’t imagine that we want to “engine hop” whenever one of them gains the lead in performance.

    Some among us have been lamenting lately about the unnecessary abstraction in Phonon, I hope we won’t make that same mistake. :) I would feel much better if we would make a decision and then put all our energy behind it. But this feeling is not based on deep knowledge of the matter of course, so I just hope it will be considered carefully. If we abstract, I hope that it will _really_ pay off undeniably.

  3. Florin Says:

    Two cents:

    c1: Why do we want to *lower* the barrier of entry that much? How many *new* terminal emulators and cd players we need for GNOME? The main problems right now are performance (CPU and memory), not features. How will the new javascript engine help with those?

    c2: What’s wrong with python? The fact that it comes with big libraries is a plus, not a minus. Otherwise you’ll have to spend lots of time and energy reimplementing many basic things or exporting them from into your VM.

  4. kamstrup Says:

    @Stuart: You just did!

    @Daniel: Some abstraction of the VM might be necessary. For example – is libmozjs even API stable (not to mention ABI stable)? Another danger is that we simply end up with an abandoned VM. Last I heard Firefox 3 will use Tamarin not TraceMonkey. Will Tamarin implement libmozjs in a compatible way?

    On the speccific case of Phonon I happen to be in the camp that think it is (mostly) a good idea. Granted; abstracting GStreamer seems moronic in the isolated case, but the larger scope that KDE devs have elaborated elsewhere I think it makes more sense. But lets not go into that hole and focus on making Gnome rock instead :-)

  5. kamstrup Says:

    @Florin: Sorry, I have to be cheeky: Did you read the post?

    c(c1): Because pretty much each and every app and lib in Gnome is dying for new development power? Because Gnome is it is now is sub-par compared to pretty much all modern desktops? Because the barrier to entry right now is insanely high? TO be honest I think it took me 2-3 years to grok GObjects and Autotools enough to be comfortable with them.

    c(c2): I quote myself: “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.”. You can of course question the feasibility of the NC+EL architecture, but I let Firefox stand for it self. Hate it or love it :-)

  6. nona Says:

    FWIW, I hear there are plans to add classes as syntactic sugar to ECMAScript Harmony.

    ES4 had lots of stuff like packages, namespaces and classes. When things came to a head between the two camps, it became clear that packages and namespaces would need to be scrapped, and that classes could be supported by automatically desugaring it.

    Maybe this could help limit the boiler-plate code?

  7. h3 Says:

    Very nice. I will definitely play with this.

  8. kamstrup Says:

    @nona: Yeah, I hear that too. I even hear that Tamarin (the JSE scheduled for Firefox 4) is supporting ES4. However I have a nagging feeling that Harmony will end up like another ES4. I am definitely not betting my money on it, even though it might sound promising.

    Otoh – like I write, we might not even want a class based language. The very close mapping to GObjects gives a lot of power.

  9. Kevin Says:

    Haxe (http://haxe.org/) is a nicer language than JavaScript. It gives you modules, classes (that were dropped from ES4), strong typing, and type inference. All the features missing from JavaScript.

  10. kamstrup Says:

    @Kevin: Haxe does look nice, but I don’t think it is particularly well suited for the NC+EL use case I outline. If one goes for complete platforms then there are tons of alternatives (Java, Python, and Mono for instance).

    A place where I could see Haxe would be for writing the Native Core part of your app. Much like one would use Vala. It would require a GObject compiler output from Haxe though.

  11. Randall Says:

    Have you looked at Apple’s Open Scripting Architecture (OSA) as a model?

    OSA is the Mac OS X scripting engine that allows AppleScript and JavaScript (or Perl, Python, Ruby, and Tcl) to be used for scripting applications in Mac OS X. Applications written in the Cocoa framework get scripting support almost for free.

    This design has the side effect of allowing applications to be written in AppleScript or JavaScript that glue other applications into workflows.

    I guess you could say that I would prefer to see a model where you write a program that relies on the GTK/Gnome libs and suddenly it exposes a scripting interface to itself that any scripting language can be bound against, although I guess JavaScript would be a good reference language.

  12. Steve Lee Says:

    A quick should for accessibility – you’ll need to ensure stucture/state gets exposed via AT-SPI. For native widgets that will probably still happen via GAIL but what about custom widgets. And what of those implemented in JS? If you go the DOM scripting route then you’ll want WAI-ARIA as the standard but that is a poor relative to the richness of full AT-SPI

  13. Steve Lee Says:

    sorry that should have been a quick ’shout’

  14. Nicolas Says:

    There are JS frameworks that can be used in environments other than the browser.
    For example Mootools lets you make your own build for special environments such as Rhino.
    That framework also implements a nice OO-class system, so you could do inheritance the “usual” way:
    http://mootools.net/docs/Class/Class

  15. mike Says:

    Why fill the whole GUI with JS?

    Why not use Gtk.Builder files, where you can rearrange widget etc..

    That would make things easier, additionally put in some CSS :)

  16. kamstrup Says:

    @mike: Because using Gtk.Builder as the sole UI definition restricts you to shuffling widgets about as you say youself. With a powerful scripting environment i can rewrite the UI to any fancy crackpot idea I dream up.

    Gk.Builder + JS… In some form of DOM-scripting… Now that would be something

  17. kozure Says:

    Have you considered Lua? It’s used in Adobe Lightroom, for instance, and I repeat here the reasons for its adoption, according to Mark Hamburg: “Lua has an appealing balance of simplicity and power. It’s small, fast, and easy to embed. It also has a very straightforward license associated with it. It’s very much like Scheme language I like—but without a syntax likely to make people go running for the hills. So there were a lot of things.” (from http://since1968.com/article/190/mark-hamburg-interview-adobe-photoshop-lightroom-part-2-of-2)

  18. kamstrup Says:

    @kozure: There are no reasons as such that Lua could not be good choice. JS is simply a more wise choice these days IMHO. Considering its ubiquity these days as well as the _massive_ investment in its performance

  19. mohaine Says:

    Javascript is really nice once you get past all nastiness of the browser interaction. The hardest part is finding good a tutorial. Almost everything is for the beginner only. Finding good info on OO in javascirpt is even harder.

    BTW, an easier way to extend an object in JS is:

    function Base(){
    }
    function Sub(){
    }
    Sub.prototype = new Base();

    This method requires no argument constructors (or manually calling the init function in the subclass) , but I can live without them.

  20. Gustavo Carneiro Says:

    I don’t think anyone explained why “C With Embedded Language” is better than “Language With Embedded C”, i.e. why is your main() in C and not in some high level language? I would understand that if the “embedded language” parts were only plugins that can be disabled, but it does not sound like it is so.

    And I also don’t think Javascript is a good language; it does not have an elegant design, and so I am not sure it will attract that many developers. Yes, there are many javascript _web_ developers out there, but javascript is not nearly as easy to learn as Python. As for Python performance, I suspect that maybe IronPython is at least as much fast and light as javascript?

  21. Jean Says:

    Java, Ruby and Python can be already translated into JavaScript without problems (Java for example by GWT). So support for others languages will come with JavaScript support (for free).

    JavaScript is becoming de facto universal VM.

  22. kamstrup Says:

    @mohaine: The Gjs Style_Guide.txt[1] states that this pattern should be avoided. Quoting that document:

    “The problem with this pattern is that you might want to have side effects in the Base() constructor. Say Base() in its constructor creates a window on the screen, because Base() is a dialog class or something. If you use the pattern that some instances of Base() are just prototypes for subclasses, you’ll get extra windows on the screen.

    The other problem with this pattern is that it’s just confusing and weird.”

    [1]: http://svn.gnome.org/svn/gjs/trunk/doc/Style_Guide.txt

  23. kamstrup Says:

    @Gustavo: I think the reasons are sorta implicit from what I write… Please note though I don’t explicitely require C, but just something that compiles to native code. The restriction can be made more loose by setting the requirements for the “native language” part of the architecture, to be not “native”, but:

    * Runs with a memory-footprint comparable to native code
    * Runs with a speed comparable to native code
    * The platform it runs against is pushed into (and used) in the embedded language

    Another point is that “Language with Embedded C” pretty much translates to “Writing in a managed language with bindings”… no? Which I specifically say is still a very good way to write apps.

    Whether or not Javascript is beautiful or not is really in the eye of the beholder I think. And regarding the performance and foorprint of IronPython I must confess that I don’t know the answer. And if you are writing an app in IronPython why not write the enitre app in IP?

  24. Creating Themes « dborg’s Journal Says:

    [...] only way I could see CSS making a real difference is if we would enable absolute themes as kamstrup calls it, which I believe are very badly needed if we want to see some actual creative [...]

  25. fresch Says:

    I’ll jump on the Lua-wagon as well… let’s just forget Javascript really fast, even though it is prototype based, and there is lots of activity in developing ever faster engines. And instead use Lua… a language actually developed to be embedded! And only minimal syntax, too!

    I firmly say no to a consortium controlled language, expecially one where at least one monopolistic company has vested interest in. Even if I happen to like Javascript… that alone kills it for me. Can’t do anything about it being the scripting language of the web in it’s many dialects (see what monopolists did there?) but please lets not use it anywhere else ever…

    Also while I’m at it, lets take a look what good it did for HTML and CSS to be governed by a consortium: How long did they have to work on XHTML1.0? How long on CSS v2? Hmmm? How much have the various web consortiums and experts changed to shape todays web? That’s right, they spent too much time and changed not much! It was the Browser Godfathers (Netscape, Mozilla, Microsoft, and that annoying upstart Apple) that changed (or more accurately didn’t), the webdevelopers did change the web, by simply doing and not so much talking (that nobody heard.)

    And don’t get me started about “Introducing classes” into Javascript, or “Lambda function statements” (Mozilla)… That’s exactly what’ll happen if you let people that never really use the damn thing decide how it should evolve…

    Prototype based and class based can actually live alongside comfortably, I just don’t see why the prototyper has to avoid “class”, “instance”, “public”, “private” and all that design-by-contract-junk for variable names while they don’t even get proper “copy” and “clone” keywords!?

  26. Laszlo Pandy Says:

    I realize this discussion ended months ago, but i just had a thought trying out all these new fancy next gen browsers.

    Above Jean remarked that JavaScript is the new defacto VM, citing GWT as an example. There is already a thing like that for Python called Pyjamas (http://pyjs.org/).

    Given that Firefox 3.1, Chrome both have new superfast open source JavaScript engines, why can’t we have a thing which lets you write in Python, compile to JavaScript with Pyjamas (translating the GTK api calls using a thing like Vala’s .vapi files) and then run in the fastest VM available. It would be nice to see how much faster than Python we can make it go.

  27. kamstrup Says:

    @Laszlo: You are talking ancient history :-) See http://www.advogato.org/article/985.html.

  28. skrat Says:

    Well, I think Gnome as a whole should be language neutral. As it is these days, there Gnome and Gtk+ bindings for many popular languages. It’s just that Javascript should included. That’s done by Gjs and Seed.

    Now the thing is that DOM + CSS (or alikes) should be used as biulding blocks for next Gtk+ (3.0). Forget GtkBuilder, forget Glade, lets just rebuild these things from scratch. We already can construct GUIs from XML files, so that DOM is there. Why not allow styling using CSS like stylesheets. Let default theme be that of the running system, but allow developers to completely restyle widgets with sweetness as in CSS3.

Leave a Reply