
Instance Model Programming in C - adamansky
http://slkpg.byethost7.com/instance.html
======
skrebbel
Drifting from the topic, but I never understood this urgent need for so much
_inheritance_ when doing OO, especially when using languages that don't
natively have it, like C and JavaScript.

I really like OO programming (i.e. I'm particularly not one of the functional-
fundamentalist OO-haters here on HN), but as I've grown more experienced, I've
started to use inheritance less and less, and composition more and more. This
is trivially supported in C structs, and you don't need any fancy approach for
it, plus you can do with way less void pointer casting, which means less
runtime errors.

Inheritance is very useful for a small set of relatively complex problems,
such as language parsing or UI frameworks or particle simulations. For many
other problems, including most _applications_ (as opposed to libraries),
however, my experience is that you can do fine without. This holds especially
these days, when many of said complex problems are solved in excellent freely
available open source projects, in nearly any language.

~~~
Someone
That is far from an uncommon idea. The phrase to search for to learn more
about this is "Composition over Inheritance". That leads you to e.g.
[http://en.wikipedia.org/wiki/Composition_over_inheritance](http://en.wikipedia.org/wiki/Composition_over_inheritance)
or, combined with "site: c2.com" to
[http://c2.com/cgi/wiki?CompositionInsteadOfInheritance](http://c2.com/cgi/wiki?CompositionInsteadOfInheritance)
or
[http://c2.com/cgi/wiki?UseCompositionAndInterfacesWithoutCla...](http://c2.com/cgi/wiki?UseCompositionAndInterfacesWithoutClassInheritance).

In some sense, deep inheritance hierarchies were a thing of the 80's, when
inheritance was new (at least, in the mainstream), just like the <blink> tag
was a thing of the '90s (or was that the 00's?). Now, deep hierarchies are a
code smell.

~~~
pjmlp
80's!?!

OO only started to get into the enterprise in the 90's.

------
deletes
Advising anyone trying to make object oriented programing in C to read Object-
Oriented Programing With ANSI-C [0][1]. The book more clearly explains how to
make classes, inheritance, dynamic type checking. Don't follow the instruction
to the letter, but try to understand and write your own version. ( Not for
beginners in C though )

[0]:
[http://www.cs.rit.edu/~ats/books/ooc.pdf](http://www.cs.rit.edu/~ats/books/ooc.pdf)

[1]:
[http://www.cs.rit.edu/~ats/books/ooc-02.01.04.tar.gz](http://www.cs.rit.edu/~ats/books/ooc-02.01.04.tar.gz)
( source code)

------
twoodfin
Much of C++ made more sense to me when I read _Inside the C++ Object Model_ by
Stanley Lippman[1]. It helped me internalize the fact that C++ was originally
implemented as a preprocessor transformation into C (Stroustrup's Cfront).
Thus many C++ mechanisms can be understood as elaborate syntactic sugar.

[1] [http://www.amazon.com/Inside-Object-Model-Stanley-
Lippman/dp...](http://www.amazon.com/Inside-Object-Model-Stanley-
Lippman/dp/0201834545)

~~~
pjmlp
Another good read are _The Annotated C++ Reference Manual_ [1] and _The Design
and Evolution of C++_ [1].

They help understand all design compromises that were done to keep
compatibility with C, which is was part of what brought C++ into the
mainstream, but also the main cause of many of its warts.

[1] [http://www.amazon.com/The-Annotated-C-Reference-
Manual/dp/02...](http://www.amazon.com/The-Annotated-C-Reference-
Manual/dp/0201514591)

[2] [http://www.amazon.com/The-Design-Evolution-Bjarne-
Stroustrup...](http://www.amazon.com/The-Design-Evolution-Bjarne-
Stroustrup/dp/0201543303)

~~~
signa11
> Another good read are The Annotated C++ Reference Manual[1] and The Design
> and Evolution of C++[1].

Annotated C++ Reference Manual as well as D&E is _severely_ dated. Quite a
while back there was some talk of stroustrup co-authoring a revision of the
reference-manual with andrew-koenig, but it never came to fruition...

~~~
pjmlp
That is true, but the point here is to learn how C++ got designed in first
place, you can't update that.

------
jdp
Also worth checking out is _Open, extensible object models_ [0] which brings
prototypal inheritance and message-passing semantics to C. Along with a well-
detailed paper is a very digestible example implementation.

[0]: [http://piumarta.com/software/id-
objmodel/](http://piumarta.com/software/id-objmodel/)

------
gfalcao
This is pretty awesome. GNOME itself is all written in pure C using glib,
which also contains GObject, a beautiful OOP approach for the C programming
language. It has a dynamic type system, supports meta programming...

Very few people know it, but GNOME's GTK interface is fully object oriented,
and BTW when you click a GTK button you are clicking on an instance of the
class GtkButton that inherits from GtkBin which inherits from GtkWidget. it's
a beautiful thing!

Also because GObject is based on a lot of conventions it makes really easy to
generate bindings to other programming languages automatically, so basically
you can write you library in C with OOP approach using GObject, and for free
you get your library easily bound to python, ruby, js or any other language.

[https://developer.gnome.org/gobject/stable/](https://developer.gnome.org/gobject/stable/)

~~~
aninteger
GTK is often used as the example of what not to do when designing interfaces.
A better pure C example would be Wine's implementation of the Win32 API
(specifically take a look at user32.dll). Or the Tk toolkit.

~~~
gfalcao
I disagree that GTK is an example of what NOT to do when designing interfaces.
But anyways I just mentioned GTK as an example of GObject usage, which was my
original point.

GObject is independent of GTK.

Also here is the link for the introspection tool that generates bindings to
other languages:
[https://wiki.gnome.org/action/show/Projects/GObjectIntrospec...](https://wiki.gnome.org/action/show/Projects/GObjectIntrospection?action=show&redirect=GObjectIntrospection)

------
mhogomchungu
The simplest way to do OOP in C is to create modules with opaque handles.

Below shows how i use string and string list "classes" in C.String list
"class" inherits string "class" seamlessly.

[https://github.com/mhogomchungu/zuluCrypt/tree/master/zuluCr...](https://github.com/mhogomchungu/zuluCrypt/tree/master/zuluCrypt-
cli/utility/string)

respective easier to read header files are below:

[https://raw.github.com/mhogomchungu/zuluCrypt/master/zuluCry...](https://raw.github.com/mhogomchungu/zuluCrypt/master/zuluCrypt-
cli/utility/string/String.h)

[https://raw.github.com/mhogomchungu/zuluCrypt/master/zuluCry...](https://raw.github.com/mhogomchungu/zuluCrypt/master/zuluCrypt-
cli/utility/string/StringList.h)

------
andrewcooke
isn't this just the normal approach used in complex c code, as described in,
for example, "c interfaces and implementations" by hanson? a struct with
function pointers and state (plus, optionally, macros to sugar away the
repetition).

i don't understand what's new here. anyone?

~~~
humanrebar
It's similar to most of the complex C code I have been exposed to except for
one thing: namespace prefixes. Almost all reusable C components have to have a
name prefix or risk name collisions with other code.

------
humanrebar
> Except in a database, the data in most programs is a minor player.

I guess that depends on what your definition of "most" is. A large portion of
C code either depends on hardware interfaces or is intended to be optimized.
In both cases, the layout of your memory (data) is extremely important to an
implementation.

One of the biggest criticisms of OOP is that it tends to obscure data layout,
which isn't always an implementation detail. Interestingly, the patterns
described here are subject to the same criticisms.

~~~
brandonbloom
Also from that same paragraph:

> The design and implementation of algorithms constitutes the vast bulk and
> difficulty in developing software.

That's just a crazy statement to me. In my experience, the bulk of developing
software is _anything but_ the design and implementation of algorithms. And
I've worked on some pretty algorithm-heavy projects!

I don't even know where to start rebuking the rest of this article's
discussion of data and I suspect that the author and I simply have
dramatically different definitions of the word.

Regarding your comment:

> One of the biggest criticisms of OOP is that it tends to obscure data
> layout, which isn't always an implementation detail.

I'd argue that OOP obscures data representations more broadly than just data
layout. Encapsulation is great, but it's simply the wrong default:
Representations and the scope of their exposure should be carefully
considered. Further, immutability _greatly reduces_ the value of
encapsulation.

