+
+\subsection{Messages with keyword arguments}
+\label{sec:concepts.methods.keywords}
+
+A message or a direct method may declare that it accepts keyword arguments.
+A message which accepts keyword arguments is called a \emph{keyword message};
+a direct method which accepts keyword arguments is called a \emph{keyword
+method}.
+
+While method combinations may set their own rules, usually keyword methods
+can only be defined on keyword messages, and all methods defined on a keyword
+message must be keyword methods. The direct methods defined on a keyword
+message may differ in the keywords they accept, both from each other, and
+from the message. If two superclasses of some common class both define
+keyword methods on the same message, and the methods both accept a keyword
+argument with the same name, then these two keyword arguments must also have
+the same type. Different applicable methods may declare keyword arguments
+with the same name but different defaults; see below.
+
+The keyword arguments acceptable in a message sent to an object are the
+keywords listed in the message definition, together with all of the keywords
+accepted by any applicable method. There is no easy way to determine at
+runtime whether a particular keyword is acceptable in a message to a given
+instance.
+
+At runtime, a direct method which accepts one or more keyword arguments
+receives an additional argument named @|suppliedp|. This argument is a small
+structure. For each keyword argument named $k$ accepted by the direct
+method, @|suppliedp| contains a one-bit-wide bitfield member of type
+@|unsigned|, also named $k$. If a keyword argument named $k$ was passed in
+the message, then @|suppliedp.$k$| is one, and $k$ contains the argument
+value; otherwise @|suppliedp.$k$| is zero, and $k$ contains the default value
+from the direct method definition if there was one, or an unspecified value
+otherwise.
+
+%%%--------------------------------------------------------------------------
+\section{The object lifecycle} \label{sec:concepts.lifecycle}
+
+\subsection{Creation} \label{sec:concepts.lifecycle.birth}
+
+Construction of a new instance of a class involves three steps.
+\begin{enumerate}
+\item \emph{Allocation} arranges for there to be storage space for the
+ instance's slots and associated metadata.
+\item \emph{Imprinting} fills in the instance's metadata, associating the
+ instance with its class.
+\item \emph{Initialization} stores appropriate initial values in the
+ instance's slots, and maybe links it into any external data structures as
+ necessary.
+\end{enumerate}
+The \descref{SOD_DECL}[macro]{mac} handles constructing instances with
+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
+Sod itself) can be held in any storage of sufficient size. The in-memory
+layout of an instance of some class~$C$ is described by the type @|struct
+$C$__ilayout|, and if the relevant class is known at compile time then the
+best way to discover the layout size is with the @|sizeof| operator. Failing
+that, the size required to hold an instance of $C$ is available in a slot in
+$C$'s class object, as @|$C$__class@->cls.initsz|.
+
+It is not in general sufficient to declare, or otherwise allocate, an object
+of the class type $C$. The class type only describes a single chain of the
+object's layout. It is nearly always an error to use the class type as if it
+is a \emph{complete type}, e.g., to declare objects or arrays of the class
+type, or to enquire about its size or alignment requirements.
+
+Instance layouts may be declared as objects with automatic storage duration
+(colloquially, `allocated on the stack') or allocated dynamically, e.g.,
+using @|malloc|. They may be included as members of structures or unions, or
+elements of arrays. Sod's runtime system doesn't retain addresses of
+instances, so, for example, Sod doesn't make using fancy allocators which
+sometimes move objects around in memory any more difficult than it needs to
+be.
+
+There isn't any way to discover the alignment required for a particular
+class's instances at runtime; it's best to be conservative and assume that
+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
+ \{ return malloc(cls@->cls.initsz); \}
+\end{prog}
+
+\subsubsection{Imprinting}
+Once storage has been allocated, it must be \emph{imprinted} before it can be
+used as an instance of a class, e.g., before any messages can be sent to it.
+
+Imprinting an instance stores some metadata about its direct class in the
+instance structure, so that the rest of the program (and Sod's runtime
+library) can tell what sort of object it is, and how to use it.\footnote{%
+ Specifically, imprinting an instance's storage involves storing the
+ appropriate vtable pointers in the right places in it.} %
+A class object's @|imprint| slot points to a function which will correctly
+imprint storage for one of that class's instances.
+
+Once an instance's storage has been imprinted, it is technically possible to
+send messages to the instance; however the instance's slots are still
+uninitialized at this point, the applicable methods are unlikely to do much
+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
+ \{ cls@->cls.imprint(p); \}
+\end{prog}
+
+\subsubsection{Initialization}
+The final step for constructing a new instance is to \emph{initialize} it, to
+establish the necessary invariants for the instance itself and the
+environment in which it operates.
+
+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.
+
+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.
+
+Slots are initialized in a well-defined order.
+\begin{itemize}
+\item Slots defined by a more specific superclasses are initialized after
+ slots defined by a less specific superclass.
+\item Slots defined by the same class are initialized in the order in which
+ their definitions appear.
+\end{itemize}
+
+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, @|\dots|) \\
+ \{ \\ \ind
+ va_list ap;
+ void *p = malloc(c@->cls.initsz); \\
+ if (!p) return (0); \\
+ va_start(ap, c); \\
+ sod_initv(c, p, ap); \\
+ va_end(ap); \\
+ return (p); \- \\
+ \}
+ \\+
+ \#define MAKE(cls, keys) (cls *)make_instance(cls\#\#__class, keys)
+\end{prog}
+
+
+\subsection{Destruction}
+\label{sec:concepts.lifecycle.death}
+
+Destruction of an instance, when it is no longer required, consists of two
+steps.
+\begin{enumerate}
+\item \emph{Teardown} releases any resources held by the instance and
+ disentangles it from any external data structures.
+\item \emph{Deallocation} releases the memory used to store the instance so
+ that it can be reused.
+\end{enumerate}
+
+\subsubsection{Teardown}
+Details of teardown are class-specific, but typically it involves releasing
+resources held by the instance, and possibly unlinking it from some larger
+data structure which used to keep track of it.
+
+There is no provided protocol for teardown: classes whose instances require
+teardown behaviour must define and implement an appropriate protocol of their
+own. The following class may serve for simple cases.
+\begin{prog}
+ [nick = disposable] \\
+ class DisposableObject : SodObject \{ \\- \ind
+ void release() \{ ; \} \\
+ \quad /* Release resources held by the receiver. */ \- \\-
+ \}
+ \\+
+ code c : user \{ \\- \ind
+ /* If p is a a DisposableObject then release its resources. */ \\
+ void maybe_dispose(void *p) \\
+ \{ \\ \ind
+ DisposableObject *d = SOD_CONVERT(DisposableObject, p); \\
+ if (d) DisposableObject_release(d); \- \\
+ \} \- \\
+ \}
+\end{prog}
+
+\subsubsection{Deallocation}
+The details of instance deallocation are obviously specific to the allocation
+strategy used by the instance, and this is often orthogonal from the object's
+class.
+
+The code which makes the decision to destroy an object may often not be aware
+of the object's direct class. Low-level details of deallocation often
+require the proper base address of the instance's storage, which can be
+determined using the \descref{SOD_INSTBASE}[macro]{mac}.
+
+\subsubsection{Example}
+The following is a counterpart to the @|new_instance| function
+(\xref{sec:concepts.lifecycle.birth}), which tears down and deallocates an
+instance allocated using @|malloc|.
+\begin{prog}
+ void free_instance(void *p) \\
+ \{ \\ \ind
+ SodObject *obj = p; \\
+ maybe_dispose(p); \\
+ free(SOD_INSTBASE(obj)); \- \\
+ \}
+\end{prog}
+