X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/8ec911fa0b763bd9ea8eb24feefcdef91c691bdd..054e8f8f1ea255ff77b19df82bd845e5686dac0d:/doc/concepts.tex diff --git a/doc/concepts.tex b/doc/concepts.tex index 45f76b6..187a6f8 100644 --- a/doc/concepts.tex +++ b/doc/concepts.tex @@ -122,11 +122,11 @@ superclasses. If an object is a direct instance of class~$C$ then the object is also an (indirect) instance of every superclass of $C$. -If $C$ has a proper superclass $B$, then $B$ is not allowed to have $C$ has a -direct superclass. In different terms, if we construct a graph, whose -vertices are classes, and draw an edge from each class to each of its direct -superclasses, then this graph must be acyclic. In yet other terms, the `is a -superclass of' relation is a partial order on classes. +If $C$ has a proper superclass $B$, then $B$ must not have $C$ as a direct +superclass. In different terms, if we construct a graph, whose vertices are +classes, and draw an edge from each class to each of its direct superclasses, +then this graph must be acyclic. In yet other terms, the `is a superclass +of' relation is a partial order on classes. \subsubsection{The class precedence list} This partial order is not quite sufficient for our purposes. For each class @@ -177,11 +177,12 @@ a link superclass, and the link superclass of a class $C$, if it exists, need not be a direct superclass of $C$. Superclass links must obey the following rule: if $C$ is a class, then there -must be no three superclasses $X$, $Y$ and~$Z$ of $C$ such that $Z$ is the -link superclass of both $X$ and $Y$. As a consequence of this rule, the -superclasses of $C$ can be partitioned into linear \emph{chains}, such that -superclasses $A$ and $B$ are in the same chain if and only if one can trace a -path from $A$ to $B$ by following superclass links, or \emph{vice versa}. +must be no three distinct superclasses $X$, $Y$ and~$Z$ of $C$ such that $Z$ +is the link superclass of both $X$ and $Y$. As a consequence of this rule, +the superclasses of $C$ can be partitioned into linear \emph{chains}, such +that superclasses $A$ and $B$ are in the same chain if and only if one can +trace a path from $A$ to $B$ by following superclass links, or \emph{vice +versa}. Since a class links only to one of its proper superclasses, the classes in a chain are naturally ordered from most- to least-specific. The least specific @@ -287,8 +288,10 @@ and its type is usually @|SodClass|; @|SodClass|'s nickname is @|cls|. A class object's slots contain or point to useful information, tables and functions for working with that class's instances. (The @|SodClass| class -doesn't define any messages, so it doesn't have any methods. In Sod, a class -slot containing a function pointer is not at all the same thing as a method.) +doesn't define any messages, so it doesn't have any methods other than for +the @|SodObject| lifecycle messages @|init| and @|teardown|; see +\xref{sec:concepts.lifecycle}. In Sod, a class slot containing a function +pointer is not at all the same thing as a method.) \subsubsection{Conversions} Suppose one has a value of type pointer-to-class-type for some class~$C$, and @@ -313,7 +316,7 @@ There are three main cases to distinguish. conversion can fail: the object in question might not be an instance of~$B$ after all. The macro \descref{SOD_CONVERT}{mac} and the function \descref{sod_convert}{fun} perform general conversions. They return a null - pointer if the conversion fails. (There are therefore your analogue to the + pointer if the conversion fails. (These are therefore your analogue to the \Cplusplus\ @|dynamic_cast<>| operator.) \end{itemize} The Sod translator generates macros for performing both in-chain and @@ -499,7 +502,7 @@ entry functions. node [midway, right, align=left] {Most to \\ least \\ specific};} - \delgstack{a}{}{Around method} + \delgstack{a}{}{@|around| method} \draw [<-] ($(a0.south)!.5!(a0.south west) - (0mm, 1mm)$) -- ++(0mm, -4mm); \draw [->] ($(a0.south)!.5!(a0.south east) - (0mm, 1mm)$) -- @@ -511,7 +514,7 @@ entry functions. node [code, midway, left=3mm] {next_method} node (b0) [method, above left = 1mm + 4mm and -6mm - 4mm] {}; \node (b1) [method] at ($(b0) - (2mm, 2mm)$) {}; - \node (bn) [method] at ($(b1) - (2mm, 2mm)$) {Before method}; + \node (bn) [method] at ($(b1) - (2mm, 2mm)$) {@|before| method}; \draw [->, order] ($(bn.west) - (6mm, 0mm)$) -- ++(12mm, 12mm) node [midway, above left, align=center] {Most to \\ least \\ specific}; \draw [->] ($(b0.north east) + (-10mm, 1mm)$) -- ++(8mm, 8mm) @@ -537,7 +540,7 @@ entry functions. node [action, midway, right=3mm] {return} node (f0) [method, above right = 1mm and -6mm] {}; \node (f1) [method] at ($(f0) + (-2mm, 2mm)$) {}; - \node (fn) [method] at ($(f1) + (-2mm, 2mm)$) {After method}; + \node (fn) [method] at ($(f1) + (-2mm, 2mm)$) {@|after| method}; \draw [<-, order] ($(f0.east) + (6mm, 0mm)$) -- ++(-12mm, 12mm) node [midway, above right, align=center] {Least to \\ most \\ specific}; @@ -563,16 +566,16 @@ follows (see also~\xref{fig:concepts.methods.stdmeth}). If there any remaining @|around| methods, then @|next_method| invokes the next most specific such method, returning whichever value that method - returns; otherwise the behaviour of @|next_method| is to invoke the before - methods (if any), followed by the most specific primary method, followed by - the @|around| methods (if any), and to return whichever value was returned - by the most specific primary method, as described in the following items. - That is, the behaviour of the least specific @|around| method's - @|next_method| function is exactly the behaviour that the effective method - would have if there were no @|around| methods. Note that if the - least-specific @|around| method calls its @|next_method| more than once - then the whole sequence of @|before|, primary, and @|after| methods occurs - multiple times. + returns; otherwise the behaviour of @|next_method| is to invoke the + @|before| methods (if any), followed by the most specific primary method, + followed by the @|after| methods (if any), and to return whichever value + was returned by the most specific primary method, as described in the + following items. That is, the behaviour of the least specific @|around| + method's @|next_method| function is exactly the behaviour that the + effective method would have if there were no @|around| methods. Note that + if the least-specific @|around| method calls its @|next_method| more than + once then the whole sequence of @|before|, primary, and @|after| methods + occurs multiple times. The value returned by the most specific @|around| method is the value returned by the effective method. @@ -606,7 +609,7 @@ follows (see also~\xref{fig:concepts.methods.stdmeth}). A typical use for @|around| methods is to allow a base class to set up the dynamic environment appropriately for the primary methods of its subclasses, -e.g., by claiming a lock, and restore it afterwards. +e.g., by claiming a lock, and releasing it afterwards. The @|next_method| function provided to methods with the primary and @|around| rôles accepts the same arguments, and returns the same type, as the @@ -812,8 +815,8 @@ 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. +uninitialized at this point, so 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 @

as an instance of a class, given a pointer to its class object @. @@ -846,8 +849,8 @@ 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 a more specific superclass 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} @@ -875,9 +878,9 @@ 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 +slot or slot initializer item: the property's value 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|