Andre Pang on why OO sweetness is not just in the syntactic sugar
Jeff Waugh <[email protected]> Sun, 8 Feb 2004 18:33:22 +1100
| Newsgroups | gmane.org.user-groups.slug.pearls |
|---|---|
| Message-ID | <20040208073321.GA1071@lazarus> |
----- Forwarded message from [email protected] ----- On 08/02/2004, at 1:56 AM, invisible ink wrote: > What's the fundamental difference between learning a language and learning > a library? A lot of GNOME hackers joke about coding in glib, which happens > to be remarkably familiar if you've coded in C before. Firstly, there are all the reasons which are mentioned on the gtkmm FAQ <http://www.gtkmm.org/gtkmm2/docs/FAQ/html/index.html#id2479521>: Why use gtkmm instead of GTK+? 1. gtkmm allows you to write code using normal C++ techniques such as encapsulation, derivation, and polymorphism. As a C++ programmer you probably already realise that this leads to clearer and better organised code. 2. gtkmm is more type-safe, so the compiler can detect errors that would only be detected at run time when using C. This use of specific types also makes the API clearer because you can see what types should be used just by looking at a method's declaration. 3. Inheritance can be used to derive new widgets. The derivation of new widgets in GTK+ C code is so complicated and error prone that almost no C coders do it. As a C++ developer you know that derivation is an essential Object Orientated technique. 4. Member instances can be used, simplifying memory management. All GTK+ C widgets are dealt with by use of pointers. As a C++ coder you know that pointers should be avoided where possible. 5. Less code. The GTK+ C object model uses prefixed function names and cast macros. For instance: gtk_button_set_text(GTK_BUTTON(button), "sometext"); gtkmm C++ code is shorter and clearer. For instance: button.set_text("sometext"); 6. There's no need to worry about GTK+'s inconsistent reference-counting policy. If you have support for objects at the language level, you don't have to relearn a new object system when you go work on another project. You know that "object.foo()" means "invoke method foo on object". You even know that the _correct_ foo will get called for that object if you use late binding. I'm having a look at some of the code from the "Glib Object System" tutorial now[1], and the amount of hoops you have to jump through just to implement late binding (i.e. C++ virtual methods, or completely normal methods in Java/Python) is just plain silly. Please tell me how this code: static void maman_bar_real_do_action_two (MamanBar *self, /* parameters */) { /* Default implementation for the virtual method. */ } static void maman_bar_class_init (BarClass *klass) { /* pure virtual method: mandates implementation in children. */ klass->do_action_one = NULL; /* merely virtual method. */ klass->do_action_two = maman_bar_real_do_action_two; } void maman_bar_do_action_one (MamanBar *self, /* parameters */) { MAMAN_BAR_GET_CLASS (self)->do_action_one (self, /* parameters */); } void maman_bar_do_action_two (MamanBar *self, /* parameters */) { MAMAN_BAR_GET_CLASS (self)->do_action_two (self, /* parameters */); } is easier than: class MamanBar { virtual void DoActionOne (parameters) = 0; virtual void DoActionTwo (parameters); } void MamanBar::DoActionTwo (parameters) { /* Default implementation for the virtual method. */ } Besides this, I haven't even included the maman-bar.h file for the C example, which will probably make it a good 20-50 lines longer. You also have to make sure that any class which contains one or more virtual methods must have the correct code, you have to write the vtables yourself, and you have to use a whole bunch of glib macros to work. So you have more maintenance problems with the C code, it looks more fugly, it's less type-safe, you have to learn far more about the implementation details of how glib's gobjects work just use use it, and you have to write plenty more code to do the same thing. That's just one example, too. Check out <http://le-hacker.org/papers/gobject/ch05s02.html> to see how to define a Java-style interface with glib. I'd paste the code in here, but it'd make this email about 4x longer. So, check out that ridiculously long 200 lines of code or whatever, and tell me how that's easier (and clearer, and more maintainable) than: class MamanIbaz { virtual void maman_ibaz_do_action () = 0; } class MamanBaz : public MamanIbaz { virtual void maman_ibaz_do_action () { /* Implementation goes here */ } } And, of course, you have to learn a whole new object library if another C projects decides that glib's object model sux0rz or whatever. I'll go and bang my head into a wall some more now, because I like the bleeding! 1. http://le-hacker.org/papers/gobject/ch05.html#howto-gobject -- % Andre Pang : trust.in.love.to.save ----- End forwarded message ----- -- SLUG Pearls http://lists.slug.org.au/listinfo/pearls