On Sep 5, 2014, at 2:46 AM, Geert Janssens <janssens-ge...@telenet.be> wrote:

> This topic was lightly touched in the doxygen/design thread currently active 
> on this list. I 
> thought it to be important enough to start a new thread on it.
> 
> Historically, gnucash as acquired a lot of namespaces (think function and 
> type prefixes) for 
> various reasons.
> 
> Some examples:
> * The oldest engine code uses xaccXYZ because gnucash started as a 
> continuation of the xacc 
> project (xacc for X Accounting by the way).
> * More recent engine code and most of the gui related code usually use gnc_ 
> copying the gtk 
> name space standards.
> * The qof library introduced qof_ because it was meant to become a separate 
> library at one 
> point in time.
> 
> Types are different still:
> * The oldest engine code doesn't use prefixes at all ("Split", 
> "Transaction",...)
> * More recent engine code uses Gnc or GNC, gui code is mostly into Gnc as 
> well.
> 
> And so on...
> 
> 
> The problem with this is that it makes the gnucash "framework" hard to learn. 
> It's not possible 
> to learn by similarity like it is in strongly namespaced frameworks such as 
> gtk, qt or boost. 
> Those frameworks have a logic to their name structure, so if you know one 
> part of the 
> framework you can already imagine what other functions and types in the 
> framework will be 
> called. That speeds up adoption a lot.
> 
> The same goes for file names, and especially header files. If there is a 
> recognizable logic in the 
> names of the header files, that makes it much faster to learn how to use the 
> framework.
> 
> Now since one of our current design goals is to port our engine code to C++, 
> that means we will 
> more or less rewrite every single function and type in it. That would IMO be 
> a good time to think 
> about how we want to structure the new classes name-wise and come to a more 
> coherent set 
> of names.
> 
> I have seen how some frameworks do it and clearly there are different ways. I 
> don't know 
> however whether there exist formal theories or guidelines that we could use 
> to formulate our 
> own naming rules.
> 
> For example, in recent years I have worked mostly with the GLib/Gtk 
> frameworks. Some of their 
> naming rules include
> * Object names are prefixed with G (for GLib) and Gtk (for Gtk). The names 
> are camel-cased.
> * Function names are prefixed with g_ (for GLib) and gtk_ (for Gtk). An the 
> names use _ to 
> separate words.
> 
> If we had planned to continue to use GLib/Gtk in the long term, I would have 
> proposed to use a 
> similar naming scheme, using our own Gnc/gnc_ prefixes. That would allow 
> newcomers to 
> leverage the muscle memory built up on GLib and Gtk naming.
> 
> The plan is however to move away from those in favour of C++ based 
> alternatives, so I think it 
> would make more sense to look for examples of namespacing in the C++ world. 
> That world is 
> unknown to me unfortunately so...
> 
> Suggestions anyone ?

C++ actually has a higher level of code scope called namespaces. In behavior 
it's similar to Python's module naming scheme, and the idea is that it helps to 
prevent name collisions. I'll leave it to your favorite C++ tutorial/reference 
to explain further.

Gnome, being dedicated to creating a pretend C++ with C macros, doesn't have 
the option of enforcing actual namespaces, so they adopted a naming convention 
and called part of it namespace. Macros being inherently brittle, anything that 
doesn't comply with that naming convention breaks, though not at compile time 
and not with a message. There's another reason for the Gnome naming convention: 
In order to preserve using normal C semantics and because C can't fake the 
first function argument, all function names must begin with the class name and 
the first argument must be cast appropriately if it's a derived class. While 
there's support for vtables (defined in the class_init function), it's not 
often used outside of Gdk because few C programmers understand it.

We're freed from that with C++. There's no need to stick "GNC" (in any case 
variation you like) in front of class names, and member functions are 
automatically recognized and the object parameter taken care of, so instead of
  Account *acct = xaccMallocAccount (book);
  xaccAccountBeginEdit (acct);
  //Do stuff
  xaccAccountCommitEdit (acct);

We'll say 
   Account* acct = new Account (book);
   acct->beginEdit (); //or acct->begin_edit (); if we decide we like 
underscore better than camel case
   //Do stuff
   acct->commitEdit ();

Since we want to make the API useful outside of GnuCash we should declare a 
namespace to wrap everything in, maybe Gnc. That way an application that wants 
to extend our Account class could still call their child class Account, like so:
  class Account : public Gnc::Account;
We'd stick
  using namespace Gnc;
in all of our implementation files so we don't have to write
  Gnc::Account* acct = new Gnc::Account (book);

So the question becomes:
* Is Gnc OK for the namespace name?
* Do we want to use camel-case or underscore-separated function and variable 
names?

N.B. The C++ code above mirrors the old C code to emphasize the different 
naming and calling conventions. The actual C++ code will be somewhat different.

Regards,
John Ralls


_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to