Re: Proposal for a collection API in glib

2008-07-18 Thread Jürg Billeter
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

2008-07-18 Thread Sebastian Rittau
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

2008-07-17 Thread Havoc Pennington
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

2008-07-17 Thread Philip Van Hoof
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

2008-07-17 Thread Mathias Hasselmann
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-07-17 Thread Mikkel Kamstrup Erlandsen
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