[RFC] A differnt options system

Derek Atkins warlord at MIT.EDU
Wed Feb 16 14:30:27 EST 2005


Let me try to provide feedback based on your actual code comments
in the header.  I didn't look at the actual implementation because,
frankly, how you implement it is much less important that how it is
used..  At least at this stage of the game.

There'll be lots of snipping of your header; I don't plan to mark all
of those snips.

Chris Shoemaker <c.shoemaker at cox.net> writes:

>  * The "Options Triad":
>  *
>  *    I call GNCOptionWin, GncOptionDB, and options.scm the "options
>  * triad."  GNCOptionWin is a dialog wrapper for GncOptionDB, which is
>  * the C interface to an options system that is written in Scheme (see
>  * src/app-utils/options.scm).  Unfortunately, there is very little
>  * documentation for GNCOptionWin and GncOptionDB.  (Actually, there's
>  * just a few comments in the code.  Maybe some of the comments here
>  * will grow into some documentation that can then be moved to
>  * GNCOptionWin.)  The underlying options system is well-documented in
>  * gnucash-design.info.

More documentation is always a good thing.

>  *    The options triad can be a bit confusing, but a few tips can
>  * ease the understanding.  The options system is actually much more
>  * than just a way to display and modify option values.  It is also
>  * intended to be the primary storage container for those option
>  * values.  That means that the option values "live" somewhere in the
>  * Scheme interpreter.  On the C side of things, GnuCash has access
>  * (getting and setting) to the option values though guile bindings.
>  * As a consequence, using the options system for new options
>  * (I'm not talking about new option types.) requires at
>  * least a bit of scheme coding.

"a bit of scheme coding" isn't being quite accurate.  It's a miniscule
amount of scheme coding, and it's coding that is well documented (by
your own admission).  So, reading between the lines it doesn't sound
like this is a complaint...  Except for the fact that it's scheme
instead of some other "language" to define the set of options.

>  *    A typical scenario might roughly go like this: (Lots of details
>  * are left out here - this is only intended as a conceptual outline.)

This is a great example (that I removed here).  This description
would be great for the docs.  It truly shows how easy it is to
use the triad.

>  * But... there are cases where everything doesn't work perfectly, and
>  * there are cases where things work, but painfully:
>  *
>  * 1) GncOptionWin's option layout is quite flat.  Linear layout order
>  * can be specified in the scheme option definition, but that's it.

Well, not quite.  You supply a page and a layout order on the page.
True, you can't put options next to each other, but is that
necessarily a bad thing?  Agreed, the options system is not meant to
be a generic dialog builder.  Is that really a problem?

>  * 2) Some option types are buggy.

Oh?  Which ones?  If there are buggy option types that should
definitely be fixed!  This is the first I've heard of buggy options.

>  * 3) Not all GnuCash values have option types, and new GnuCash values
>  * that you invent for sure won't, (unless you make them).  The
>  * options triad supports a fairly complete set of simple option
>  * types.  This is good because extending the underlying options
>  * system to support new option types requires a _deep_ understanding
>  * of Scheme, Guile, Gtk+/Gnome, and existing GnuCash users (Here and
>  * henceforth, by "user" I usually mean code that uses some API.) of
>  * the option system (currently, Reports options, business options and
>  * top-level GnuCash preferences).

What do you mean by "gnucash values"?  Do you mean "data type with a
corresponding option type"?  As I said in a previous email, the system
is designed in an extensive manner; Option types have only been added
as necessary.  For example, see the business-options code for an
example of how I added options for various business objects.

Historically we haven't had a need for options of every gnucash data
type, so yes, we need to add more if you need more.  That's not
necessarily a reason to scrap the existing infrastructure.

>  * 4) Reusing groups of options isn't easy.  There's probably some way
>  * to define the option list as a concatenation of smaller option
>  * lists, but I don't think there are any examples of this.

It's very easy, and there are examples.  See gnc:options-add-account-selection!
in src/reports/report-system/options-utilities.scm for one example.
Basically you write a scheme procedure that defines the block of
options you want to create.

>  * 5) If you're storing option values in C as enumerated types
>  * (multi-choice option type), you'll need to specify the enumeration
>  * in C and in Scheme, and keep them in sync.

That's not quite true.  Yes, you need to define the list in the option
definition in scheme, but what those values mean is up to you later.
You could define them in one place and export to the other, or you can
define in two places and keep them in sync.  That's just a matter of
programming.  Can you show me an example where there's a list that
needs to be kept in sync between scheme and C?

>  * 6) Your options are displayed in a GtkNotebook page.  I hope that's
>  * what you want, because that's the way it is.

And why is this a problem?  It's just a bunch of options.  If you have
multiple pages how ELSE would display them other than a GtkNotebook?
What other multi-page dialog method would you use?  A Druid?

