[Vala] [RFC] Extension methods (Re: maemo5 hildon input mode)



Hello,

This looks like another use-case for extension methods in a day.

Extension methods in C# work are static methods defined anywhere, that
can be called like (instance) methods of some particular class or interface.

They would make perfect way for add-on libraries to provide convenience
methods for objects defined elsewhere. In .NET they are mainly used to
provide the "linq" methods to interfaces.

In C# extension methods are defined as static methods of any class, but
that seems to be because they were invented before C# allowed namespace-
scoped functions. So for Vala I'd suggest putting them in the namespace
the class is in or in a special "extend class".

Suppose there is interface Moo.IComparable, that looks like
namespace Moo {
    interface IComparable : GLib.Object {
        bool less_than(IComparable rhs);
    }
}

Having one comparison allows defining the others in terms of the first
one. In Vala (unlike C#) interfaces can have implemented methods, but
suppose the library author forgot to define less_or_equal and you want
to define it and don't have control over the interface. So you'd define
extension method to add it. I propose following options for syntax:

namespace Moo {
    bool less_or_equal(IComparable this lhs, IComparable rhs) {
        return !rhs.less_than(lhs);
    }
}
(the disadvantage here is that it has to be mangled to
moo_icomparable_less_or_equal, leading to a bit of overloading (another
less_or_equal with different "this" argument would be allowed))

namespace Moo {
    bool icomparable_less_or_equal(IComparable this lhs, IComparable rhs) {
        return !rhs.less_than(lhs);
    }
}
(now the author needs to know the Vala mangling, because it's still supposed
to be called a.less_or_equal(b))

namespace Moo {
    [lowercase_cprefix="icomparable_"]
    class IComparableExtensions {
        bool less_or_equal(IComparable this lhs, IComparable rhs) {
            return !rhs.less_than(lhs);
        }
    }
}
(this is most C#-py, but requires either the c prefix annotation, or special
mangling rules)

namespace Moo {
    [Extend]
    interface IComparable {
        bool less_or_equal(IComparable rhs) {
            return !rhs.less_than(this);
        }
    }
}
(writing [Extend] to avoid new keyword, but that would be an option)
I probably like the last option best, but it's least like C#, so it depends
on how much similarity is desired.

I suppose extension properties should be possible with the limitation, that
they cannot have default implementation.

On Tue, February 9, 2010 22:44, pHilipp Zabel wrote:
I would suggest that adding vendor specific modifications to existing
classes is way too ugly

Agreed.

Modifications are indeed ugly, but adding a couple of convenience methods
following the normal naming convention of methods for the class is IMHO OK.

to be accepted and you should bind it to hildon
classes. How can they even add more properties to an already defined
class?

They ship a modified GTK+ library. Hildon depends on that.
I guess we could get away with just binding the hildon_gtk_entry_*
methods to Hildon.Entry instead of Gtk.Entry. Is there a way of doing
this via metadata before the vapigen step?
But there are a few others like hildon_gtk_widget_set_theme_size or
hildon_gtk_window_set_progress_indicator that can't be mapped to
Hildon classes, as they are needed to work on Gtk.Button and
Gtk.Dialog, for example.

That's where extension methods would be useful. The hildon package would
just do
[cprefix="hildon_gtk"]
namespace Gtk {
    [Extend] class Widget { ... set_theme_size(...); }
    [Extend] class Widnow { ... set_progress_indicator(...); }
}
and

-- 
                                        - Jan Hudec <bulb ucw cz>




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]