X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/54fa3df9560fe739b5fe20ca561749092cef0fd5..a142609c5dc2a7c3df02497235881beaf47088bf:/doc/concepts.tex

diff --git a/doc/concepts.tex b/doc/concepts.tex
index 1663939..39cccb8 100644
--- a/doc/concepts.tex
+++ b/doc/concepts.tex
@@ -388,7 +388,8 @@ Keyword arguments can be provided in three ways.
 
 Keyword arguments are provided as a general feature for C functions.
 However, Sod has special support for messages which accept keyword arguments
-(\xref{sec:concepts.methods.keywords}).
+(\xref{sec:concepts.methods.keywords}); and they play an essential role in
+the instance construction protocol (\xref{sec:concepts.lifecycle.birth}).
 
 %%%--------------------------------------------------------------------------
 \section{Messages and methods} \label{sec:concepts.methods}
@@ -654,8 +655,10 @@ Construction of a new instance of a class involves three steps.
   necessary.
 \end{enumerate}
 The \descref{SOD_DECL}[macro]{mac} handles constructing instances with
-automatic storage duration (`on the stack').  Currently, there is no built-in
-support for constructing dynamically-allocated instances.
+automatic storage duration (`on the stack').  Programmers can add support for
+other allocation strategies by using the \descref{SOD_INIT}[macro]{mac} and
+the \descref{sod_init}{fun} and \descref{sod_initv}{fun} functions, which
+package up imprinting and initialization.
 
 \subsubsection{Allocation}
 Instances of most classes (specifically including those classes defined by
@@ -724,31 +727,42 @@ Details of initialization are necessarily class-specific, but typically it
 involves setting the instance's slots to appropriate values, and possibly
 linking it into some larger data structure to keep track of it.
 
-Classes can declare initial values for their slots.  A class object's @|init|
-slot points to a function which will establish the appropriate initial values
-for a new instance's slots.  Slots are not initialized in any particularly
-useful order.
-
-The provided initialization protocol is extremely simplistic; most notably,
-it's not possible to pass parameters into the initialization process.
-Classes which have more complex requirements will need to define and
-implement their own additional (or alternative) protocols.
+Initialization is performed by sending the imprinted instance an @|init|
+message, defined by the @|SodObject| class.  This message uses a nonstandard
+method combination which works like the standard combination, except that the
+\emph{default behaviour}, if there is no overriding method, is to initialize
+the instance's slots using the initializers defined in the class and its
+superclasses.  This default behaviour may be invoked multiple times if some
+method calls on its @|next_method| more than once, unless some other method
+takes steps to prevent this.
+
+The recommended way to add new initialization behaviour is to define @|after|
+methods on the @|init| message.  These will be run after the slot
+initializers have been applied, in reverse precedence order.
+
+Initialization is \emph{parametrized}, so the caller may select from a space
+of possible initial states for the new instance, or to inform the new
+instance about some other objects known to the caller.  Specifically, the
+@|init| message accepts keyword arguments (\xref{sec:concepts.keywords})
+which can be defined and used by methods defined on it.
 
 \subsubsection{Example}
 The following is a simple function, with syntactic-sugar macro, which
 allocate storage for an instance of a class, imprints and initializes it, and
 returns a pointer to the new instance.
 \begin{prog}
-  void *make_instance(const SodClass *c) \\
+  void *make_instance(const SodClass *c, @|\dots|) \\
   \{ \\ \ind
+    va_list ap;
     void *p = malloc(c@->cls.initsz); \\
     if (!p) return (0); \\
-    c@->cls.imprint(p); \\
-    c@->cls.init(p); \\
+    va_start(ap, c); \\
+    sod_initv(c, p, ap); \\
+    va_end(ap); \\
     return (p); \- \\
   \}
   \\+
-  \#define MAKE(cls) (cls *)make_instance(cls\#\#__class)
+  \#define MAKE(cls, keys) (cls *)make_instance(cls\#\#__class, keys)
 \end{prog}
 
 
