X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/a42893dda5f4dd2b89fbfe4e497da261159225ca..388ab3827ab7c584c30723f5044c2a38cf6fe55d:/doc/concepts.tex

diff --git a/doc/concepts.tex b/doc/concepts.tex
index 8151014..b4e80ca 100644
--- a/doc/concepts.tex
+++ b/doc/concepts.tex
@@ -704,7 +704,7 @@ the platform's strictest alignment requirement applies.
 The following simple function correctly allocates and returns space for an
 instance of a class given a pointer to its class object @<cls>.
 \begin{prog}
-  void *allocate_instance(const SodClass *cls) \\ \ind
+  void *allocate_instance(const SodClass *cls)                  \\ \ind
     \{ return malloc(cls@->cls.initsz); \}
 \end{prog}
 
@@ -728,7 +728,7 @@ of any use unless they've been written specifically for the purpose.
 The following simple function imprints storage at address @<p> as an instance
 of a class, given a pointer to its class object @<cls>.
 \begin{prog}
-  void imprint_instance(const SodClass *cls, void *p) \\ \ind
+  void imprint_instance(const SodClass *cls, void *p)           \\ \ind
     \{ cls@->cls.imprint(p); \}
 \end{prog}
 
@@ -745,11 +745,10 @@ 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, and to invoke each superclass's initialization fragments.  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 instance's slots, as described below, and to invoke each superclass's
+initialization fragments.  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.
 
 Slots are initialized in a well-defined order.
 \begin{itemize}
@@ -771,19 +770,53 @@ definition.  It is possible for an initialization fragment to use @|return|
 or @|goto| for special control-flow effects, but this is not likely to be a
 good idea.
 
-Note that an initialization fragment defined in a class is copied literally
-into each subclass's initialization method.  This is fine for simple cases
-but wasteful if the initialization logic is complicated.  More complex
-initialization behaviour should be added either by having an initialization
-fragments call functions (necessarily with external linkage), or by defining
-@|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.
+The @|init| message accepts keyword arguments
+(\xref{sec:concepts.methods.keywords}).  The set of acceptable keywords is
+determined by the applicable methods as usual, but also by the
+\emph{initargs} defined by the receiving instance's class and its
+superclasses, which are made available to slot initializers and
+initialization fragments.
+
+There are two kinds of initarg definitions.  \emph{User initargs} are defined
+by an explicit @|initarg| item appearing in a class definition: the item
+defines a name, type, and (optionally) a default value for the initarg.
+\emph{Slot initargs} are defined by attaching an @|initarg| property to a
+slot or slot initializer item: the property's determines the initarg's name,
+while the type is taken from the underlying slot type; slot initargs do not
+have default values.  Both kinds define a \emph{direct initarg} for the
+containing class.
+
+Initargs are inherited.  The \emph{applicable} direct initargs for an @|init|
+effective method are those defined by the receiving object's class, and all
+of its superclasses.  Applicable direct initargs with the same name are
+merged to form \emph{effective initargs}.  An error is reported if two
+applicable direct initargs have the same name but different types.  The
+default value of an effective initarg is taken from the most specific
+applicable direct initarg which specifies a defalt value; if no applicable
+direct initarg specifies a default value then the effective initarg has no
+default.
+
+All initarg values are made available at runtime to user code --
+initialization fragments and slot initializer expressions -- through local
+variables and a @|suppliedp| structure, as in a direct method
+(\xref{sec:concepts.methods.keywords}).  Furthermore, slot initarg
+definitions influence the initialization of slots.
+
+The process for deciding how to initialize a particular slot works as
+follows.
+\begin{enumerate}
+\item If there are any slot initargs defined on the slot, or any of its slot
+  initializers, \emph{and} the sender supplied a value for one or more of the
+  corresponding effective initargs, then the value of the most specific slot
+  initarg is stored in the slot.
+\item Otherwise, if there are any slot initializers defined which include an
+  initializer expression, then the initializer expression from the most
+  specific such slot initializer is evaluated and its value stored in the
+  slot.
+\item Otherwise, the slot is left uninitialized.
+\end{enumerate}
+Note that the default values (if any) of effective initargs do \emph{not}
+affect this procedure.
 
 
 \subsection{Destruction}
@@ -820,16 +853,16 @@ program may be in an inconsistent state and should not continue.
 This simple protocol can be used, for example, to implement a reference
 counting system, as follows.
 \begin{prog}
-  [nick = ref] \\
-  class ReferenceCountedObject \{ \\ \ind
-    unsigned nref = 1; \\-
-    void inc() \{ me@->ref.nref++; \} \\-
-    [role = around] \\
-    int obj.teardown() \\
-    \{ \\ \ind
-      if (--\,--me@->ref.nref) return (1); \\
-      else return (CALL_NEXT_METHOD); \- \\
-    \} \- \\
+  [nick = ref]                                                  \\
+  class ReferenceCountedObject \{                               \\ \ind
+    unsigned nref = 1;                                          \\-
+    void inc() \{ me@->ref.nref++; \}                           \\-
+    [role = around]                                             \\
+    int obj.teardown()                                          \\
+    \{                                                          \\ \ind
+      if (--\,--me@->ref.nref) return (1);                      \\
+      else return (CALL_NEXT_METHOD);                         \-\\
+    \}                                                        \-\\
   \}
 \end{prog}
 