>  *    Of course these problems are probably solvable by improving
>  * GNCOptionWin and GncOptionDB and the Scheme options system.  But,
>  * that's not easy.  (Feel free to prove otherwise.)  The fact is, the
>  * complexity of the "options triad" is beyond the comprehension of an
>  * averagely bright high-school student.  And outside of its
>  * author(s), it seems there are very few who understand its depths
>  * (GncPropWin author excluded).

* raises his hand *

Take a look at the business options.  It adds a bunch of new option
types.  It's pretty darn easy to do.  Granted, it depends on the data
type you want to define an option, but adding new options is not a lot
of code and is not something that happens very often.  So it seems
like an awful lot of work to optimize for adding new options rather
than optimizing for using the options database.

>  *     That said, there are cases where the options triad is clearly
>  * what you need.  For example: 
>  *
>  * 1) You need access to the option values from Scheme, or 

We do.  The reports.

>  * 2) You need the option values to have a life-time longer than that
>  * of any C-side object.

Why would you NOT want to store your options?  What's the point of
making options if you don't store them for later?

>  *     Furthermore, there are several qualities that make the options
>  * triad appealing even when the above requirements are absent:
>  * 
>  * 1) The concept of "sections" is useful for organizing large sets of
>  * options.
>  *
>  * 2) The GncOptionDB API hides the GTK+ details of setting and
>  * getting values to/from the widgets.
>  *
>  * 3) The scheme option type definitions hide the GTK+ details.
>  *
>  * 4) The combination of 2) and 3) above mean that, conceivably, a
>  * programmer could set/get option values without even knowing about
>  * GTK+, (e.g. GtkEntry, or GtkSpinButton).  More realistically, it
>  * means a programmer spends less time looking up things like
>  * gtk_entry_set_text() and gtk_spin_button_get_value() in the GTK+
>  * API Reference.

Yes, these are all good things!  IMHO these are features that should
be retained.

>  * XML vs. Scheme:
>  *
>  *    Specifically, GncPropWin expects the option list and layout to
>  * be defined in XML instead of Scheme.  Given GnuCash's extensive
>  * investment in Scheme, this may prove controversial.  
>  *
>  *    Scheme has its pros and cons. <shameless grin> Scheme is a real
>  * programming language, so it has computational power and
>  * expressiveness that XML will never have.  OTOH, the task of
>  * setting/getting option values (which is essentially a programming
>  * language task and must be defined in whatever programming language
>  * you're working in) is distinct from the task of enumerating the
>  * list of options and their layout (which is not a computational task
>  * but a descriptive task).

* shrugs * I don't really see this as a major issue, one way or the
other.  Whether the options are defined in scheme or C seems to be a
no-op tradeoff in my book.  So what if scheme is a full language and
guile isn't?

>  * No long-term option value storage:
>  *
>  *    Another significant design difference is the option value
>  * storage.  GncPropWin is meant to be considered just a GUI tool,
>  * like a dialog window, and doesn't provide any long-term (longer
>  * than the dialog's lifetime) option value storage.  So, you must set
>  * the option values every time you create the GncPropWin and get the
>  * option values before the GncPropWin is destroyed.  (Which you have
>  * to do anyway for the options triad if you're setting object
>  * property values for C objects that don't have Scheme storage.)

I think this is a BAD THING.  What's the point of making options if
you can't save them somewhere?

>  *    Even though GncPropWin is less ambitious than the option triad
>  * in that respect, I consider this a design feature, not a
>  * short-coming, because it decouples value storage from the gui.  For
>  * C object properties, this is good because the object will usually
>  * provide their own property value storage as fields in the object's
>  * structure.  For things like top-level program preferences this may
>  * be not-so-good, because option value persistence no longer comes
>  * "automatically".  

The triad has the gui and storage decoupled, too.  But you still need
option storage somewhere.  So in essence you're just redesigning the
triad without knowing that you're doing so!  :)

>  * Composability
>  * 
>  *    To encourage reuse of option groups and their associated GUI
>  * layouts, an options system should support composition of option
>  * groups into larger option groups.  The option triad probably
>  * supports this with regular scheme list operations, but I haven't
>  * seen an example.

It does.  Example above.

>  *    GncPropWin supports composition of option groups.  First,
>  * libglade will support composition through the use of the "custom
>  * widget".  This is very easy.  But, it requires that you create a
>  * composite GtkWidget that derives from some GtkWidget class.

This is a LOT of work for the programmer.  More so than a simple
scheme script to generate a bunch of options.

>  *     Are there any new benefits?  I hope so. :) I hope the chief new
>  * benefit will be maintainability.  GncPropWin is quite a bit simpler
>  * than the options triad, and it could be made even simpler if the
>  * type generic interface was dropped.  It also seems to be more
>  * powerful in terms of supported option types.  Newly invented widget
>  * types are supported automatically, and anything that derives from
>  * GtkWidget can be accessed.

It may be simpler but at the cost of functionality.  :(


       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       warlord at MIT.EDU                        PGP key available

More information about the gnucash-devel mailing list