Vala Programming Language Vala is an object-oriented programming language with a self-hosting compiler that generates C code and uses the GObject type system. Zola 2024-05-09T00:00:00+00:00 https://vala.dev/atom.xml ValaBot: an AI coding assistant fine-tuned for Vala 2024-05-09T00:00:00+00:00 2024-05-09T00:00:00+00:00 Unknown https://vala.dev/blog/valabot/ <h2 id="enhancing-ai-coding-assistants-for-vala-developers">Enhancing AI Coding Assistants for Vala Developers<a class="zola-anchor" href="#enhancing-ai-coding-assistants-for-vala-developers" aria-label="Anchor link for: enhancing-ai-coding-assistants-for-vala-developers">#</a> </h2> <p>As a programmer, I've been impressed by AI coding assistants like GitHub Copilot and Codeium, which have significantly boosted my productivity. These tools excel at reducing disruptive interruptions, saving time on typing, and often completing lines of code accurately. However, I've encountered limitations with Copilot while working with the Vala programming language. Its suggestions often get muddled with similar languages like Java and C#, and it lacks training on the more common Vala libraries.</p> <p>Like many other developers, I'm also dissatisfied with the dominance of Github Copilot and that open source code has been monetized without attribution or consideration for the original authors (some of whom now pay for the service).</p> <p>This challenge inspired me to enhance the Copilot concept by creating an AI coding assistant that is finely tuned to provide a viable and superior alternative that caters for the specific needs of Vala developers. I began with an open-source Large Language Model that had been trained on source code - the powerful Deepseek Coder 6.7b model. This model has been trained from scratch by Deepseek AI on 2 trillion tokens sourced from GitHub. Deepseek Coder significantly outperforms other open-source coding models, such as Codellama.</p> <p>I chose the Deepseekcoder-6.7b-base model as the foundation for fine-tuning because of its great benchmark performance and also because it was trained on Java and C# – languages syntactically close to Vala. This allowed me to build upon its existing capabilities and adapt it to the specific needs of Vala.</p> <h2 id="fine-tuning-for-vala">Fine-Tuning for Vala<a class="zola-anchor" href="#fine-tuning-for-vala" aria-label="Anchor link for: fine-tuning-for-vala">#</a> </h2> <p>I fine-tuned the model on Vala programming language datasets. This involved downloading as many Vala projects as I could find from GitHub, extracting the Vala source files, and splitting them into ~40 line segments. I then used Llama3 to create logical and predictable "holes" in each segment, which were then used to create the FIM (fill-in-the-middle) dataset. This data preparation process took 96 hours of GPU time using my quad-RX6800 machine over a weekend. The resulting dataset was cleaned to remove non-code elements, such as license headers, and personal identifiable information.</p> <h2 id="the-training">The Training<a class="zola-anchor" href="#the-training" aria-label="Anchor link for: the-training">#</a> </h2> <p>The fine-tuning process took 10 hours on an RTX 3090. The result was a LoRA, which was merged back into the base model, converted to GGUF, and quantized to q8_0, which is the format required by TabbyML.</p> <h2 id="the-result">The Result<a class="zola-anchor" href="#the-result" aria-label="Anchor link for: the-result">#</a> </h2> <p>The outcome was a model that is more helpful and productive for Vala-related projects. By fine-tuning Deepseek Coder, I was able to create a more accurate and effective AI coding assistant that understands the nuances of the Vala programming language. The model is hosted on Huggingface (<a href="https://huggingface.co/scowen/deepseek-coder-6.7b-vala/tree/main">https://huggingface.co/scowen/deepseek-coder-6.7b-vala/tree/main</a>). It can be used in VSCode, VIM, and other popular IDEs with TabbyML. The complete instructions, training scripts, and dataset are available on GitHub (<a href="https://github.com/supercamel/ValaBot">https://github.com/supercamel/ValaBot</a>).</p> <h2 id="licensing-and-fair-use">Licensing and Fair Use<a class="zola-anchor" href="#licensing-and-fair-use" aria-label="Anchor link for: licensing-and-fair-use">#</a> </h2> <p>As a project rooted in the principles of Free and Open-Source Software (FOSS), I believe in promoting freedom, community, and sharing knowledge. To facilitate collaboration and innovation, I've made the following resources publicly available:</p> <ul> <li>The fine-tuned model weights are hosted on Hugging Face for anyone to access and utilize in a TabbyML or other deployment.</li> <li>The training scripts and dataset preparation process are open-sourced on GitHub, providing a transparent and reproducible framework for others to build upon.</li> <li>A comprehensive list of repositories used during the fine-tuning process is available on GitHub, ensuring that contributors and users can easily identify and explore the sources that made this project possible.</li> </ul> <p>I hope that this openness will pave the way for further advancements and refinements, ultimately benefiting the Vala developer community as a whole.</p> <h2 id="conclusion">Conclusion<a class="zola-anchor" href="#conclusion" aria-label="Anchor link for: conclusion">#</a> </h2> <p>In this blog post, I've shared my experience with fine-tuning the Deepseek Coder for the Vala programming language, demonstrating how targeted adjustments can significantly enhance AI coding assistants. This project is just the beginning. I aim to continue developing models specifically optimized for Vala to support the Vala developer community. With the release of new base models, such as CodeQwen 7B, there are exciting possibilities for further advancements. Through this work, I hope to highlight the potential of AI fine-tuning in creating more effective coding assistants and inspire others to explore the possibilities of AI-assisted coding.</p> <p>Get started with ValaBot here: <a href="https://github.com/supercamel/ValaBot">https://github.com/supercamel/ValaBot</a></p> Vala: the smoothest C off-ramp 2024-04-22T00:00:00+00:00 2024-04-22T00:00:00+00:00 Unknown https://vala.dev/blog/c-off-ramp/ <p>Hi! I’m Reuben, a long-time free software maintainer and author. One of my specialities is taking on mature projects from their original authors and maintaining them long-term.</p> <p>In this post, I want to talk about how I’ve rewritten entire projects in Vala, to make them easier, more productive and more fun to maintain.</p> <p>Vala works well with C—that’s one of its primary features and design choices. But these abilities can be used for another purpose: to provide a “smooth off-ramp” for C, converting old code step-by-step to more-maintainable Vala, without an “all or nothing” rewrite, and with the ability to reimplement C libraries in Vala, so that existing C code can still call them.</p> <p>Over the few years, I have rewritten two small–to–medium-sized C code bases in Vala: the minimal Emacs clone <a href="https://www.gnu.org/software/zile">GNU Zile</a> and the spell-checking meta-library <a href="https://abiword.github.io/enchant/">Enchant</a>, which has been used by GNOME for years, most recently by <a href="https://gitlab.gnome.org/GNOME/libspelling">libspelling</a>, which provides spell-checking in the <a href="https://apps.gnome.org/TextEditor/">GNOME Text Editor</a>. In the rest of this post, I’ll focus on the challenges I faced doing these rewrites, how Vala helped me, and discuss whether such a drastic move (of rewriting entire code bases) was in fact a good idea.</p> <h2 id="vala-is-good-at-talking-to-c">Vala is good at talking to C<a class="zola-anchor" href="#vala-is-good-at-talking-to-c" aria-label="Anchor link for: vala-is-good-at-talking-to-c">#</a> </h2> <p>Vala is designed to work well with C, and a nice consequence of this is that often one doesn’t have to think about C at all, because so many useful libraries are already conveniently bound to Vala “out of the box”. It’s impressive the degree to which some of Vala’s basic abilities, such as its “built-in” container types are “just” clever binding of GLib functions plus some syntactic sugar.</p> <p>But Vala’s binding abilities are very powerful: it’s not just GLib and GObject APIs that it can bind successfully; it can bind almost any C API. Later I will also show some examples that test its limits.</p> <p>Further, Vala can <em>implement</em> C APIs just as well as it can <em>consume</em> them.</p> <h2 id="allowing-c-to-talk-back">Allowing C to talk back<a class="zola-anchor" href="#allowing-c-to-talk-back" aria-label="Anchor link for: allowing-c-to-talk-back">#</a> </h2> <p>Why would you want to implement C APIs in Vala? I have three answers for you. Firstly, maintaining a typical C code-base is a horrible experience. I just wanted to not have more memory management errors, especially to do with strings (which both Zile and Enchant are big on). It’s so easy to corrupt memory, to get lifetimes wrong, or simply get the wrong answer with C’s primitive string manipulation routines.</p> <p>Secondly, implementing an existing C API in Vala gives an easier-to-maintain codebase that can be used by existing consumers, which don’t need to be C programs: they can be written in Python, Rust, JavaScript or, of course, Vala!</p> <p>Thirdly, and perhaps less obviously, you can use this ability to rewrite a C program in Vala incrementally, one module (say) at a time. The result is a pure Vala application (no C APIs are being implemented), but at each step one has a complete working application, partly written in C and partly in Vala; and where C needs to call Vala, the Vala code must implement the right C APIs.</p> <h2 id="before-we-start-a-sanity-check">Before we start, a sanity check<a class="zola-anchor" href="#before-we-start-a-sanity-check" aria-label="Anchor link for: before-we-start-a-sanity-check">#</a> </h2> <p>I’m talking about rewriting mature code-bases. Zile dates from the late 1990s, and I rewrote it into Vala in 2020. Enchant was written starting around 2003, and I rewrote it in Vala this week (in 2024). So:</p> <ul> <li>Isn’t that an awful lot of work?</li> <li>Won’t it introduce lots of new bugs?</li> </ul> <p>In other words, is it worth it? Or am I just being quixotic?</p> <h2 id="it-s-not-that-hard">It’s not that hard<a class="zola-anchor" href="#it-s-not-that-hard" aria-label="Anchor link for: it-s-not-that-hard">#</a> </h2> <p>As I said above, I rewrote Enchant in Vala this week. Actually, that’s not quite true: I rewrote the core, about 2,000 lines of C. Enchant is, as I said above, a meta-library: that is, it doesn’t do spell-checking itself, but delegates to a number of libraries that do. Each one needs an adaptor plugin, which Enchant calls a “provider”, and these providers are written in C, C++ and even Objective C. I haven’t touched those (yet!).</p> <p>But still, 2,000 lines of code in a week is not bad.</p> <p>GNU Zile was about 8,000 lines of C, and that took me about a month.</p> <h2 id="avoiding-a-plague-of-new-bugs">Avoiding a plague of new bugs<a class="zola-anchor" href="#avoiding-a-plague-of-new-bugs" aria-label="Anchor link for: avoiding-a-plague-of-new-bugs">#</a> </h2> <h3 id="vala-is-well-matched-to-c">Vala is well matched to C<a class="zola-anchor" href="#vala-is-well-matched-to-c" aria-label="Anchor link for: vala-is-well-matched-to-c">#</a> </h3> <p>Any time you touch code you can introduce bugs, of course: the slightest adjustment can be risky. How much more so rewriting in another language?</p> <p>The good news here is that because Vala is so close to C, it is relatively easy to translate code without introducing new bugs. The syntax is sufficiently similar that code can be easily translated with some search and replace (e.g. <code>NULL</code> in C becomes <code>null</code> in Vala) plus light editing (e.g. adding missing comparisons in conditions to make them boolean, so that <code>if (ptr)</code> in C becomes <code>if (ptr != null)</code> in Vala). C APIs can be used directly via Vala bindings, and C data structures can be replicated precisely. Vala’s static typing also helps.</p> <p>Here’s an example of a struct in C from Zile:</p> <pre data-lang="c" class="language-c z-code"><code class="language-c" data-lang="c"><span class="z-source z-c"><span class="z-meta z-struct z-c"><span class="z-storage z-type z-c">struct</span> <span class="z-meta z-struct z-c"><span class="z-entity z-name z-struct z-c">Region</span></span></span><span class="z-meta z-struct z-c"> </span></span><span class="z-source z-c"><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"><span class="z-punctuation z-section z-block z-begin z-c">{</span></span></span><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"> </span></span></span><span class="z-source z-c"><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"><span class="z-meta z-preprocessor z-macro z-c"><span class="z-keyword z-control z-import z-define z-c">#define</span></span><span class="z-meta z-preprocessor z-macro z-c"> <span class="z-entity z-name z-function z-preprocessor z-c">FIELD</span></span><span class="z-meta z-preprocessor z-macro z-parameters z-c"><span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span><span class="z-variable z-parameter z-c">ty</span><span class="z-punctuation z-separator z-c">,</span> <span class="z-variable z-parameter z-c">name</span><span class="z-punctuation z-section z-group z-end z-c">)</span></span></span><span class="z-meta z-preprocessor z-macro z-c"> ty name<span class="z-punctuation z-terminator z-c">;</span></span> </span></span></span><span class="z-source z-c"><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"><span class="z-meta z-preprocessor z-include z-c"><span class="z-keyword z-control z-import z-include z-c">#include</span> <span class="z-string z-quoted z-double z-include z-c"><span class="z-punctuation z-definition z-string z-begin z-c">&quot;</span>region.h<span class="z-punctuation z-definition z-string z-end z-c">&quot;</span></span> </span></span></span></span><span class="z-source z-c"><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"><span class="z-meta z-preprocessor z-c"><span class="z-keyword z-control z-import z-c">#undef</span> FIELD </span></span></span></span><span class="z-source z-c"><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"></span></span><span class="z-meta z-struct z-c"><span class="z-meta z-block z-c"><span class="z-punctuation z-section z-block z-end z-c">}</span></span></span><span class="z-punctuation z-terminator z-c">;</span> </span><span class="z-source z-c"> </span><span class="z-source z-c"><span class="z-meta z-preprocessor z-macro z-c"><span class="z-keyword z-control z-import z-define z-c">#define</span></span><span class="z-meta z-preprocessor z-macro z-c"> <span class="z-entity z-name z-function z-preprocessor z-c">FIELD</span></span><span class="z-meta z-preprocessor z-macro z-parameters z-c"><span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span><span class="z-variable z-parameter z-c">ty</span><span class="z-punctuation z-separator z-c">,</span> <span class="z-variable z-parameter z-c">field</span><span class="z-punctuation z-section z-group z-end z-c">)</span></span></span><span class="z-meta z-preprocessor z-macro z-c"> <span class="z-punctuation z-separator z-continuation z-c">\</span> </span></span><span class="z-source z-c"><span class="z-meta z-preprocessor z-macro z-c"> <span class="z-meta z-function-call z-c"><span class="z-variable z-function z-c">GETTER</span> <span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span></span></span><span class="z-meta z-function-call z-c"><span class="z-meta z-group z-c">Region<span class="z-punctuation z-separator z-c">,</span> region<span class="z-punctuation z-separator z-c">,</span> ty<span class="z-punctuation z-separator z-c">,</span> field</span></span><span class="z-meta z-function-call z-c"><span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-end z-c">)</span></span></span> <span class="z-punctuation z-separator z-continuation z-c">\</span> </span></span><span class="z-source z-c"><span class="z-meta z-preprocessor z-macro z-c"><span class="z-meta z-assumed-macro z-c"> <span class="z-variable z-function z-assumed-macro z-c">SETTER</span> <span class="z-punctuation z-section z-group z-begin z-c">(</span>Region<span class="z-punctuation z-separator z-c">,</span> region<span class="z-punctuation z-separator z-c">,</span> ty<span class="z-punctuation z-separator z-c">,</span> field<span class="z-punctuation z-section z-group z-end z-c">)</span></span></span> </span><span class="z-source z-c"> </span><span class="z-source z-c"><span class="z-meta z-preprocessor z-include z-c"><span class="z-keyword z-control z-import z-include z-c">#include</span> <span class="z-string z-quoted z-double z-include z-c"><span class="z-punctuation z-definition z-string z-begin z-c">&quot;</span>region.h<span class="z-punctuation z-definition z-string z-end z-c">&quot;</span></span> </span></span><span class="z-source z-c"><span class="z-meta z-preprocessor z-c"><span class="z-keyword z-control z-import z-c">#undef</span> FIELD </span></span></code></pre> <p>The file <code>region.h</code> contained:</p> <pre data-lang="c" class="language-c z-code"><code class="language-c" data-lang="c"><span class="z-source z-c"><span class="z-meta z-assumed-macro z-c"><span class="z-variable z-function z-assumed-macro z-c">FIELD</span><span class="z-punctuation z-section z-group z-begin z-c">(</span><span class="z-support z-type z-sys-types z-c">size_t</span><span class="z-punctuation z-separator z-c">,</span> start<span class="z-punctuation z-section z-group z-end z-c">)</span></span> </span><span class="z-source z-c"><span class="z-meta z-assumed-macro z-c"><span class="z-variable z-function z-assumed-macro z-c">FIELD</span><span class="z-punctuation z-section z-group z-begin z-c">(</span><span class="z-support z-type z-sys-types z-c">size_t</span><span class="z-punctuation z-separator z-c">,</span> end<span class="z-punctuation z-section z-group z-end z-c">)</span></span> </span></code></pre> <p>Here’s the translation into Vala:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-meta z-class z-vala"><span class="z-storage z-type z-class z-vala">class</span> <span class="z-entity z-name z-class z-vala">Region </span></span><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-type z-vala">size_t</span> <span class="z-support z-type z-vala">start</span> { <span class="z-support z-type z-vala">get</span>; <span class="z-support z-type z-vala">set</span>; } </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-type z-vala">size_t</span> <span class="z-support z-type z-vala">end</span> { <span class="z-support z-type z-vala">get</span>; <span class="z-support z-type z-vala">set</span>; } </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-comment z-line z-vala"><span class="z-punctuation z-definition z-comment z-vala">//</span> …methods go here </span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala">} </span></span></span></code></pre> <p>Compare and contrast: around 2009, I translated Zile into <a href="https://www.lua.org">Lua</a>. I completed the translation, but I did not release it, as I found that Lua’s lack of static type-checking made it too easy to introduce new bugs. While I was translating it I was forever finding off-by-one errors caused by Lua counting arrays and string positions from 1, while C is 0-based (as is Vala, of course). Don’t get me wrong: Lua is a great language; indeed, I have successfully written other, smaller programs from C into Lua, though I wouldn’t now recommend that; its strengths lie elsewhere.</p> <p>With Vala, I recommend making the initial translation as “light” as possible: don’t use lots of Vala’s features to rewrite code. Translate <code>char *</code> pointers to string offsets (that is, an integer string index). Make sure the translated code works first, then start simplifying. Even the “light” translation will contain simplifications, anyway: no more <code>malloc</code> or <code>free</code>, for example.</p> <h3 id="you-already-have-a-test-suite-of-course">You already have a test suite, of course<a class="zola-anchor" href="#you-already-have-a-test-suite-of-course" aria-label="Anchor link for: you-already-have-a-test-suite-of-course">#</a> </h3> <p>The other way you avoid a plague of new bugs is with a good test suite. Sorry! There’s no way around that. If you want to alter, let alone completely rewrite code, you need to have tests.</p> <p>Fortunately, I had already added a fairly extensive test suite to Zile years ago, when I was trying to make sure that it really behaved exactly like Emacs. The situation with Enchant was even better: it has an exhaustive (and sometimes exhausting) test suite that checks every aspect of its API, added a few years after Enchant was written, by a commission from <a href="https://www.sil.org">SIL International</a>. (A big shout-out to those who commission work on libre software, especially this sort of important under-the-hood work. These tests have saved me from introducing bugs time and time again.)</p> <p>Again, you have to be disciplined: no turning off the tests, or changing them as you go. Complete the translation without changing them, as far as possible.</p> <h3 id="your-existing-build-tool-is-probably-supported">Your existing build tool is probably supported<a class="zola-anchor" href="#your-existing-build-tool-is-probably-supported" aria-label="Anchor link for: your-existing-build-tool-is-probably-supported">#</a> </h3> <p>Many Vala projects these days are using the <a href="https://mesonbuild.com">Meson</a> build system, which is very popular in the GNOME space. But Vala is also supported well by older tools, such as <a href="https://cmake.org">CMake</a> and <a href="https://en.wikipedia.org/wiki/GNU_Autotools">GNU Autotools</a>. Both of the projects I translated were using GNU Autotools, and I stuck with it, for two main reasons:</p> <ol> <li>I use the excellent <a href="https://www.gnu.org/software/gnulib/">gnulib</a> portability library to ensure that my POSIX-compliant code runs on most systems without problems. Unfortunately, gnulib is tied to GNU Autotools. But then, few build systems work on as many platforms as the Autotools in any case.</li> <li><a href="https://www.gnu.org/software/automake/">Automake</a> not only has Vala support, but allows you to ship the generated C sources, so that users can build your code without a Vala compiler. This means that your translated project has exactly the same build dependencies as it had before, which can help with users and packagers who haven’t heard of Vala and don’t want to learn. With Zile, previously a pure-POSIX project, I added GLib as a build-time dependency, but of course that’s so widely used that it’s unlikely to be a problem. Enchant already used GLib.</li> </ol> <h2 id="the-vala-experience">The Vala experience<a class="zola-anchor" href="#the-vala-experience" aria-label="Anchor link for: the-vala-experience">#</a> </h2> <p>I will now describe the process of translating the two code-bases. Although they were a bit different (Zile an application, Enchant a library), and I made the translations a few years apart, I was pleasantly surprised to find the second time that the process was much the same as the first.</p> <h3 id="add-vala-to-the-build-system">Add Vala to the build system<a class="zola-anchor" href="#add-vala-to-the-build-system" aria-label="Anchor link for: add-vala-to-the-build-system">#</a> </h3> <p>With Autotools, this is a matter of adding a couple of <code>configure.ac</code> lines to detect the Vala compiler and check for GNU Make (which is required to build from Vala sources), and then adding a test Vala source file to a <code>Makefile.am</code>.</p> <h3 id="translating-the-code">Translating the code<a class="zola-anchor" href="#translating-the-code" aria-label="Anchor link for: translating-the-code">#</a> </h3> <p>I typically translate one file at a time. The code will of course usually call functions from other parts of the program: I add a private VAPI file with suitable bindings. You can usefully pre-populate the VAPI file with the commented-out contents of relevant C header files, then just uncomment the APIs you need in Vala, and edit them suitably. The excellent <a href="https://wiki.gnome.org/Projects/Vala/ManualBindings">Manual bindings</a> guide from the Wiki is my constant companion.</p> <p>To translate a file, I copy <code>foo.c</code> to <code>foo_vala.vala</code>. (The <code>_vala</code> bit ensures that the Vala-generated C won’t overwrite the original file, which I will keep for reference.) I translate the code, possibly in multiple steps, commenting out the bits I have translated in <code>foo.c</code>.</p> <p>Compile, test, fix, rinse, repeat.</p> <p>I find that I get a nice rhythm with my translation, of doing the obvious basic syntactic stuff, as mentioned above, then finding the equivalent Vala APIs where necessary, then tackling any hard bits, such as binding third-party APIs that Vala does not yet know about.</p> <p>For Zile I leaned heavily on the POSIX VAPI, and added a new GNU VAPI for some GNU-specific APIs, which I have also used and extended while translating Enchant. Enchant was easier on the whole, because it was already GLib-based, so I just had to search <a href="https://valadoc.org">valadoc.org</a> for the Vala versions of the GLib APIs.</p> <p>For Zile, I found <a href="https://wiki.gnome.org/Projects/Libgee">libgee</a> invaluable, with its superior collections that are both richer than GLib’s and allows extra use cases, such as collections of unboxed simple types (e.g. <code>ArrayList&lt;int&gt;</code>). For Enchant, it so happened I didn’t need this extra functionality; Enchant’s use of collections is mostly limited to singly-linked lists of objects and hash tables with string keys.</p> <h3 id="stumbling-blocks">Stumbling blocks…<a class="zola-anchor" href="#stumbling-blocks" aria-label="Anchor link for: stumbling-blocks">#</a> </h3> <h4 id="documentation-and-api-coverage">Documentation and API coverage<a class="zola-anchor" href="#documentation-and-api-coverage" aria-label="Anchor link for: documentation-and-api-coverage">#</a> </h4> <p>Vala is a small ecosystem, even after all these years. Hence, I found bugs, mostly in the documentation. I took the time to submit <a href="https://github.com/vala-lang/valadoc-org/pull/414">fixes</a>, and this past week reaped the rewards! Some of these fixes went as far as GLib itself; many were to the Vala wiki. As I noted above, I also made additions to the VAPIs, in particular adding a complete binding for the POSIX, GNU and BSD regex APIs (Zile only needed the GNU API, but since the GNU regex module implements all three, I thought I might as well!), as well as <code>getopt_long()</code>. I added <code>freopen</code> to the POSIX VAPI (as <code>FILE.reopen()</code>), upgraded the curses VAPI to improve its Terminfo coverage and add key-codes for function keys, and added return codes to GLib’s <code>FileStream.putc</code> and <code>puts</code>.</p> <p>I was also able to offer my old-school expertise to the Vala project itself: I converted the test suite to use Automake’s relatively recent ability to run tests in parallel.</p> <h4 id="falling-between-two-stools">Falling between two stools<a class="zola-anchor" href="#falling-between-two-stools" aria-label="Anchor link for: falling-between-two-stools">#</a> </h4> <p>Vala itself mostly insulates you from the memory-management woes that bedevil C, but mid-translation there is still C code, so you have to be careful if you want to keep a working program. It’s always tempting to just plough on with the translation and hope that crashes will disappear, but I try not to give in, as that can bury bugs deeper and make them harder to find later. So, expect to spend some time studying <code>valac</code>-generated C, and revising your knowledge of <code>owned</code> and other esoteric Vala features.</p> <p>For me, this is particularly relevant to Enchant, as a C library whose API and ABI I want to maintain. I am happy to report that I have been mostly successful, and at the time of writing I am tracking down some problems with object lifetime management, but otherwise the Vala implementation seems to perfectly replicate the C.</p> <p>Another area of awkwardness is strings: as I hinted above, C often uses pointers to refer to string positions, whereas in Vala it’s usual to use integer offsets. This code is fairly easy to convert once you get the hang of it. Since C <em>can</em> use offsets instead of pointers, you can always rewrite the code in two stages, first changing the C to use offsets, and then translating it into Vala.</p> <p>Here’s an example of the translation from pointers in C to offsets in Vala. The C version refers to positions in strings with pointers:</p> <pre data-lang="c" class="language-c z-code"><code class="language-c" data-lang="c"><span class="z-source z-c"><span class="z-storage z-type z-c">char</span> <span class="z-keyword z-operator z-c">*</span> <span class="z-meta z-function z-c"><span class="z-entity z-name z-function z-c">enchant_iso_639_from_tag</span></span><span class="z-meta z-function z-c"> </span><span class="z-meta z-function z-parameters z-c"><span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span></span></span><span class="z-meta z-function z-parameters z-c"><span class="z-meta z-group z-c"><span class="z-storage z-modifier z-c">const</span> <span class="z-storage z-type z-c">char</span> <span class="z-keyword z-operator z-c">*</span> <span class="z-storage z-modifier z-c">const</span> <span class="z-variable z-parameter z-c">dict_tag</span><span class="z-punctuation z-section z-group z-end z-c">)</span></span></span><span class="z-meta z-function z-c"> </span><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"><span class="z-punctuation z-section z-block z-begin z-c">{</span></span></span><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-storage z-type z-c">char</span> <span class="z-keyword z-operator z-c">*</span> new_tag <span class="z-keyword z-operator z-assignment z-c">=</span> <span class="z-meta z-function-call z-c"><span class="z-variable z-function z-c">strdup</span> <span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span></span></span><span class="z-meta z-function-call z-c"><span class="z-meta z-group z-c">dict_tag</span></span><span class="z-meta z-function-call z-c"><span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-end z-c">)</span></span></span><span class="z-punctuation z-terminator z-c">;</span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-keyword z-control z-c">if</span> <span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span>new_tag <span class="z-keyword z-operator z-comparison z-c">==</span> <span class="z-constant z-language z-c">NULL</span><span class="z-punctuation z-section z-group z-end z-c">)</span></span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-keyword z-control z-flow z-return z-c">return</span> <span class="z-constant z-language z-c">NULL</span><span class="z-punctuation z-terminator z-c">;</span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-storage z-type z-c">char</span> <span class="z-keyword z-operator z-c">*</span> needle <span class="z-keyword z-operator z-assignment z-c">=</span> <span class="z-meta z-function-call z-c"><span class="z-support z-function z-C99 z-c">strchr</span> <span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span></span></span><span class="z-meta z-function-call z-c"><span class="z-meta z-group z-c">new_tag<span class="z-punctuation z-separator z-c">,</span> <span class="z-string z-quoted z-single z-c"><span class="z-punctuation z-definition z-string z-begin z-c">&#39;</span>_<span class="z-punctuation z-definition z-string z-end z-c">&#39;</span></span></span></span><span class="z-meta z-function-call z-c"><span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-end z-c">)</span></span></span><span class="z-punctuation z-terminator z-c">;</span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-keyword z-control z-c">if</span> <span class="z-meta z-group z-c"><span class="z-punctuation z-section z-group z-begin z-c">(</span>needle <span class="z-keyword z-operator z-comparison z-c">!=</span> <span class="z-constant z-language z-c">NULL</span><span class="z-punctuation z-section z-group z-end z-c">)</span></span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-keyword z-operator z-c">*</span>needle <span class="z-keyword z-operator z-assignment z-c">=</span> <span class="z-string z-quoted z-single z-c"><span class="z-punctuation z-definition z-string z-begin z-c">&#39;</span><span class="z-constant z-character z-escape z-c">\0</span><span class="z-punctuation z-definition z-string z-end z-c">&#39;</span></span><span class="z-punctuation z-terminator z-c">;</span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"> <span class="z-keyword z-control z-flow z-return z-c">return</span> new_tag<span class="z-punctuation z-terminator z-c">;</span> </span></span></span><span class="z-source z-c"><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"></span></span><span class="z-meta z-function z-c"><span class="z-meta z-block z-c"><span class="z-punctuation z-section z-block z-end z-c">}</span></span></span> </span></code></pre> <p>In Vala, we use string offsets:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-modifier z-vala">static</span> <span class="z-storage z-type z-vala">string</span> <span class="z-meta z-method z-constructor z-vala"><span class="z-entity z-name z-function z-constructor z-vala">iso_639_from_tag</span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-begin z-vala">(</span></span></span><span class="z-meta z-method z-constructor z-vala"><span class="z-meta z-method z-parameters z-vala"><span class="z-storage z-type z-vala">string</span> <span class="z-variable z-parameter z-vala">dict_tag</span></span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-end z-vala">)</span></span> </span><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-control z-flow z-return z-vala">return</span> <span class="z-variable z-other z-vala">dict_tag</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">substring</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">0</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">dict_tag</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">index_of_char</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-meta z-string z-vala"><span class="z-string z-quoted z-single z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&#39;</span><span class="z-constant z-character z-literal z-vala">_</span><span class="z-punctuation z-definition z-string z-end z-vala">&#39;</span></span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span></code></pre> <p>The comparison here is perhaps obscured by the simplification obtained in Vala from automatic memory management, which is nothing to do with string handling <em>per se</em>.</p> <h4 id="binding-challenges">Binding challenges<a class="zola-anchor" href="#binding-challenges" aria-label="Anchor link for: binding-challenges">#</a> </h4> <p>I had a number of particular challenges. Some of them may be relevant to other developers, but I detail them here mostly to illustrate that Vala can bind just about anything if you try!</p> <h5 id="config-h"><code>config.h</code><a class="zola-anchor" href="#config-h" aria-label="Anchor link for: config-h">#</a> </h5> <p>Like any Autoconf-based build system, mine produce a <code>config.h</code> header of various <code>#define</code>d symbols, some of which my C code uses. These I simply replicate in a <a href="https://gitlab.gnome.org/GNOME/vala/-/blob/main/vapi/config.vapi"><code>Config</code> module</a></p> <p>One could imagine generating this automatically from <code>config.h</code>, but since I didn’t need more than a handful of values in my projects, I didn’t bother.</p> <h5 id="relocate"><code>relocate</code><a class="zola-anchor" href="#relocate" aria-label="Anchor link for: relocate">#</a> </h5> <p>This is a GNU API that returns a string that may or may not be <code>malloc</code>ed. You can tell which easily enough: if the return value is different from the argument, then it is a newly-allocated string. The problem is getting Vala to do the right thing. Even in C, I wrote my own wrapper function that would always return a <code>malloc</code>ed string.</p> <p>Here’s the Vala VAPI definition:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-meta z-annotation z-vala"><span class="z-punctuation z-definition z-annotation z-begin z-vala">[</span><span class="z-variable z-annotation z-vala">CCode</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-annotation z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-parameter z-vala">cheader_filename</span> <span class="z-keyword z-operator z-assignment z-vala">=</span> <span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>relocatable.h<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-parameter z-vala">cname</span> <span class="z-keyword z-operator z-assignment z-vala">=</span> <span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>relocate<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-meta z-annotation z-vala"><span class="z-punctuation z-definition z-annotation z-end z-vala">]</span></span> </span><span class="z-source z-vala"><span class="z-storage z-modifier z-access z-vala">private</span> <span class="z-support z-type z-vala">unowned</span> <span class="z-variable z-other z-vala">string</span> <span class="z-variable z-other z-vala">_gnulib_relocate</span>(<span class="z-variable z-other z-vala">string</span> <span class="z-variable z-other z-vala">path</span><span class="z-invalid z-illegal z-stray z-brace z-vala">)</span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></code></pre> <p>I use the name <code>_gnulib_relocate</code> because I am about to add a Vala wrapper which uses the original name. We tell Vala that the return value is <code>unowned</code>, to prevent Vala thinking that it must <code>free</code> it.</p> <p>Here’s the wrapper, which I also put in the VAPI:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-meta z-annotation z-vala"><span class="z-punctuation z-definition z-annotation z-begin z-vala">[</span><span class="z-variable z-annotation z-vala">CCode</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-annotation z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-parameter z-vala">cname</span> <span class="z-keyword z-operator z-assignment z-vala">=</span> <span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>_vala_relocate<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-meta z-annotation z-vala"><span class="z-punctuation z-definition z-annotation z-end z-vala">]</span></span> </span><span class="z-source z-vala"><span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-type z-vala">string</span> <span class="z-meta z-method z-constructor z-vala"><span class="z-entity z-name z-function z-constructor z-vala">relocate</span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-begin z-vala">(</span></span></span><span class="z-meta z-method z-constructor z-vala"><span class="z-meta z-method z-parameters z-vala"><span class="z-storage z-type z-vala">string</span> <span class="z-variable z-parameter z-vala">path</span></span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-end z-vala">)</span></span> </span><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-support z-type z-vala">unowned</span> <span class="z-variable z-other z-vala">string</span> <span class="z-variable z-other z-vala">newpath</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">_gnulib_relocate</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">path</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-comment z-line z-vala"><span class="z-punctuation z-definition z-comment z-vala">//</span> If relocate malloced, then return the value, defeating Vala&#39;s attempt </span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-comment z-line z-vala"><span class="z-punctuation z-definition z-comment z-vala">//</span> to (re-)strdup it. </span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-other z-vala">GLib</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">return_val_if_fail</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">newpath</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">data</span> <span class="z-keyword z-operator z-vala">==</span> <span class="z-variable z-other z-vala">path</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">data</span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">newpath</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-comment z-line z-vala"><span class="z-punctuation z-definition z-comment z-vala">//</span> Otherwise, allow Vala to strdup the non-malloced return value. </span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-control z-flow z-return z-vala">return</span> <span class="z-variable z-other z-vala">newpath</span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span></code></pre> <p>This is tricky. First, it calls the “real” <code>relocate</code> (but using its Vala name), and stores the result in an <code>unowned</code> string. So far, <code>valac</code> will not allocate any memory.</p> <p>We then test the value returned, and if it is unequal to the original argument, return it. Because we use the <code>return_if_fail</code> macro, <code>valac</code> will not insert memory allocation code at this point, but that’s OK, because <code>relocate</code> has already <code>malloc</code>ed in this case, so the return value is an allocated <code>string</code> as indicated.</p> <p>Otherwise, we simply <code>return</code> the un-<code>malloc</code>ed value. In the generated C, <code>valac</code> will insert a <code>g_strdup</code> at this point, so again the return value is an allocated string.</p> <p>Phew!</p> <h5 id="strfreev"><code>strfreev</code><a class="zola-anchor" href="#strfreev" aria-label="Anchor link for: strfreev">#</a> </h5> <p>Rather surprisingly, while <code>g_strfreev</code> takes <code>char **</code> (because it frees a list of strings), <code>strfreev</code> takes <code>string **</code>. Why? Well, Vala uses one level of pointer indirection to indicate that a value is not managed by Vala. So we have the following set of equivalences:</p> <ul> <li><code>string</code> = <code>char *</code> (generates <code>char *</code>; as we expect, a string is a pointer to <code>char</code>)</li> <li><code>string *</code> = <code>char *</code> (generates <code>char *</code>; this is just a <code>string</code> that Vala does not manage)</li> <li><code>string **</code> = <code>char **</code> (generates <code>char **</code>; now we have a list of <code>string</code>)</li> </ul> <p>This was a problem for me because I wanted to use <code>strfreev</code> to free a “real” <code>char **</code> passed in from C. But <code>valac</code> gives a type error. I got sufficiently confused that I submitted a <a href="https://gitlab.gnome.org/GNOME/vala/-/merge_requests/383">merge request</a>, and Rico had to de-confuse me. In the end, all I needed was a cast:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">strfreev</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala">(<span class="z-storage z-type z-vala">string</span> <span class="z-keyword z-operator z-vala">*</span><span class="z-keyword z-operator z-vala">*</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-variable z-other z-vala">c_string_list</span><span class="z-invalid z-illegal z-stray z-brace z-vala">)</span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></code></pre> <p>The cast placates <code>valac</code>, and the generated C ends up calling <code>g_strfreev</code>, which expected a <code>char **</code> all along.</p> <h5 id="s-size-t-is-not-really-s-size-t"><code>[s]size_t</code> is not really <code>[s]size_t</code><a class="zola-anchor" href="#s-size-t-is-not-really-s-size-t" aria-label="Anchor link for: s-size-t-is-not-really-s-size-t">#</a> </h5> <p>When compiling my Vala version of Enchant on Windows, I accidentally tried compiling it in a flavour of Windows I don’t normally test, namely Mingw MSYS (I normally build for Mingw64-x86_64 and Mingw64-i686). To my surprise, I got a compilation error: GCC complained that one 8-byte signed integer type (<code>long int</code>) was incompatible with another 8-byte signed integer type (<code>long long int</code>). Yes, these are both 64-bit types on this system, and yes, they are nonetheless incompatible.</p> <p>But why did I have this problem in the first place? I was using Vala’s <code>ssize_t</code>, and Vala maps this to GLib’s <code>gsize</code>. I don’t know why, but it’s a problem, because in some cases, like mine, these two types end up with different fundamental types in the C compiler, and an error results. I filed an <a href="https://gitlab.gnome.org/GNOME/vala/-/issues/1539">issue</a> and found a workaround, which was to copy the definition of <code>size_t</code> and <code>ssize_t</code> from <code>posix.vapi</code>, which are normally only used when <code>valac</code> is used with <code>--profile posix</code> and the GLib definitions are not used. The <code>posix.vapi</code> definitions correctly map <code>size_t</code> in Vala to <code>size_t</code> in C.</p> <h3 id="and-helping-hands">…and helping hands<a class="zola-anchor" href="#and-helping-hands" aria-label="Anchor link for: and-helping-hands">#</a> </h3> <p>I mentioned above that Vala is a small ecosystem. An up-side to this is that it’s friendly and usually quick to get things done. The fixes I offered were mostly triaged and applied by the indefatigable Rico Tzschichholz, who was often able to suggest more elegant solutions, mostly for my VAPI bindings. I ended up using a pre-release of <code>valac</code> for Zile, but I could release the code, since you didn’t need <code>valac</code> to build it, and within a few months, Vala 0.52 was released with all the fixes I needed.</p> <p>With Enchant I have had help from Rico again, and also from Lorenz Wildberg; many thanks to both of them, and to everyone else in the community to has both helped me with my projects, and welcomed my own contributions, which, I hope, improve things for everyone else.</p> <h2 id="was-it-worth-it">Was it worth it?<a class="zola-anchor" href="#was-it-worth-it" aria-label="Anchor link for: was-it-worth-it">#</a> </h2> <p>With GNU Zile I can say: probably, yes. I found one “brown-paper bag” bug in the initial stable release, but that’s it: I have made only two non-alpha releases of the Vala version. On the other hand, the C version was already very stable, and I suspect it’s not widely used any more (I myself have encouraged users to migrate to Emacs for some years!). But then, it was a low-risk project to try out this new technique. And a few years on, the code still builds with no problems: unlike some language ecosystems, Vala seems very stable, and code does not rot fast.</p> <p>For Enchant, it’s too early to say. It’s a much more widely-used package, and though it is quite mature, I have steadily improved and developed it over the past few years, and intend to continue in future. I hope that the switch to Vala will not annoy packagers (it shouldn’t, as they shouldn’t have to change their recipes at all if they don’t want to), and that developers should not notice (because the library remains API and ABI compatible), nor users (because the functionality should be identical, and the performance much the same). Certainly, I expect it will make my future work more productive and fun!</p> <h2 id="is-this-a-good-idea">Is this a good idea?<a class="zola-anchor" href="#is-this-a-good-idea" aria-label="Anchor link for: is-this-a-good-idea">#</a> </h2> <p>My projects are old-school: highly portable, low-level C. This is not an area that Vala is particularly aimed at, although it does pretty well here. For projects that are firmly in the GLib world, and especially when they use related libraries such as Gtk, rewriting C in Vala seems an excellent option to me.</p> <p>While I completely rewrote my projects before releasing them, I think I’ve shown there’s no need to do that. When I rewrote Zile in Lua, the intermediate steps had horrible performance, because the Lua/C interface I used was very inefficient (Lua has an efficient-but-complex C API; I chose to use some simple-but-slow home-grown macros instead). When I rewrote Zile in Vala, the performance was much the same at every stage of the process, and I could easily have translated just half of the code and released the project. Many projects, particularly larger ones, might benefit from such an approach.</p> <p>After completing the translation, the code was already significantly shorter and more readable than in C. This in turn unlocked further simplifications: able to “see the wood for the trees” it was much easier to refactor and further simplify the code. With Zile, I eventually reduced 8,000 lines of C to 6,000 of Vala, a 25% reduction; in Enchant the percentage saving was more like 35%, largely because of a reduction in GLib boilerplate, such as argument validation, which Vala mostly automates.</p> <p>One final thought: I hope that Vala will continue to flourish for many years, but if it doesn’t, then all is not lost: in the worst case, I or my successor could salvage the generated C code, which is ugly but far from impossible to read (and C, I think we can confidently say, will be around for many decades yet); and Vala is also a relatively “neutral” language that would be easy to translate again, into Rust, say; indeed, it would be easier to do that starting from Vala than from C, largely because the Vala code is easier to read and understand.</p> <hr /> <p>You are always invited to join our matrix chat <a href="https://matrix.to/#/#_gimpnet_#vala:gnome.org">#vala:gnome.org</a> and ask questions about Vala or how to contribute. Until then, have a nice time and build great apps with Vala!</p> <!-- LocalWords: Vala’s GLib GObject Lua’s VAPI GLib’s Enchant’s codegen <!-- LocalWords: Automake’s Terminfo Gtk Mingw MSYS VAPIs regex libgee ed <!-- LocalWords: ArrayList int getopt freopen FileStream putc valac Jürg <!-- LocalWords: config Billeter malloc vala CCode cheader cname newpath <!-- LocalWords: malloced Vala's strdup val un strfreev Mingw64 i686 vapi <!-- LocalWords: ssize gsize posix gimpnet se --> print("Hello Planet GNOME"); 2023-10-11T00:00:00+00:00 2023-10-11T00:00:00+00:00 Unknown https://vala.dev/blog/planet-gnome/ <p>Hello to all of you reading <a href="https://planet.gnome.org/">Planet GNOME</a> right now! This is the first post from the <a href="https://vala.dev/blog/">Vala Blog</a> now appearing in the big wide world of GNOME.</p> <p>Big thanks to the Planet GNOME team and Felipe Borges for making this possible!</p> <p>This blog is operated by the Vala project and we are posting here once in a while about new Vala releases, noteworthy changes like new features and how to use them, interesting projects using Vala and their experience with it and other stuff related to the Vala programming language.</p> <p>If you have an idea to write about something that fits one of the categories above, reach out to us and we are sure eventually a great article will be released! (Talk to us <a href="https://vala.dev/#community">here</a>)</p> <p>Stay tuned for the next posts coming out! :)</p> Vala 0.56 2022-03-18T00:00:00+00:00 2022-03-18T00:00:00+00:00 Unknown https://vala.dev/blog/vala-0-56/ <p>After 4 months of work we are proud to announce a new release of Vala. This time it contains lots of new language features and advancements and of course also the usual bug fixes and binding updates.</p> <h2 id="asynchronous-main-function">Asynchronous Main Function<a class="zola-anchor" href="#asynchronous-main-function" aria-label="Anchor link for: asynchronous-main-function">#</a> </h2> <p>With the new release the main function can now be defined as <code>async</code>. This has multiple advantages. For example is it now possible to call asynchronous functions with <code>yield</code>:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-modifier z-vala">async</span> <span class="z-storage z-type z-vala">int</span> <span class="z-meta z-method z-constructor z-vala"><span class="z-entity z-name z-function z-constructor z-vala">main</span> <span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-begin z-vala">(</span></span></span><span class="z-meta z-method z-constructor z-vala"><span class="z-meta z-method z-parameters z-vala"><span class="z-storage z-type z-vala">string</span><span class="z-meta z-brackets z-vala"><span class="z-punctuation z-section z-brackets z-begin z-vala">[</span><span class="z-punctuation z-section z-brackets z-end z-vala">]</span></span> <span class="z-variable z-parameter z-vala">args</span></span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-end z-vala">)</span></span> </span><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-type z-vala">string</span> <span class="z-variable z-other z-vala">dir</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-variable z-other z-vala">args</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">length</span> <span class="z-keyword z-operator z-vala">==</span> <span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">2</span></span> <span class="z-keyword z-operator z-ternary z-vala">?</span> <span class="z-variable z-other z-vala">args</span><span class="z-meta z-brackets z-vala"><span class="z-punctuation z-section z-brackets z-begin z-vala">[</span></span><span class="z-meta z-brackets z-vala"><span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">1</span></span></span><span class="z-meta z-brackets z-vala"><span class="z-punctuation z-section z-brackets z-end z-vala">]</span></span> <span class="z-keyword z-operator z-ternary z-vala">:</span> <span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>.<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-type z-variable z-vala">var</span> <span class="z-variable z-other z-vala">file</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-variable z-other z-vala">File</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">new_for_commandline_arg</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">dir</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-meta z-block z-trycatch z-vala"><span class="z-keyword z-control z-trycatch z-try z-vala">try</span> <span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-support z-type z-vala">FileEnumerator</span> <span class="z-variable z-other z-vala">enumerator</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-other z-vala">yield</span> <span class="z-variable z-other z-vala">file</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">enumerate_children_async</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> <span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>standard::*,time::*<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> <span class="z-variable z-other z-vala">FileQueryInfoFlags</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">NOFOLLOW_SYMLINKS</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> </span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-support z-type z-vala">List</span><span class="z-meta z-generic z-vala"><span class="z-punctuation z-definition z-generic z-begin z-vala">&lt;</span></span><span class="z-meta z-generic z-vala"><span class="z-support z-type z-vala">FileInfo</span><span class="z-meta z-generic z-vala"><span class="z-punctuation z-definition z-generic z-end z-vala">&gt;</span></span></span> <span class="z-variable z-other z-vala">children</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-other z-vala">yield</span> <span class="z-variable z-other z-vala">enumerator</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">next_files_async</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-storage z-type z-vala">int</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">MAX</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">print</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>total %lu<span class="z-constant z-character z-escape z-vala">\n</span><span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">children</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">length</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-control z-loop z-foreach z-vala">foreach</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span><span class="z-meta z-group z-vala"><span class="z-storage z-type z-variable z-vala">var</span> <span class="z-variable z-other z-vala">info</span> <span class="z-keyword z-control z-flow z-vala">in</span> <span class="z-variable z-other z-vala">children</span><span class="z-punctuation z-section z-group z-end z-vala">)</span></span> <span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"> <span class="z-comment z-line z-vala"><span class="z-punctuation z-definition z-comment z-vala">//</span> &lt;file-type&gt; &lt;access-date&gt; &lt;size&gt; &lt;name&gt; </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"> <span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">print</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>%26s %24s %10<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-keyword z-operator z-vala">+</span><span class="z-storage z-type z-vala">int64</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">FORMAT</span><span class="z-keyword z-operator z-vala">+</span><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span> B %s<span class="z-constant z-character z-escape z-vala">\n</span><span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> </span></span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> <span class="z-variable z-other z-vala">info</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">get_content_type</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> </span></span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> <span class="z-variable z-other z-vala">info</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">get_access_date_time</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">to_string</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> </span></span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> <span class="z-variable z-other z-vala">info</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">get_size</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> </span></span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"> <span class="z-variable z-other z-vala">info</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">get_name</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-vala"> <span class="z-punctuation z-section z-block z-end z-vala">}</span></span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-punctuation z-section z-block z-end z-vala">}</span></span> <span class="z-keyword z-control z-trycatch z-catch z-vala">catch</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span><span class="z-meta z-group z-vala"><span class="z-support z-type z-vala">Error</span> <span class="z-variable z-other z-vala">e</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span> <span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">printerr</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>failed to enumerate files - %s<span class="z-constant z-character z-escape z-vala">\n</span><span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">e</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">message</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-control z-flow z-return z-vala">return</span> <span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">1</span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-punctuation z-section z-block z-end z-vala">}</span></span> </span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"> </span><span class="z-keyword z-control z-flow z-return z-vala">return</span> <span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">0</span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span></code></pre> <p>In main blocks (experimental feature that allows it to write code in a file without putting in a main function) invoking functions with <code>yield</code> is also supported by making the main block automatically asynchronous.</p> <p>Merge Request <a href="https://gitlab.gnome.org/GNOME/vala/-/merge_requests/226">#226</a></p> <h2 id="nested-functions">Nested functions<a class="zola-anchor" href="#nested-functions" aria-label="Anchor link for: nested-functions">#</a> </h2> <p>A simple but very useful feature is to be able to nest functions inside of other functions or methods. These functions are then only visible to the code in the function that contains the nested one. But on the other way the code in the nested function has access to variables in the upper method. Actually they are only lambdas assigned to a local variable.</p> <p>Use cases are to structure very complicated functions into multiple smaller ones, without exposing them publicly. In this example the same asynchronous callback is used for two invocations, in which you otherwise would use lambdas:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-type z-vala">void</span> <span class="z-meta z-method z-constructor z-vala"><span class="z-entity z-name z-function z-constructor z-vala">write_streams</span> <span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-begin z-vala">(</span></span></span><span class="z-meta z-method z-constructor z-vala"><span class="z-meta z-method z-parameters z-vala"><span class="z-support z-type z-vala">OutputStream</span> <span class="z-variable z-parameter z-vala">stream1</span><span class="z-punctuation z-separator z-parameter z-function z-vala">,</span> <span class="z-support z-type z-vala">OutputStream</span> <span class="z-variable z-parameter z-vala">stream2</span><span class="z-punctuation z-separator z-parameter z-function z-vala">,</span> <span class="z-storage z-type z-vala">uint8</span><span class="z-meta z-brackets z-vala"><span class="z-punctuation z-section z-brackets z-begin z-vala">[</span><span class="z-punctuation z-section z-brackets z-end z-vala">]</span></span> <span class="z-variable z-parameter z-vala">data</span></span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-end z-vala">)</span></span> </span><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-type z-vala">void</span> <span class="z-meta z-method z-constructor z-vala"><span class="z-entity z-name z-function z-constructor z-vala">nested_function</span> <span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-begin z-vala">(</span></span></span><span class="z-meta z-method z-constructor z-vala"><span class="z-meta z-method z-parameters z-vala"><span class="z-support z-type z-vala">Object</span> <span class="z-variable z-parameter z-vala">object_source</span><span class="z-punctuation z-separator z-parameter z-function z-vala">,</span> <span class="z-support z-type z-vala">AsyncResult</span> <span class="z-variable z-parameter z-vala">result</span></span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-end z-vala">)</span></span> </span><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-support z-type z-vala">OutputStream</span> <span class="z-variable z-other z-vala">stream</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-variable z-other z-vala">object_source</span> <span class="z-keyword z-operator z-reflection z-vala">as</span> <span class="z-support z-type z-vala">OutputStream</span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-meta z-block z-trycatch z-vala"><span class="z-keyword z-control z-trycatch z-try z-vala">try</span> <span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-type z-vala">ssize_t</span> <span class="z-variable z-other z-vala">size</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-variable z-other z-vala">stream</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">write_async</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">finish</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">result</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-other z-vala">stdout</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">printf</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-raw z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">@&quot;</span>Written $size bytes\n<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-punctuation z-section z-block z-end z-vala">}</span></span> <span class="z-keyword z-control z-trycatch z-catch z-vala">catch</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span><span class="z-meta z-group z-vala"><span class="z-support z-type z-vala">Error</span> <span class="z-variable z-other z-vala">e</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span> <span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-other z-vala">stderr</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">printf</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>Error writing to stream: %s<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">e</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">message</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"><span class="z-meta z-block z-vala"> <span class="z-punctuation z-section z-block z-end z-vala">}</span></span> </span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-block z-trycatch z-vala"> </span><span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-other z-vala">stream1</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">write_async</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">data</span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">nested_function</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-other z-vala">stream2</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">write_async</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">data</span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-variable z-other z-vala">nested_function</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span><span class="z-source z-vala"> </span></code></pre> <p>Merge Request <a href="https://gitlab.gnome.org/GNOME/vala/-/merge_requests/203">#203</a></p> <h2 id="redesign-of-error-and-warning-output">Redesign of error and warning output<a class="zola-anchor" href="#redesign-of-error-and-warning-output" aria-label="Anchor link for: redesign-of-error-and-warning-output">#</a> </h2> <p>If programming errors are outputted at compile time in a pretty way and provide as much information as possible, they massively help and speed up finding the mistakes and correcting them. In the new release this part got an update. Look at the differences yourself:</p> <p>Before Vala 0.56:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-type z-vala">int</span> <span class="z-variable z-other z-vala">foo</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">bar</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span><span class="z-source z-vala"> <span class="z-keyword z-operator z-vala">^</span><span class="z-keyword z-operator z-vala">^</span><span class="z-keyword z-operator z-vala">^</span> </span></code></pre> <p>Vala 0.56:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">2</span></span> <span class="z-keyword z-operator z-vala">|</span> <span class="z-storage z-type z-vala">int</span> <span class="z-variable z-other z-vala">foo</span> <span class="z-keyword z-operator z-assignment z-vala">=</span> <span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">bar</span><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span><span class="z-source z-vala"> <span class="z-keyword z-operator z-vala">|</span> <span class="z-keyword z-operator z-vala">^</span><span class="z-keyword z-operator z-vala">~</span><span class="z-keyword z-operator z-vala">~</span> </span><span class="z-source z-vala"> </span></code></pre> <p>What looks better? :)</p> <p>Issue <a href="https://gitlab.gnome.org/GNOME/vala/-/issues/764">#764</a></p> <h2 id="dynamic-invocation-of-signals">Dynamic invocation of Signals<a class="zola-anchor" href="#dynamic-invocation-of-signals" aria-label="Anchor link for: dynamic-invocation-of-signals">#</a> </h2> <p>Libraries using the GObject type system are providing usually documentation about their API so other languages can use them. However sometimes some parts are missing. With the <code>dynamic</code> keyword an object can be treated as not having all properties or signals specified and they can be accessed dynamically without checking:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-support z-type z-vala">dynamic</span> <span class="z-variable z-other z-vala">Gst</span>.<span class="z-variable z-other z-vala">Element</span> <span class="z-variable z-other z-vala">appsink</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-variable z-other z-vala">Gst</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">ElementFactory</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">make</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>appsink<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span><span class="z-punctuation z-separator z-argument z-vala">,</span> <span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>my_src<span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span><span class="z-source z-vala"><span class="z-variable z-other z-vala">appsink</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">max_buffers</span> <span class="z-keyword z-operator z-assignment z-vala">=</span> <span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">0</span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span><span class="z-source z-vala"><span class="z-variable z-other z-vala">appsink</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">eos</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">connect</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-variable z-other z-vala">on_eos</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span><span class="z-source z-vala"><span class="z-support z-type z-vala">Gst</span><span class="z-punctuation z-accessor z-dot z-namespace z-vala">.</span><span class="z-support z-type z-vala">Sample</span><span class="z-storage z-type z-nullable z-vala">?</span> <span class="z-variable z-other z-vala">res</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-variable z-other z-vala">appsink</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">pull_sample</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">emit</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span><span class="z-source z-vala"> </span></code></pre> <p>As you can see, signals are now also callable with <code>.emit ()</code>. This is necessary to differentiate between a method or a dynamic signal. But this syntax can be also used with non-dynamic variables if wanted.</p> <p>Merge Request <a href="https://gitlab.gnome.org/GNOME/vala/-/merge_requests/227">#227</a></p> <h2 id="partial-classes">Partial classes<a class="zola-anchor" href="#partial-classes" aria-label="Anchor link for: partial-classes">#</a> </h2> <p>In rare cases, if a class is so huge and complex, it can be now split up into multiple pieces even into multiple files. All parts of the class only need the partial keyword in front of it.</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-modifier z-vala">partial</span> <span class="z-meta z-class z-vala"><span class="z-storage z-type z-class z-vala">class</span> <span class="z-entity z-name z-class z-vala">Foo </span><span class="z-punctuation z-separator z-type z-vala">:</span> <span class="z-entity z-other z-inherited-class z-vala">Object</span> </span><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-type z-vala">double</span> <span class="z-support z-type z-vala">bar</span> { <span class="z-support z-type z-vala">get</span>; <span class="z-support z-type z-vala">set</span>; } </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala">} </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-modifier z-vala">partial</span> <span class="z-meta z-class z-vala"><span class="z-storage z-type z-class z-vala">class</span> <span class="z-entity z-name z-class z-vala">Foo </span><span class="z-punctuation z-separator z-type z-vala">:</span> <span class="z-entity z-other z-inherited-class z-vala">Initable</span> </span><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-storage z-modifier z-access z-vala">public</span> <span class="z-storage z-modifier z-vala">virtual</span> <span class="z-storage z-type z-vala">bool</span> <span class="z-meta z-method z-constructor z-vala"><span class="z-entity z-name z-function z-constructor z-vala">init</span> <span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-begin z-vala">(</span></span></span><span class="z-meta z-method z-constructor z-vala"><span class="z-meta z-method z-parameters z-vala"><span class="z-support z-type z-vala">Cancellable</span><span class="z-storage z-type z-nullable z-vala">?</span> <span class="z-variable z-parameter z-vala">cancellable</span> <span class="z-keyword z-operator z-assignment z-default-value z-vala">=</span> <span class="z-constant z-language z-vala">null</span></span><span class="z-meta z-method z-parameters z-vala"><span class="z-punctuation z-section z-parameters z-end z-vala">)</span></span> </span><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-begin z-vala">{</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-other z-vala">stdout</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-meta z-function-call z-vala"><span class="z-variable z-function z-vala">printf</span> <span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-begin z-vala">(</span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-string z-quoted z-double z-vala"><span class="z-punctuation z-definition z-string z-begin z-vala">&quot;</span>hello!<span class="z-constant z-character z-escape z-vala">\n</span><span class="z-punctuation z-definition z-string z-end z-vala">&quot;</span></span></span></span><span class="z-meta z-function-call z-vala"><span class="z-meta z-group z-vala"><span class="z-punctuation z-section z-group z-end z-vala">)</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-variable z-language z-vala">this</span><span class="z-punctuation z-accessor z-dot z-vala">.</span><span class="z-variable z-other z-vala">bar</span> <span class="z-keyword z-operator z-assignment z-vala">=</span> <span class="z-meta z-number z-float z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">0</span><span class="z-constant z-numeric z-value z-vala"><span class="z-punctuation z-separator z-decimal z-vala">.</span>56</span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-keyword z-control z-flow z-return z-vala">return</span> <span class="z-constant z-language z-vala">true</span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></span></span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-method z-body z-vala"><span class="z-meta z-block z-vala"> <span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span></span></span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"><span class="z-punctuation z-section z-block z-end z-vala">}</span></span></span> </span></span></span><span class="z-source z-vala"><span class="z-meta z-class z-body z-vala"><span class="z-meta z-block z-vala"> </span></span></span></code></pre> <p>Merge Request <a href="https://gitlab.gnome.org/GNOME/vala/-/merge_requests/200">#200</a></p> <h2 id="length-type-for-arrays">Length-type for Arrays<a class="zola-anchor" href="#length-type-for-arrays" aria-label="Anchor link for: length-type-for-arrays">#</a> </h2> <p>The length of an array is usually specified by an 32bit integer. However in some cases, especially in bindings to other libaries, sometimes the length of an array is given by a different type of integer. We now have support for that:</p> <pre data-lang="vala" class="language-vala z-code"><code class="language-vala" data-lang="vala"><span class="z-source z-vala"><span class="z-storage z-type z-vala">string</span><span class="z-meta z-brackets z-vala"><span class="z-punctuation z-section z-brackets z-begin z-vala">[</span><span class="z-punctuation z-section z-brackets z-end z-vala">]</span></span> <span class="z-variable z-other z-vala">list</span> <span class="z-keyword z-operator z-assignment z-variable z-vala">=</span> <span class="z-meta z-instance z-vala"><span class="z-keyword z-operator z-new z-vala">new</span></span><span class="z-meta z-instance z-vala"> </span><span class="z-meta z-instance z-vala"><span class="z-storage z-type z-vala">string</span><span class="z-meta z-brackets z-vala"><span class="z-punctuation z-section z-brackets z-begin z-vala">[</span><span class="z-meta z-number z-integer z-decimal z-vala"><span class="z-constant z-numeric z-value z-vala">10</span></span>:<span class="z-storage z-type z-vala">uint8</span><span class="z-punctuation z-section z-brackets z-end z-vala">]</span></span></span><span class="z-punctuation z-terminator z-statement z-vala">;</span> </span></code></pre> <p>Issue <a href="https://gitlab.gnome.org/GNOME/vala/-/issues/607">#607</a></p> <h2 id="foreach-support-on-glib-sequence-and-glib-array">Foreach support on Glib.Sequence and Glib.Array<a class="zola-anchor" href="#foreach-support-on-glib-sequence-and-glib-array" aria-label="Anchor link for: foreach-support-on-glib-sequence-and-glib-array">#</a> </h2> <p>This small change will be a big improvement for users of these data structures. Instead of manually looping with for, they are now ready to be used with a foreach loop over the items in the sequence or array.</p> <p>Merge Request <a href="https://gitlab.gnome.org/GNOME/vala/-/merge_requests/234">#234</a></p> <h2 id="new-bindings">New Bindings<a class="zola-anchor" href="#new-bindings" aria-label="Anchor link for: new-bindings">#</a> </h2> <p>A bunch of new bindings to libraries got added this release. Here is a list:</p> <ul> <li>libsoup is now also available in version 3.0 and webkit2gtk in version 4.1 and 5.0 so you can start porting you Vala apps to the new releases of these libraries</li> <li>linux-media can now be used from Vala. There were also lots of more additions and fixes in other linux kernel interface bindings.</li> <li>During the port of the gnome-desktop library it was splitted up into gnome-desktop-4, gnome-rr-4 and gnome-bg-4. They are all now available to use in your new app.</li> <li>The GLib vapi was updated to version 2.72, including the new Signal- and BindingGroups and DebugController</li> </ul> <h2 id="gnome-getting-started-tutorial">GNOME Getting started tutorial<a class="zola-anchor" href="#gnome-getting-started-tutorial" aria-label="Anchor link for: gnome-getting-started-tutorial">#</a> </h2> <p>The GNOME developer documentation has besides other stuff a excellent section on getting started with GTK and app development. Most of the <a href="https://developer.gnome.org/documentation/tutorials.html">tutorials</a> there have now code examples in Vala. So read it and write your first Vala application! :)</p> <h2 id="vala-flatpak-sdk-extension">Vala Flatpak Sdk Extension<a class="zola-anchor" href="#vala-flatpak-sdk-extension" aria-label="Anchor link for: vala-flatpak-sdk-extension">#</a> </h2> <p>You can find on flathub now the <code>org.freedesktop.Sdk.Extension.vala</code> Extension. It contains the Vala compiler, language server and more tooling. You can use it either for compiling your Vala app, or if you need for example the language server at runtime, like an IDE. Instructions can be found at the <a href="https://github.com/flathub/org.freedesktop.Sdk.Extension.vala">flathub repository</a>.</p> <h2 id="google-summer-of-code">Google Summer of Code<a class="zola-anchor" href="#google-summer-of-code" aria-label="Anchor link for: google-summer-of-code">#</a> </h2> <p>We have proposed a project idea for the Google Summer of Code for working on Vala. If you are interested, check out the <a href="https://discourse.gnome.org/t/gsoc-2022-project-ideas/8931#add-support-for-the-latest-gir-attributes-and-gi-docgen-formatting-to-valadoc-15">project ideas page</a> on GNOME discourse.</p> <hr /> <p>You are always invited to join our matrix chat <a href="https://matrix.to/#/#_gimpnet_#vala:gnome.org">#vala:gnome.org</a> and ask questions about Vala or how to contribute. Until then, have a nice time and build great apps with Vala!</p>