2010-06-24

Vala and Monads

Hello,
I've been reading around lately about functional monads written in imperative languages, then I've tried to bring them to Vala. I'm not going to explain what a monad is, there's a lot of papers out there.

If you want to test the code below you need Vala git master (more recent than 0.9.2).

First of all we need a basic framework and some monads you can immediately read here.
Notice some comments are in do notation and that related functions are really only utilities to let the example code below be more readable, they respect the functional semantics of monads without adding more imperative power.

The only difference with other implementations is that BindFunc not only passes the underlying value but also the return function. This is helpful to avoid keeping monads around in termporary variables.

Now let's port some Haskell typic examples to Vala:

safe_div a b = if b == 0 then Nothing else Just (div a b)

Monad safe_div (int a, int b) { if (b == 0) return nothing; return new Just (a/b); }

The nothing variable is initialized with Nothing.instance which is a singleton.
Now let's map a simple multiplication function:

bind_and_mul monad factor = do { x <- monad; return (x*factor); }

Monad bind_and_mul (Monad monad, double factor) {
return monad.bind ((v,unit) => unit (((int)v) * factor)) as Monad;
}

Pretty easy, we get the unpacked value and multiply it with the given value.

Things get a bit longer with list monads. We want that given an x the function returns [x,x+1]:

bind_and_list_plus monad val = do { x <- monad; return [x,x+1]; }

Monad bind_and_list_plus (Monad monad, int val) {
return monad.bind ((x,unit) => {
var l = new List (); l.add (x); l.add (((int)x)+val); return unit(l);
});
}
Ok, but what is the result of those weird definitions?

Haskell: do { x <- safe_div 5 2; return (x*2); }
Vala: bind_and_mul (safe_div(5,2), 2);
Result: Just (4)
What if we divide by zero?

do { x <- safe_div 5 0; return (x*2); }
bind_and_mul (safe_div(5,0), 2);
Result: Nothing
Transform -10 into some useless list:

do { x <- -10; return [x,x+1]; }
bind_and_list_plus (new Just (-10), 1);
Result: [-10,-9]

Now do the same transformation for a list:

Haskell: do { x <- [1,2,3]; return [x,x+2]; }
Vala: var l = new List(); l.add(1); l.add(2); l.add(3);
bind_and_list_plus (l, 2);
Result: [[1,3],[2,4],[3,5]]

Again, the complete code with test cases can be found here.

2010-06-20

Vala 0.9.2 has been released

Hello,
this new release follows the huge changes coming along with GLib and GTK+ latest releases:
  • Initial support for GDBus-based clients and servers.
  • Support implicit and explicit GVariant casts.
  • Add support for [Deprecated] attribute.
  • Add GenericArray as alternative binding to GPtrArray.
  • Add gdk-pixbuf-3.0, gdk-3.0, gdk-x11-3.0, and gtk+-3.0 bindings.
  • Updates to the GLib bindings.
  • Many bug fixes.
Stay tuned with furter updates.

2010-06-08

Vala 0.9.1 is out

Hello,
yesterday the announce of the 0.9.1 release of Vala. You can find release notes here.
This is more like a transitional development release torward a new 0.8.x branch stable release.

Changes

  • Support constants in enums.
  • Deprecate +=/-= syntax to connect/disconnect signal handlers.
  • Add experimental support for Dova profile.
  • Update Genie parser (Jamie McCracken).

  • Add clutter-gst-1.0 bindings (Ali Sabil).
  • Add gdu and gdu-gtk bindings.
  • Add libesmtp bindings (Adrien Bustany).
  • Add mx-1.0 bindings (Evan Nemerson).
  • Add orc-0.4 bindings (Fabian Deutsch).
  • Add rest-extras-0.6 bindings (Adrien Bustany).
  • Updates to the GLib, GStreamer, Linux, SQLite, and other bindings.
  • Many bug fixes.

2010-05-27

Post Vala 0.8.1 update

Hello,
thanks to Jiří Zárevúcký for giving me the permission to write to this blog, this is my first post.

It's been at least a month since 0.8.1 has been released, and Vala is growing day by day. I'd like to share some news that will be available in the next release:
  • New regex literals
  • New libesmtp, mx-1.0, rest-extras and orc-0.4 bindings.
  • Improvements for sqlite3, alsa, libgdata and gstreamer-0.10 bindings
  • rest bindings renamed to rest-0.6
  • Several bug fixes for the compiler (especially for arrays, async and delegates), bindings and lots of other vapigen and vala-gen-introspect improvements.
  • Gtkdoc support for Valadoc.
  • And more...
Stay tuned!

2010-03-31

Vala 0.8.0 Released!

For the official release notes and download link, see http://live.gnome.org/Vala/Release ;)

2010-03-17

Shotwell 0.5.0

A few days back, a new version of Shotwell got released.
For those of you who don't know, Shotwell is a great open-source photo manager written in Vala.
The new version has some cool features, including but not limited to uploading photos to Picasa Web Albums. ;)

Read the full release announcement here:
http://www.yorba.org/blog/jim/2010/03/shotwell-050-released.html

2010-02-18

To compare, or not to compare? That is a question for you

Since I don't want to sleep yet, but don't have anything to do either, I thought I might as well start with the new, totally random single-topic approach to the Vala Journal.

A while ago (in the first attempt on this journal thingy to be precise), I noted a proposed feature of "complex conditionals". Since there hasn't been much response, it may be better to dedicate a post to it.

It all boils down to a single new added possibility - chain more relational operations in a single expression. Example: if you need to compare a variable to two values, you currently need to do this:

if (1 < a && a < 5) {}

Well, that doesn't look too bad, you're right. What about this?

if (0 < a && a < b && b < c && c < d && d < 255) {
    // do something
} else {
    error ("Invalid data");
}

I don't know about you, but I think this is just evil.
Now, with the complex conditionals thingy, this would be possible:

if (1 < a < 5) {}

if (0 < a < b < c < d < 255) {
    // do something
} else {
    error ("Invalid data");
}

Muuuuuch nicer. :)

However, Jürg suggested that there are more possible approaches to this problem. For example a range syntax:

if (a in [1..5]) {}

I don't find this possibility particularly bad, but it wouldn't allow any fancier chaining, like in my second example.

So, questions for you: What do you thing about it? Which one do you prefer? Do you have any other suggestions?

EDIT:
Ahh, forgot to link the bug report.
https://bugzilla.gnome.org/show_bug.cgi?id=606480