C with traits - or how I learned to stop worrying and love something resembling multiple inheritance.


This is an experiment in writing a dynamically configurable type system in C
where traits/capabilities can be added and removed on instances at runtime.

Encapsulation within an instance is done by developing orthogonal modules of
data and logic called traits.  Traits can be added to an instantiated on
demand by the traits methods, providing a highly dynamic programming

The core traits are demand driven, and are added as needed when the relevant
API methods like ref_inc or set_float or listening to particular message. This
ensures that the size of each instance remains low.

The core traits in Oi:

TRAIT      handles memory management and life cycle management of the other
           capabilities/traits on an object.

LIST       provides a container API and storage of pointers, allows to register
           a destruction function when items are removed.

REF        provides reference counting mechanism that is added implicitly when
           @ref:inc() is called. Calling @ref:dec() without having a reference
           causes direct destruction - without instantiating the ref trait.

PROPERTY   provides implictly created storage for key/value pairs of
           floats,ints, strings, pointers and oi instances.

MESSAGE    Signalling mechanism - capabilities can listen for messages emitted
           on the instance itself or on other instances. Use of messages permits
           a form of polymorphism by swapping out capabilities responding
           to given messages.

OWN        Ownership tracking, to make working with manual reference counting
           easier. The Own trait tracks destruction of traits/instances
           and can disconnect message handlers or unref instances that an
           owner-ship is held for. Adding per-trait malloc/free; that is
           also tracked this way would give talloc like functionality as well.

Oi exist both as a C level API, that provides a traditional OOP with C like
calling semantic; passing the instance as the first argument. And as an
extension to C that transforms to the aforementioned C API; with a 1:1
matching for the lines - allowing it to be used as a gcc front-end providing
warnings with correct line numbers.