litl's technical secrets revealed!
Update: Lucas has written up some additional technical details — and he mentions our update system, which was one of the first bits I worked on when I arrived. We heavily dog-food the updater, using buildbot to push out the latest bits to developers every night.
Update 2: Welcome, slashdot! The videos at http://litl.com/support/ give a good idea of what the UI is like.
Update 3: Non-technical press coverage: Wired, WSJ, Xconomy, CrunchGear
Update 4: More words: dignacio on litl's server side, J5, twitter
litl launches today, so I can finally
talk a bit about the cool technologies behind our software stack.
On the server side, litl is a cloud computer, built on Google App
Engine, Amazon
S3, and Django
— all of which are fantastic technologies.
All machine data is stored in the cloud, so you can have a
gorilla stomp on your litl, pick up another one, log on and instantly
recreate your environment. (Since we developers are always abusing
our prototype hardware, we've tested this a lot!)
On the client side, the litl software (naturally, code-named "big")
is built on gjs, which is the
smallest possible wrapper around JavaScript
necessary to make it a large-scale programming language. I've really
enjoyed programming in JavaScript, which might seem odd to people who
(a) have had frustrating experiences with global variables and crazy
incompatibilites trying to make JavaScript work on the web, and (b)
know that I'm a static types and
compiler-bondage
sort of guy. So I'll spend a little time here talking about gjs.
From a language standpoint gjs adds just one feature: a minimal
module/namespacing mechanism built on a single top-level definition: the name "imports
".
Modules are imported using (typically constant) definitions, such as:
const StringUtil = imports.stringUtil;
s = StringUtil.sprintf("%d", 3);
The dynamic stringUtil
property of the
imports
object is an object whose properties are the
top-level definitions in the file stringUtil.js
, found on
the import path. Subdirectories are additional dot-separated
components, as in Java package names; imports.util
is a
dynamic object representing modules found in a util
directory on the path. You may need to compare this to the
namespacing mechanism in the abandoned ES4
proposal to appreciate how small and elegant this is.
Further, this module system integrates with the GObject system via
GObject
introspection annotations for library code. This allows
easy integration with libraries written in C
or any other introspectable language. For example:
const Gtk = imports.gi.Gtk;
Gtk.init(0, null);
let w = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL });
w.connect('destroy', Gtk.main_quit );
let button = new Gtk.Button({ label: "Hello, world!" });
button.connect('clicked', function() { w.destroy(); } );
w.add(button);
w.show_all();
Gtk.main();
The gjs system is built on the SpiderMonkey
JavaScript engine, the one used in Firefox,
so JavaScript execution benefits from all the JIT and performance work
done upstream. Further, it means that we can code in JavaScript
1.8, Mozilla's dialect of JavaScript with lots of bells and
whistles (mostly borrowed from Python):
gjs> function range(n) { for (let i=0; i<n; i++) yield i; }
gjs> [i*2 for (i in range(5))]
0,2,4,6,8
(In a later post perhaps I'll describe how you can use the
yield
expression to build a continuation-based system for
writing asynchronous callbacks for UI code in a natural manner.)
Overall,
JavaScript as a system programming language feels a lot like Lisp must
have for the programming generation before mine: minimal
syntax, very powerful and orthogonal core abstractions, and (dare I
say it) not much type-checking or busy-work to get in your way.
(gjs
is not a homage to Sussman, but it should
be!) JavaScript is a programming language for those who know what they're
doing and aren't afraid of a little functional abstraction. (Now if
only there was a way to disable semicolon
insertion!)
OK, enough about gjs. The litl software stack is based on Canonical's distribution
of Ubuntu for mobile/embedded
devices, and the Canonical folks have been great partners.
It's been a joy to get changes integrated upstream, and Canonical has done a
lot of excellent work accommodating their distribution to litl's
unique needs. On the UI side, we use X11 and some GTK widgets, but
implement our own (very simple) window manager. Most of the
actual look and feel is done with Clutter
(hardware-accelerated 3d animated effects, whee!), and we have a
Flash-based API for external developers. We also have
hardware-accelerated h.264 video.
Regardless of the technical fun, though, I have to say that the
best thing about working at litl is its management: developing with
all the other rockstars here is made the more fun by the knowledge
that management will help ensure that our goals are realistic and that
we'll be able to hit our targets, with time left over to polish before
release. It's just much more fun to code when you know you'll be
proud of the end result.
Syndicated 2009-11-04 19:27:15 (Updated 2009-11-05 03:36:59) from C. Scott Ananian