Closures and asynchronous methods in Vala

It’s time for the release of Vala 0.7.6. Tarballs are available from the GNOME FTP servers. This release includes a couple of new features worth explaining in a bit more detail.

Closures

While Vala has lambda expressions for a long time, they haven’t supported accessing local variables from the outer method. With the release of Vala 0.7.6 this has changed, and you can access and set any local variable from lambda expressions. One place where I’d expect this to be convenient is in signal handlers:

void main (string[] args) {
    Gtk.init (ref args);
 
    var window = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
    window.set_default_size (300, 50);
    window.destroy.connect (Gtk.main_quit);
 
    var button = new Gtk.Button.with_label ("Click me!");
    button.clicked.connect (() => {
        window.title = "Closures in Vala";
    });
 
    window.add (button);
    window.show_all ();
 
    Gtk.main ();
}

You can even write recursive lambda expressions:

delegate int Func (int i);
 
void main () {
	Func fib = null;
	fib = (i) => (i <= 1) ? i : (fib (i - 2) + fib (i - 1));
 
	for (int i = 0; i < 10; i++) {
		message ("%d", fib (i));
	}
}

Asynchronous methods

The idea of integrating async methods into the language is to make it easier to write code that calls or implements async methods. Async methods are frequently used in I/O API such as GIO and in D-Bus clients and servers. Traditionally, writing async code has beeen quite painful as you often end up writing callback chains and completely lose track over the control flow in the process.

Experimental support for async methods has been implemented in Vala almost a year ago. However, the implementation was rather a proof of concept than a finished solution. While I still expect a few bugs in that area with 0.7.6, it’s a lot more robust and complete than it used to be a short time ago.

So how does it look like? It’s not unlike Alex’s AsyncRunner in JavaScript except that it’s even more concise as it’s fully integrated into the language. The following code defines an async method list_dir that asynchronously enumerates all files in the home directory:

async void list_dir () {
    var dir = File.new_for_path (Environment.get_home_dir ());
    try {
        var e = yield dir.enumerate_children_async (FILE_ATTRIBUTE_STANDARD_NAME, 0, Priority.DEFAULT, null);
        while (true) {
            var files = yield e.next_files_async (10, Priority.DEFAULT, null);
            if (files == null) {
                break;
            }
            foreach (var info in files) {
                print ("%s\n", info.get_name ());
            }
        }
    } catch (GLib.Error err) {
        warning ("Error: %s\n", err.message);
    }
}
 
void main () {
    list_dir.begin ();
 
    var loop = new GLib.MainLoop (null, false);
    loop.run();
}

As you can see, it’s very easy to call the async methods enumerate_children_async and next_files_async in try-catch blocks and loops. There is no need for manually creating structs for user_data or similar inconveniences.

Async methods in Vala can also be used to implement D-Bus servers that can process multiple requests at the same time. Using it couldn’t be easier, just write an async method such as the above example, add it to a class annotated with [DBus (name = “org.example.Test”)], and register an instance of that class with the D-Bus connection. Vala also supports async methods on client-side D-Bus interfaces.

Vala 0.5.3

Long time no post, I’ll try to get better. Yesterday we’ve released Vala 0.5.3. Tarballs are available from the GNOME FTP servers.

  • D-Bus server support has been rewritten to directly use libdbus. Avoiding dbus-glib marshalling helps Vala to support complex D-Bus types more easily.
  • All Vala structs will now be registered with GBoxed.
  • Many critical warnings and crashes on invalid code have been fixed and replaced by better understandable error messages.
  • Private class fields and class destructors (base_finalize) are now supported.
  • vala-gen-project has been dropped from the package, it is now part of Vala Toys for gEdit, which is progressing very well.
  • Many bug fixes all over the place.

In the following weeks and months we will focus on bug fixing, finishing some partially implemented features, and switching to GObject Introspection trunk for our bindings. We’re aiming to release a stable Vala 1.0 in March 2009.

Vala 0.3.3

It’s release time again. Yesterday we’ve released Vala 0.3.3. Tarballs are available from the GNOME FTP servers.

Thanks a lot to all the people helping out and have fun with the new version! For the following two releases we will focus on GObject introspection hacking to make it easy to write great bindings for many languages.

Vala Roadmap and 0.2.0

Last week I wrote an initial roadmap that we want to follow for the upcoming Vala releases on our way towards guaranteed language stability. Today we’ve released Vala 0.2.0 as planned. Tarballs are available from the GNOME FTP servers. It’s mainly a bug fix release, however, it also got some new features like nested namespaces, static constructors, and GType-registered enums. We also have three new contributed bindings for GNOME Keyring, SDL, and libftdi, and the usual updates for existing bindings.

Vala 0.1.7

We’ve just released Vala 0.1.7. Tarballs are available from the GNOME FTP servers.

  • Enhanced property syntax
    public int foo { get; private set; default (3); }
  • New errordomain syntax
    public errordomain MyError { NOT_FOUND, TIMED_OUT }
  • Detect missing return and break statements and unreachable code
  • Improved pointer support (pointer member access, pointer element access, and pointer arithmetic)
  • New bindings: WebKit, JSON-GLib, goocanvas, hildon-fm-2, taglib, libusb, and bzip2
  • A lot of bug fixes

Vala Project Generator

Vala 0.1.5 has been released. Tarballs are available from the GNOME FTP servers. I’ve added a small tool to create new Vala projects:

Vala Project Generator

It generates the necessary autotools magic for a Vala console or GTK+ application including i18n support and it passes distcheck. Suggestions for improvements are more than welcome.

We’ve also replaced the bindings generator gidlgen by vala-gen-introspect which includes a real C parser instead of Perl scripts using regular expressions. The 20 included bindings have all been ported. Some smaller features and many bug fixes can also be found in the new release.

There are two articles about Vala and an interview in the German Linux-Magazin, all by Christian Meyer.

Vala 0.1.4

Vala 0.1.4 has been released. Tarballs are available from the GNOME FTP servers. We’ve added some small enhancements besides bug fixes and the previously mentioned #line support for debugging.

  • Object initializers
    var btn = new Button () { label = “Button” };
  • Creation methods in structs
  • Experimental support for new fundamental classed types
    class MiniObject : TypeInstance { … }
  • [Notify] attribute for properties

Vala and Nemiver

I’ve added preliminary support for #line directives to Vala. This means that the debug information of your application compiled with valac -g will now contain the filename and line number of your Vala sources, instead of the generated C sources. Vala applications can be more or less graphically debugged using Nemiver now 🙂 Mathias was kind enough to create a little demo video as the screencast tools didn’t work well on my system. There are still some issues left but it’s a start.

Vala 0.1.3

Vala 0.1.3 is out. Tarballs are available from the GNOME FTP servers. There are a lot of new bindings from many contributors: D-Bus, GConf, libgnome, libgnomeui, Glade, libnotify, GnomeVFS, GtkSourceView, Panel Applet, GNOME Desktop Library, libsoup, libwnck, GtkMozEmbed, Poppler, Enchant, Hildon, SQLite, and curses. Many bugs have been fixed all over the place.

A noteworthy change is that the type system has been made more consistent by converting the reference-type structs in the bindings to classes. The [ReferenceType] attribute is gone, you can now declare all reference types as classes in bindings, even if they don’t derive from GObject. A side-effect of this change is that you now always have to specify the base class in your class declarations, e.g. use

using GLib;
public class Bar : Object { … }

to declare a class Bar which derives from GObject. The advantage is that you can be sure now that all structs have value-type semantics and all classes have reference-type semantics, no mixup anymore.