crategus / cl-cffi-gtk

cl-cffi-gtk is a Lisp binding to the GTK+ 3 library.
http://www.crategus.com/books/cl-cffi-gtk
146 stars 33 forks source link

Gah, I just don't understand the design choices... #70

Open stacksmith opened 4 years ago

stacksmith commented 4 years ago

OK, this is driving me crazy. Either I am insane (which is possible), or most design decisions in cl-cffi-gtk are suboptimal. I've been trying to use these bindings for a few years now. Please take it as a constructive criticism of a frustrated user, and if you can, please document your reasoning and some details of the low-level implementation.

I already complained about gtk-text-iter being an opaque gobject. This is a good example, however: an iter is a useless blob. There is nothing you can do with it - except pass it around as a foreign pointer! Converting it back and forth as a lisp object is entirely a waste of everyone's time and resources. Instead of implementing as a simple foreign object, it is constructed by copying something a few times, managed as a lisp object, converted and typechecked every time it's used as a parameter (and due to bug referenced in issue 69, every binding that uses one creates at least one new type for no reason)... god knows if it's ever destroyed (I can't figure out how or where). SBCL cannot create temporary iters on the stack, as is intended by gtk.

Now consider every g-object-based object here. It's nice to keep a corresponding lisp object to hang callbacks and such. But every gtk call that takes one of these as a parameter incurs a translation penalty, and pointless typechecking. On my SBCL system, every cl-cffi-gtk function binding is close to 1K of code. Not to mention that every g-object parameter is a new type (see issue 69).

These are C bindings. They should be reasonably small. Passing pointers instead of g-objects to most functions is sufficient - there is nothing gained from translating a Lisp object.

I my ideal world, there should be a clean layer of bindings without any hidden translation or error-checking - perhaps prefixed by %, and a layer above with typechecking, translation, and temporary objects that are sometimes required. And a third layer for a lispier interface with optional arguments. Instead we have a mess - a function that seems to be a gtk binding is sometimes a defcfun, sometimes a g-object slot, and other times a really complicated thing that makes all kinds of assumptions and calls other bindings!

Lifecycle management and reference-counting is taken care of on the C side. I have no idea what cl-cffi-gtk does, but it seems to be something complicated with hashtables. I have no idea if it works (I could not track down any iters beign destroyed - how do you do that?).

I don't know why things like gtk-text-buffer and gtk-text-view implement some functions as slot accessors. Do these slots marshall data across to corresponding foreign objects? Why do that if there are C bindings to get and set these? Some are not even settable etc.

In short, the more I use cl-cffi-gtk, the more confused I get about the internals. While it works, and the demos work, I get into some really weird issues every time I try to do something useful, and resource utilization seems problematic on smaller systems like raspberry-pi...