June 3, 2009
This article was contributed by Nathan Willis
Some programming languages forge new ground, others are refinements of
previously existing ideas, and still others tackle a specific problem in a
new and better way. This article will look at two up-and-coming languages
that are not yet as widely adopted as C, C++, or Java, but offer developers
some intriguing benefits: Vala and
Clojure. Vala is designed specifically
to build native applications for the GNOME desktop environment, and Clojure
brings the power of Lisp
and functional programming to the Java Virtual Machine (JVM).
Vala
GNOME itself is written in C, but many of the higher-level libraries
that make up the GNOME platform (such as GTK+ and Pango) make heavy use of
the GLib and GObject
frameworks, which implement a complete object system including types,
messaging, classes, and all of the other components that make up a typical
object oriented application program interface (API). GObject makes it
possible to write object oriented GNOME applications in C, and also makes
it simple to provide wrappers to GNOME for object oriented languages like
C++ or Python.
While GObject makes object-oriented programming in C possible, it
remains somewhat cumbersome. The GObject wrappers for other languages can
be even worse, introducing yet another layer of dependencies which can
include virtual machines of their own. Vala was created in an attempt to
address these problems and make GNOME programming easier. Vala provides a
C#-like syntax that
integrates GObject features, but the valac compiler compiles to C
output
rather than assembly. The resulting C compiles normally with gcc, plus it
can be distributed as source packages fully usable on platforms that do not
have Vala installed. That allows the developer to use Vala's modern
language features — dynamic type system, assisted memory management,
and so on — while still making source releases compatible with C
applications and libraries.
In addition to GLib and GObject, the Vala project produces bindings to the major GNOME libraries: GTK+, GDK, Cairo, SDL, GStreamer, D-Bus, GIO, and many more. In addition,
several external projects provide their own bindings for Vala (such as Clutter), and there are third-party efforts
to create bindings for other libraries, such as OpenGL. Plugins for Vala
support are available for the Eclipse, Anjuta, and MonoDevelop IDEs, as well as for the
editors Emacs, Vim, and GEdit. Val(a)IDE, still in development, is a
dedicated Vala IDE written in Vala itself.
The latest release of
Vala is 0.7.3, which went public on May 26, 2009. It is a bugfix release
for the 0.7 series, which is intended to be the last development series
before 1.0. The biggest change in the 0.7 series, according to developer
Jürg Billeter, is to C header file generation. In previous
releases, Vala would generate a .h header file for every
.vala source file,
which caused problems:
This caused various issues when the
dependencies between the .vala source files get complex or more
specifically, circular, and it did not allow us to have internal methods
that can be used in multiple .vala files but remain outside the public
API. Therefore we decided to move to a single public C header file with 0.7
and stop using separate header files for internal methods.
That
change demanded making changes to the build system for existing Vala
applications, but Billeter said it should be the last such headache for a
while.
Vala 1.0 is scheduled
to be released in September of 2009, coinciding with the release of GNOME
2.28. According to Billeter, the project is on track to make the 1.0
deadline, which will mark the start of a long stable release cycle during
which application developers can count on language stability. The bindings
to GNOME libraries are maintained separately, Billeter said, and are added
to and enhanced on an as-needed basis, so they are not subject to the same
schedule.
The project offers a tutorial and sample
code for those new to Vala; some familiarity with GObject is expected.
Benchmarks
between Vala and C show no significant execution speed losses (in some cases,
Vala even beats plain C).
The project maintains a list
of applications developed using Vala, in whole or in part, including GNOME
panel applets and full-fledged applications. The webcam utility Cheese is currently
maintaining a Vala branch in addition to its main trunk, just to road test
the viability of the language. Billeter noted that although people
generally think of using Vala only when starting a new project, it is
possible to incorporate it into an existing C code base, too. "Among
our users are both, people writing C that now want to move to something
higher level and also people that just start programming in the GNOME
environment," he said.
Clojure
While Vala is a language designed around a particular object system,
targeting a particular desktop environment, Clojure could not be more
different. It is a dialect of the functional-flavored programming language
Lisp,
implemented on the Java platform. That makes it cross-platform; Clojure
applications are compiled to Java bytecode, so they can run on any platform
with a well-supported JVM.
Creator Rich Hickey has explained that building on top of
the JVM grants Clojure automatic platform stability from a broad user and
developer community, but that itself was not the goal of creating the
language. Hickey's primary interest was concurrency — he wanted the
ability to write multi-threaded applications, but increasingly found the
mutable, stateful paradigm of object oriented programming to be part of the
problem. "Discovering Common Lisp after over a decade of C++, I said
to myself — 'What have I been doing with my life?', and resolved to
at some point code in Lisp. Several years of trying to make that practical,
with 'bridges' like jFli, Foil etc, made it clear that bridges weren't
going to be sufficient for the commercial work I was doing."
Hickey became less enamored of object oriented programming and started
adopting a functional-programming style in his work, which he found to make
the code more robust and easier for him and for his coworkers to
understand. Eventually, maintaining that style in other languages like C#
became more trouble than it was worth:
The idea of a functional Lisp
integrated with a commercially accepted host platform just seemed like
chocolate and peanut butter. It can be hard to remember the exact time in
which you decide to do the crazy thing that is designing a new language -
you just find yourself doing it because you have to. Coming up with
persistent data structures that were fast enough was the tipping point for
my considering it viable.
Clojure does provide persistent data structures, although it does
considerably more. For those unfamiliar, functional programming (the style
from which Lisp and Clojure originate) places a greater emphasis on
functions as first-class objects, meaning that functions can be placed into
data structures, passed as arguments to other functions, evaluated in
comparisons, even returned as the return value of another function.
Moreover, functions do not have "side effects" — the ability to
modify program state or data. This paradigm focuses on computation in the
mathematical sense, rather than procedural algorithms, and is a completely
different approach to programming.
As a language, Clojure is a Lisp-1, part of the same
family of Lisp variants as Scheme,
notable for sharing a single namespace between functions and variables.
Clojure differs from Scheme and other Lisp dialects in several respects documented at the Clojure web site.
For application developers, the most significant distinction is that
Clojure defaults to
making all data structures immutable. To maintain program state,
developers must use one of four special mutable structures that are
explicitly designed to be shared between threads: refs, vars, atoms, and
agents. Clojure uses software
transactional memory (STM) to coordinate changing these mutable
structures while keeping them in a consistent state, much like a
transactional database. This model makes it considerably simpler to write
thread-safe code than it is in object oriented languages. No locks are
required, therefore there are no deadlocks or race conditions.
Like other Lisp implementations, Clojure is interpreted through a console-like
read-eval-print-loop (REPL). The user launches the REPL from a .jar file
and is presented with the REPL command prompt, from which he or she can
load Clojure programs or directly write and execute functions and macros.
The code is compiled on-the-fly to Java bytecode, which is then in turn
executed by the JVM. The REPL environment is much like an interactive IDE
and debugger all rolled into one, but for distribution purposes, Clojure
code can be compiled ahead of
time into ordinary Java applications. Because it is hosted by the JVM,
Clojure can automatically make use of its features, including the type
system, thread implementation, and garbage collector, rather than having to
re-implement each of them. Clojure code can also call Java libraries, opening up
a wealth of classes and interfaces to Clojure programmers.
Clojure 1.0 was released on May
4, 2009. There are several good resources online for learning about the
language and for getting started, although a general introduction to Lisp
is probably warranted for those with no experience in functional
programming. Though there are not large-scale projects using Clojure, an
active community is growing
around it, including several local users' groups. The Clojure site offers
documentation of the language
syntax and examples (including example code), there is a very active Google
Groups discussion
forum, and Mark Volkmann's Clojure page at Object
Computing tracks articles, slides, and wikibooks about Clojure.
Two-way interoperability
Vala and Clojure seem to have little if anything in common; one is
object oriented and the other functional, one aimed at a specific desktop
system and the other intentionally cross-platform. They are kindred
spirits in one sense, however — they seek to build a more modern,
robust language implementation on top of an existing, established platform.
Vala's goal is to let C programmers more easily take advantage of the power
of GObject and GNOME, and Clojure's is to let developers easily write
concurrent applications on top of the stability of the JVM.
What is equally important is that both projects maintain bi-directional
compatibility with their underlying languages and platforms. A Vala
program can use any C library, and a C program can use any library written
in Vala. Likewise, Clojure code can be compiled to Java, and Clojure
applications can use any Java class or interface. Such interoperability
will likely increase adoption of both of these languages, and it is a welcome
sight in any project.
(
Log in to post comments)