Hello Vala: An Introduction to the Vala Language - Instructors: Lethalman, juergbi

Logs for this session will be available at http://irclogs.ubuntu.com/2011/09/07/%23ubuntu-classroom.html following the conclusion of the session. 
alright :) 
hi all, I'm Luca Bruno and I contribute to the Vala project 
juergbi is the project leader 
vala is a new programming language with C#-like syntax that compiles to C and targets the GObject type system 
I'm going to introduce the basics and the features of the vala language 
the homepage can be found at https://live.gnome.org/Vala 
you can get the vala compiler with "apt-get install valac", this is likely going to install at least vala 0.12 on an up-to-date system 
so what's good with vala... :) 
vala has syntax support for most of GLib/GObject features like classes/interfaces, properties, RTTI, virtual methods, signals, GValue and GVariant boxing/unboxing, error handling and optionally GIO features like GAsync and GDBus 
it also provides generics, closures, delegates, contract programming, duck typing and some other cool stuff without any additional run-time! 
these are some applications written in vala 
so, let's start by taking a look at the hello world: http://paste.debian.net/127646/ 
you can compile it with "valac hello.vala" then run it with "./hello" 
args is the well known array of strings passed to the command line 
string[] denotes an array of strings, while "print" refers to "GLib.print" which is static method mapped to g_print() 
in vala you can have namespaces, and GLib is the default namespace 
for reference, the online documentation for GLib can be found here: http://valadoc.org/glib-2.0/GLib.html 
the main() static method is the entry point for applications, it will be executed first 
at the very basics you might want to see what happens behind the scenes... if you want to see the generated C code, compile with "valac -C hello.vala" then read "hello.c" 
vala has most of the basic glib types like int, bool, int16, uint16, float, double, string, structs, enums, flags, classes, interfaces and so on 
so let's take a look at the next example: http://paste.debian.net/127644/ 
we're defining the "Foo" class that extends the "Object" class 
then the "bar" property of type int with automatic getter and setter (you can also define custom getter and setter) 
we have a constructor which takes an int value and sets the bar property, "this" refers to the instance of the class 
in main() we create a new Foo instance and assign it to the local variable foo 
the "var" keyword is meant to exploit type inference, so the type of foo is Foo... useful when you're lazy at writing long types ;) 
you can find other examples of type inference in vala here: https://live.gnome.org/Vala/Tutorial#Type_Inference 
for completeness let me say that the print() method supports printf-like format (man sprintf), so that you can format the arguments to the output very easily 
the first important thing to notice is that we don't manually manage the foo variable lifetime in the example, instead vala does manage it 
vala has automatic memory management using reference counting when possible, so you don't have to manually call ref() or unref() functions for gobjects 
in this case, the foo variable is automatically unref()'d once it goes out of the scope 
for more information about the memory model see both http://developer.gnome.org/gobject/stable/gobject-memory.html#gobject-memory-refcount and https://live.gnome.org/Vala/ReferenceHandling 
what's special in this example is that Foo is a registered GObject class in C and bar is a regular GObject property 
so, if you tell valac to autogenerate the header (valac -H sample.h sample.vala), C applications can use the class directly 
in general, vala performs very well in the interoperability area 
vala can talk to C using vala bindings (.vapi files) without additional run-time 
that is, vala calls C functions directly without the need of any FFI 
in fact .vapi files are just descriptions of the API of C libraries 
e.g. in order to use a foreign package called gtk+-2.0.vapi that is installed in your system, just use valac --pkg gtk+-2.0 yourprogram.vala so that vala compiles your program against gtk+-2.0 and you can use the gtk symbols 
a .vapi file has the same syntax of a .vala file, thus easy to write manually, see json-1.0.vapi (short enough for a pastebin) for example: http://paste.debian.net/127656/ 
don't worry, bindings can also be autogenerated from GIR files ;) (http://live.gnome.org/GObjectIntrospection) 
to generate a somelib.vapi from a gir it's as simple as doing vapigen --library somelib SomeLib-1.0.gir 
that's a little different than python or javascript or... as it's compile-time stuff 
anyway, vala itself ships with many bindings, you can see the docs at http://valadoc.org/ 
ok some more about interoperability then we talk about some cool features :) 
vala is able to autogenerate well-annotated GIR files to be used from other languages like python, javascript, etc. 
that means higher level languages can talk to vala just immediately (just two steps without writing any GI annotation like in C) 
let's see for example: https://live.gnome.org/Vala/SharedLibSample#Calling_vala_functions_using_introspection 
what we do is first creating a test_shared.so library and tell valac to generate testShared-0.1.gir for us 
once you got a gir we're done, it's only a matter of generating a typelib using the GI compiler 
shazzner77 asked: weird question, but I have a microcontroller that can be programmed in C. Can I use Vala for this? 
that's an hard question as it highly depends on the microcontroller 
most of microcontroller have different C dialects 
but you can use the posix profile to generate non-glib code somehow, but it's mostly an experimental feature... it's usable to some sort though 
so, let's talk about error handling 
vala features error handling on top of GError, with the well known try/catch/finally syntax 
in other words, you can catch errors thrown by C methods... eek! that sounds weird ;) 
this is a simple example: http://paste.debian.net/128329/ 
in the example we try to read a file, if the file doesn't exist (FileError.NOENT) we keep throwing the error, for any other error we abort the program with GLib.error() 
errors in glib are propagated using GError, so vala autogenerates the necessary code to handle that gracefully 
you can define your own error types using "errordomain" like this: http://paste.debian.net/128714/ 
so, this is already a lot of nice features, but that's not all about it! 
some cool stuff about vala is the syntax support for async operations, closures and dbus client/server 
it is possible to define GIO-style async methods and calling other async methods very easily 
an async method returns immediately giving control back to the caller, and when the job is completed a callback is fired 
take a look at the first example here: http://live.gnome.org/Vala/AsyncSamples 
the "async" keyword in front of list_dir() marks it as being a GIO-style coroutine 
yield dir.enumerate_children_async() will pause the method, then it will be resumed once there's a result... that's amazingly simple 
(in the meantime, thanks to nemequ for doing a great work in -chat :P) 
also notice in the main() method (which is not an async method) that we used a closure to be notified when list_dir() completes its job 
list_dir.begin() will initiate the async operation, then when the job is complete we free the resources with list_dir.end() 
closures are an important feature of vala compared to raw C 
a closure (or lambda expression, or ...) is a method created on-the-fly that shares the scope of the parent method (main() in this case) 
this is very very useful for callbacks for which you need to pass user data 
in fact, in the example the "loop" variable is used within the closure, but it's defined outside the closure 
the general syntax for defining lambda expressions is (param1, param2, ...) => { ... body here ... } 
the types of param1, param2, ... automatically match the parameters of the target type 
in this case the target type is AsyncReadyCallback which is a delegate type (i.e. a type that accepts methods) 
here's the definition of AsyncReadyCallback: http://www.valadoc.org/gio-2.0/GLib.AsyncReadyCallback.html 
it takes two parameters, an Object and an AsyncResult... that's why we used (obj,res) => { ... } in the example 
kermit66676 asked: I noticed there is no #include directive when using a library in Vala - doesn't that make things messy in bigger applications with a lot of packages - you have to watch out not to repeat class names from some other libraries? Or use namespaces all the time... 
if I understood the question correctly... when you compile a project you feed to valac all the .vala files at once 
valac file1.vala file2.vala ... 
for what concerns collision with existing names, yes namespaces are used for that 
but applications or libraries written in vala usually have their own namespace, that's the best practice 
mjaga asked: is valac part of the gcc family? 
no it isn't, it's a self-hosted compiler on its own 
but valac uses the C compiler as it produces C code 
it's very slim and compiles fast, most of the time spent on compiling is usually due to the C compiler 
vala lets the underlying C compiler optimize things... 
so... the async stuff is very powerful when combined with dbus :) 
we can call dbus methods (well, a property in this case) in a such simple way: http://paste.debian.net/128341/ 
methods of UPower would have suspended your workstation, so :P 
the interface in the example is a way for vala to generate proxy calls to the dbus interface 
the "can_hibernate" property is mapped to the dbus property org.freedesktop.UPower.CanHibernate 
what we do here is starting the async upower_query() operation, which will asynchronously connect to the system bus and request a proxy for UPower 
afterwards we request the value of the "can_hibernate" property... bool.to_string() is an helper method defined by vala, you know what it does :) 
vala automatically does dbus serialization of values when doing dbus stuff (the bool property in this case), even for the most complex types 
this is about client code, but you can write dbus servers by just writing normal class methods 
take for example this server code: http://paste.debian.net/128754/ 
and the following client snippet to query the server: http://paste.debian.net/128756/ 
compile the server with "valac dbusserver.vala --pkg gio-2.0" and the client with "valac dbusclient.vala --pkg gio-2.0" 
so you can start the server with ./dbusserver and then invoke the client multiple times with ./dbusclient 
if everything goes well, on the client you should see a counter increasing on each call 
notice: as said in -chat not _all_ of the complex types, there might be some bug/limitation but you can use GLib.Variant manually as well 
in this case we assumed the client didn't know the server codebase, otherwise we could share the same interface definition and let the server class implement it 
server side we do some other stuff for acquiring the name, registering a callback when it's available 
so, this vala integration is very important as our desktops are leading toward async and dbus more and more 
there are several projects that massively use such advanced features of vala successfully 
after this low level stuff we can take a look at some GUI with GTK+: http://live.gnome.org/Vala/GTKSample 
reference docs for gtk3 can be found here: http://valadoc.org/gtk+-3.0/index.htm 
the "using Gtk;" statement on the top means that the Gtk namespace is merged in the file 
therefore we can use "new Window ()" instead of "new Gtk.Window ()", and so on 
also notice window.title = "First GTK+ Program"; 
window.title is a gobject property, we saw them in the first hello world example 
in this case vala will generate the C code for calling gtk_window_set_title (GTK_WINDOW (window), "First GTK+ Program") properly 
in the example we can also see the button.clicked.connect() call: it's used to connect to the "GtkButton::clicked" signal! 
the first argument is the callback that will be fired when the signal is emitted 
you can also specify a method (static method or instance method) as the signal callback, not only a closure 
I've written an equivalent code here without the use of a closure: http://paste.debian.net/128743/ 
yeah, it's more typing without closures ;) 
as you can see writing gui with vala is very simple, and you can take advantage of async operations for doing I/O without blocking the GUI! 
so now we're connecting to a signal, but in vala defining signals is as easy as putting a "signal" keyword in front of a method declaration 
an example of signal definition can be found here: https://live.gnome.org/Vala/Tutorial#Signals 
in that code we defined a full gobject signal named "sig_1" with an int parameter... like properties, signals can be used from C as well as higher level languages 
and emitting the signal is as simple as calling a normal method: t1.sig_1 (5) 
ok now let's talk a little about generics 
generics in vala are similar to C# or Java generics 
they are used to restrict the type of data that is contained in a class, both at compile-time and at run-time (no type erasure) 
for example let's use GList, which is a glib structure for doubly linked lists: http://paste.debian.net/128737/ 
the type List<string> will define a list whose elements are of type string 
then we append to strings to the list, and print them 
the foreach statement is another neat feature of vala, allowing to iterate through the elements of a collection 
the syntax is simple: foreach (element_type variable_name in container_expression) { ... } 
in this case we used "var" as element type to exploit the type inference 
roughly speaking, in this case vala will infer the element type from the generic type of the container which is "string" 
There are 10 minutes remaining in the current session. 
mhr3 asked: there's this nice syntax to read/write gobject properties, are there any plans to have similar support for widget style properties? 
well, not that I know of 
anyway while the properties defined in a class are known at compile-time, not necessarily style properties (or child properties...) are known at compile-time 
so it may lack some type checking... if you have a clear idea you can feature request it :) 
you can also define your own complex types using generics like the first example here: https://live.gnome.org/Vala/Tutorial#Generics 
glib offers several data structures already, but there's also libgee that provides a collection library that is written in vala and widely used 
libgee is more vala-friendly and has data structures such as TreeMap, PriorityQueue, HashSet, HashMultiMap, etc. 
the reference docs for libgee can be found here: http://valadoc.org/libgee-0.7/index.htm 
ok... we're almost done :) 
vala comes with libvala, which is a library for parsing and analyzing the vala code and generating code... 
There are 5 minutes remaining in the current session. 
despite the libvala API is not stable, there are many users of it like IDEs, documentation tools, code generators, etc. 
for generating documentation for you projects you can use valadoc: https://live.gnome.org/Valadoc 
there're lots of other neat features like lock statement, inheritance, virtual/abstract methods and properties, etc. that we didn't mention... 
or experimental features like chained expressions: foo < bar < baz < mama 
or regex literals like in perl: /.../ will create a GLib.Regex 
if you want to know more the tutorial at https://live.gnome.org/Vala/Tutorial is a good start... and the community is wide and very active ;) 
ok that's all, thanks everyone :) 
ok suggested from -chat to mention our community is on the mailing list vala-list@gnome.org and on #vala on irc.gimp.org 

MeetingLogs/appdevweek1109/HelloValaIntroduction (last edited 2011-09-08 09:16:58 by dpm)