Metaprogramming ideas for Vala

This is all just a set of ideas for how to add metaprogramming to Vala. It is not harmful to dream(Russian saying).

1) C++ template style

Simple make generic variables, that you can try to call any method, and the compiler checks whether this can be done or not, checking whether the type that the generic was called with has this symbol.
Perhaps this is the easiest way, in terms of implementation.

2) Macros. (The manipulation of the AST)

Problem: macros cannot be supported by tools.
2 Options:
2.1) Restrict things that macros can change, such as the semantics(Nim) must be preserved.
2.2) To create macros, a special API must be provided, such that when you create a macro, you automatically teach VLS how to work with it. Such changes to the compiler behavior are a separate project. (idea from Kotlin) But here there is a problem in the need to create a reference VLS, or include some part of it in the compiler(such things already happen https://gitlab.gnome.org/GNOME/vala/-/merge_requests/95)

PS A great article describing how this was handled in D.

3) API for code attributes

This option is very similar to the second option, and here you need to think about how to achieve VLS support.
For example, apmasell added a new code attribute to the Vala compiler [Interrupt(vector = "foo", block = true] to support AVR controllers by implementing his own custom libvala frontend.

Ideas: the class attribute which makes the object’s fields to the fields in XML/JSON/… , an attribute of a method that turns its application into an SQL string(making a class with such methods will result in something like ORM)

Once again, I’m talking specifically about providing the user with an API to create new code attributes, as in the example of how apmasell implemented its Vala forks, but to make it look easier and with restrictions.

4) New C++ backend

Pros

  • Free metaprogramming
  • Applying var (auto) in previously inaccessible places (method arguments, method types returned…)
  • constexpr ()
  • concepts (restrictions for types) and other things from C++20…23
  • Native interaction with C++ code. This is probably one of the most important advantages, as it gives access to a huge code base, and adds Vala new areas of application besides GTK applications. (Qt -> embended UI, UE4, boost?, …) (Although there aren’t too many limiting factors right now)

Cons/Problems:

  • Probably a long compilation, if you do not use some hacks for code generation. (For example, Nim actively uses goto)
  • It will take a few tricks to organize the interaction of the code on C - > C++ backends.
    The interaction between C++ -> C is limited, perhaps this problem can be solved via GIR/SWIG (ValaBind, example )
  • Interaction of the C++ backend with GIR (priority for Vala, I think it is still possible due to compatibility with C ABI)

But
constexpr and auto will appear in C2X, and vala will be able to get these advantages for free, but it won’t be soon. However, it is worth considering that by that time new features will appear in C++.

There have already been several attempts to create a C++ backend:


5)

Infix notation (Kotlin) or Uniform Function Call Syntax (D) give the language great opportunities to implement something DSL like, without directly implementing meta programming.

6) Creating custom Methods With Syntax Support

Vala already supports this for certain operators (in, foreach, [], [:], [,], …) if you let the user choose which text / operator will turn into a function, it will also allow you to create DSL and much more. From the point of view of C, this will just be a function call.
Here some examples:

class Counter: Object{
    public int Value { get; set; default = 0;}
    // infix
    public static Counter plus + (Counter c1, Counter c2) {
        return new Counter { Value = c1.Value + c2.Value }; // var res = c1 + c2;
    }
// prefix, postfix
public static Counter increment ++ (Counter c1) {
    return new Counter { Value = c1.Value + 10 };
}
// 
    public static bool roughly_equal  ~~ (Counter c1, Counter c2) {
        return  round(c1.Value) > round(c2.Value); // bool res = c1 ~~ c2;
    }
    public static bool contain in (Counter c1, Counter c2) {
        return  round(c1.Value) > round(c2.Value);
    }
   // or like that, Most likely it will require the implementation of the first option
    public static bool contain<T> in (T left_value){ 
        return this.contain(left_value);
    }
    //with keyword? Need to implement templates from first variant
    delegate T WithFunc<T> (T t);
    public static void with with (params WithFunc[] funcs){
        foreach (var func in funcs)
             func(this);
             // or
             this.func;
    }
    //real with, same but with AST manipulation?, T here is somehow type for code (Dlang mixin?)
    public static void<T> with with (params T[] anything){
        foreach (var any in anything)
             this.T;
    }
}

7) API for creating / modifying parsers as Genie.

This must also be accompanied by correct VLS changes so that syntax highlighting and the rest will continue to work. Something similar has already been discussed here (I didn’t know HAXE existed then). This option is very similar to macros.


All these options are too complex to implement, and Vala already has unresolved problems(I think all languages have). But there is progress in improving the syntax, for example, the params keyword added in 0.48 from C#, PR by adding the null-conditional member access operator ?. , negation of is/in operators, Kotlin-style namespace declaration, and my favorite is the with keyword .

All this can be implemented at libvala, some features should be implemented thinking about how that can be implemented in C. For the ones out of C, because they can be too complicated, a new profile should be implemented like C++ code generator.

The big advantage of Vala against, for example C++, is C generated code. C code can be reused anywhere, even in C++, ValaBind is a good example on how to create bindings to other languages using the C generated code from Vala. Write down directly C++ code, I think, is out of scope of Vala and the user will loose its advantages.

Adding more operators to Vala, in order to increase its sugar syntax and increase its productivity will push harder to developers wanting to use GLib/GObject, including Gtk, as the base technology for their projects, to use Vala instead other, allowing them to reuse its code, breaking the limits of programming languages.

1 Like