Re: Proposal for a collection API in glib
Hi Havoc, On Thu, 2008-07-17 at 13:37 -0400, Havoc Pennington wrote: 2) Another idea would be an equivalent to registering boxed types: g_iterator_type_register_static(const char *name, GBoxedCopyFunc boxed_copy, GBoxedFreeFunc boxed_free, GIteratorNextFunc iterator_next, GIteratorGetFunc iterator_get); This would allow language bindings to generically manipulate custom iterator types like TextIter and TreeIter, without making things a pain in C and while keeping things lightweight. And without redoing/breaking TreeModelIter and TextIter and all the other existing examples you mention. One issue I see with this approach is that new libraries in C still have to invent their own interfaces for collections, as GList is certainly not suitable for every situation, e.g. when using lazy loading. They could register their collection interfaces, which helps for language bindings, but we'd still not have a real collection API that libraries can use. However, I agree that we certainly should support iteration over GLists with the new API, building such a bridge should be possible with almost any approach we take, though. Why explore alternate ideas? Some downsides to GIterator-as-gobject: * GObject is pretty heavyweight for something like this, and moreover right now libglib doesn't depend on libgobject I certainly understand this point as for example valac spends most of the compile time creating new GObjects. However, I think there is still room for improvement without dropping the idea of using interfaces for collections. There are two objects involved when iterating over a collection: the collection and the iterator. In libgee, both are GObjects, which might really be an overkill. One possibility would be to drop the GObject prerequisite in the interfaces, i.e. allow types like GstMiniObject to implement the collection interface. This would speed up object creation quite significantly (by factor 5, iirc), and still have all the interface features. The major issue I see with this approach is that you can't just use the usual g_object_ref/unref as that's only valid for GObjects. Possible solutions for this problem: * add a new fundamental classed type to GLib, either something like GstMiniObject or a more concrete GCollection, however, this makes it impossible for full GObjects to implement the same interface * add virtual functions for ref/unref to the interface * move reference counting from GObject down to GTypeInstance, not possible for GLib 2.x, and might drag too much from GObject to GTypeInstance, not sure If this is still not performing well enough, we could keep the interface for the collection but use a stack-allocated struct like GtkTreeIter for the iterator, so that we only need a heap object for the collection. * the need to unref the iterator is onerous for C programmers using iterators Freeing a GList is certainly more complex and error-prone than unrefing a GObject-based collection, as you have to take care of the elements when freeing a GList. I consider this a major drawback of GList, not only for language bindings, also when used in C. For the iterator itself, we certainly could switch to a stack-allocated struct, as noted above for performance reasons. However, for collections unref makes it a lot easier, in my opinion. * the need to subclass a GObject is onerous for C programmers creating iterators Not everyone needs to implement their own collection and iterator class. Many libraries and applications will probably work fine with something like GeeArraList if that'd be in GLib. The main point is to enable developers to implement their own collections if they have specific needs. The interface approach allows this without breaking the interface, as it doesn't expose implementation details as is the case when using GLists. You also have to subclass a GObject in GTK+ if you write your own widget, however, many applications don't need to. * as Owen mentioned long ago when this was already discussed, we'd end up duplicating bunches of APIs just to make them use iterators instead of whatever they use now - this is both bloat and confusing. It would not be realistic to ever deprecate walking GList etc. - the iterator replacement is much less convenient, and there's way, way, way too much code using GList already. You can't deprecate something that touches this much code. I agree, however, there are already many libraries that don't use GList for various reasons and implement their own iterator interfaces. Moving such an iterator interface to GLib would at leasts prevent the ongoing fragmentation in that area. Also, as I already wrote above, we certainly want to build a bridge between GList and the new iterator interface. Jürg ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Proposal for a collection API in glib
On Thu, Jul 17, 2008 at 05:51:24PM +0200, Philip Van Hoof wrote: I would like to propose this API to go into glib/gio: http://live.gnome.org/IteratorsAPI I'd like to point to my comment on that page: Please make the Iterator interface derive from the Iterable interface, where the iterator() function should just return the object itself. I've explained the point in detail in [1], but here is a short summary: Often you'd like to iterate an object in different orders, for example a Tree class that might be iterated depth-first or breath-first. In that case it's not enough to just make Tree implement the Iterable interface, you also need to have two functions DepthFirstIterator and BreathFirstIterator. If Iterators are Iterable, you can just use the returned iterator like you would use the Tree object itself. If they aren't you'd need to return a custom Iterable object (which implements an Iterator). - Sebastian [1] http://www.rittau.org/blog/20061122-00 ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Proposal for a collection API in glib
Hi, Here are some alternate ideas, just brainstorming: 1) have an iterator concept in gobject-introspection and map from GList etc. in g-i. So g-i would allow you to invoke a method that returns a list, and get an iterator back. If I were doing this in gobject-introspection I'd tend to make the base API use a stack-allocated lightweight iterator similar to GtkTreeIter/GtkTextIter, and then bindings that wanted to could write generic code to wrap that kind of lightweight iterator in a GObject. Any language binding not using g-i has nothing to stand on if they whine about manual work - they need to a) port to / help with g-i and then b) we'll talk. It would be possible to generically auto-create a GObject-based iterator like yours, using this g-i feature. 2) Another idea would be an equivalent to registering boxed types: g_iterator_type_register_static(const char *name, GBoxedCopyFunc boxed_copy, GBoxedFreeFunc boxed_free, GIteratorNextFunc iterator_next, GIteratorGetFunc iterator_get); This would allow language bindings to generically manipulate custom iterator types like TextIter and TreeIter, without making things a pain in C and while keeping things lightweight. And without redoing/breaking TreeModelIter and TextIter and all the other existing examples you mention. Why explore alternate ideas? Some downsides to GIterator-as-gobject: * GObject is pretty heavyweight for something like this, and moreover right now libglib doesn't depend on libgobject * the need to unref the iterator is onerous for C programmers using iterators * the need to subclass a GObject is onerous for C programmers creating iterators * as Owen mentioned long ago when this was already discussed, we'd end up duplicating bunches of APIs just to make them use iterators instead of whatever they use now - this is both bloat and confusing. It would not be realistic to ever deprecate walking GList etc. - the iterator replacement is much less convenient, and there's way, way, way too much code using GList already. You can't deprecate something that touches this much code. Havoc ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Proposal for a collection API in glib
On Thu, 2008-07-17 at 14:22 -0400, Jamie McCracken wrote: On Thu, 2008-07-17 at 13:37 -0400, Havoc Pennington wrote: As philip's proposal centres around easier bindings this would only affect public API dealing with licts/collections so all of the above will probably have negligible impact. Exactly (I agree). GList would still be around for internal usage or where performance matters. The onus would still be on devs to make their api more binding friendly by using iterators so I feel its important for them to have that choice GList for performance?! :-) Not for the things the vast majority of GLib based library developers are using it for! And if GList must be used in a high performance situation, the kernel's list.h is better designed anyway: the item's data is in the same allocation as the next/prev ptrs, instead of having an allocation for the data and another allocation for the list node. Looking at how GList is used all over our project's code nearly always makes me conclude that most people who used a GList probably wanted a GPtrArray instead. Its realloc overhead is usually not expensive at all. There are specific uses for doubly linked lists, of course. For UI rich applications (where you usually want things like sorting and index based accessing your collections) I don't think GList is very useful. For index-based access and sorting it's even a performance 'mistake'. The problem is, I think, that GList's API is more easy than GPTrArray's. Which validates my POV that: - The simple, most common use cases, must be easy - The complex things must (just) be possible If a complex thing becomes even more complex caused by wanting to make a common use case even a little bit more simple, then don't even think about it and DO make the complex thing even more complex .. indeed. Just make a wiki page on Live explaining how to do the complex thing. The developers who feel brave (and have some competence) will figure it out anyway. But don't bother app developers, who spend 90% of their time codifying common use cases, with complexities. -- Philip Van Hoof, freelance software developer home: me at pvanhoof dot be gnome: pvanhoof at gnome dot org http://pvanhoof.be/blog http://codeminded.be ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Proposal for a collection API in glib
Am Donnerstag, den 17.07.2008, 14:23 -0400 schrieb Havoc Pennington: Hi, On Thu, Jul 17, 2008 at 2:06 PM, Philip Van Hoof [EMAIL PROTECTED] wrote: You could make a GLib.Iterator that uses gobject-introspection, but I don't think you want to make gobject-introspection the one thing everybody who wants to expose collections in his API has to use and learn. I didn't mean that - I meant if you exposed collections you'd use GList or whatever, and g-i would know that it was a GList of Foo, and g-i would generate an iterator around the list based on that. Then users of the g-i API for language bindings would see only the iterator. Well, I am doing some refactoring right now and during this process it would be quite helpful if we'd have something better than GList: It would be really helpful if our GLists would express its element type. Maybe we can figure out how to do this in a sane way for GTK3? Ciao, Mathias -- Mathias Hasselmann [EMAIL PROTECTED] Openismus GmbH: http://www.openismus.com/ Personal Site: http://taschenorakel.de/ signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Proposal for a collection API in glib
2008/7/17 Mikkel Kamstrup Erlandsen [EMAIL PROTECTED]: 2008/7/17 Havoc Pennington [EMAIL PROTECTED]: Hi, Here are some alternate ideas, just brainstorming: 1) have an iterator concept in gobject-introspection and map from GList etc. in g-i. So g-i would allow you to invoke a method that returns a list, and get an iterator back. If I were doing this in gobject-introspection I'd tend to make the base API use a stack-allocated lightweight iterator similar to GtkTreeIter/GtkTextIter, and then bindings that wanted to could write generic code to wrap that kind of lightweight iterator in a GObject. Any language binding not using g-i has nothing to stand on if they whine about manual work - they need to a) port to / help with g-i and then b) we'll talk. It would be possible to generically auto-create a GObject-based iterator like yours, using this g-i feature. I am not sure I fully understand your proposal here. It would cater most for the bindings writers and not the C application developers, right? Also, if one where to use such a construct in C we would need a new external tool glib-gen-iterators. Please say it ain't so ;-) 2) Another idea would be an equivalent to registering boxed types: g_iterator_type_register_static(const char *name, GBoxedCopyFunc boxed_copy, GBoxedFreeFunc boxed_free, GIteratorNextFunc iterator_next, GIteratorGetFunc iterator_get); This would allow language bindings to generically manipulate custom iterator types like TextIter and TreeIter, without making things a pain in C and while keeping things lightweight. And without redoing/breaking TreeModelIter and TextIter and all the other existing examples you mention. This idea is probably the one I like the most (also over Philip's original proposal), it has some problems though. The GBoxed implementation does a lookup based on the GType supplied to g_boxed_{copy,free}() to get the vtable for the implementation. This could mean that g_iter_next(GType type, gpointer iter) would have some overhead which might not be desirable for something we want to be as snappy as possible. This might be alleviated a little (or worsened) if we cache the vtable of the last call to g_iter_next() in a local static variable. Not sure. The same problem applies if we want to model a GCollection this way. And here is a full proposal using the GBoxed technique (no, not the drunken uncle technique, sorry): http://live.gnome.org/MikkelKamstrup/GCollection If one took of in gobject/gboxed.c it should not be that hard to do. The work will probably lie in registering the existing collections as GIterable!-- --s. Cheers, Mikkel ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list