String handling
---------------

I strongly believe in dealing with strings like you do with complex numbers:
they have two separate parts, and you must know the rules when dealing with
those. 

The parts of a string are its location and its size. Forget what you learned
about zero termination (C) or length prefixing (Pascal).  Those are hacks that
try and brush the size under the carpet, that actually make a lot of common
operations harder.

I am very strongly against encapsulating either strings or complex numbers -
that thing you see in every C++ tutorial. It's not only less efficient for the
CPU, it's also less efficient for any programmer at any place in the learning
curve. 

In these cases the programmer has to learn the basic concepts anyway to be
efficient. Those encapsulations are leaky, that is, not perfect; you need to
know a few bits and pieces of the internals, in addition to the basic concepts,
in order to use them properly.

If the concepts plus the encapsulation's implementation details are harder to
learn than the concepts plus the primitive operations, then encapsulation does
more harm than good.

My role here is to design smart data structures and smart rules governing their
members, so that you don't have to reinvent the wheel. I offer functions to
manipulate them only when they are helpful.

I will definitely *not* try to shield you from a well designed OS API,
protocol, data structure or primitive data type by offering a slightly
transformed, and hence more complex version of it. 


Type naming
-----------

Structures: NAME_T	(pass by reference for efficiency; structures)
Others: name_t		(pass by value)

We never typedef pointers, but always typedef the real thing.


Function naming
---------------

NAME_T *name_new(args)		- allocates structure on heap and calls _init
int name_init(NAME_T *n, args)	- initializes structure, allocate children; 
				  may be called again after calling _done
void name_done(NAME_T *n)	- free memory owned by children; may be 
				  called multiple times safely
void name_del(NAME_T *n)	- 

Rationale: this allows NAME_T structures to be embedded in bigger structures.
Always allocating all substructures as a children on the heap makes cleanup
harder, is more error prone and less efficient.

