X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/bf2e745293194a9fc27a86496623ccc515b7aa52..d9db9c73add5814057a80e9969c74419ce30e664:/doc/concepts.tex diff --git a/doc/concepts.tex b/doc/concepts.tex index d9239d0..eae67aa 100644 --- a/doc/concepts.tex +++ b/doc/concepts.tex @@ -63,22 +63,33 @@ having to implement additional syntax. For the most part, Sod takes a fairly traditional view of what it means to be an object system. -An \emph{object} maintains \emph{state} and exhibits \emph{behaviour}. An -object's state is maintained in named \emph{slots}, each of which can store a -C value of an appropriate (scalar or aggregate) type. An object's behaviour -is stimulated by sending it \emph{messages}. A message has a name, and may -carry a number of arguments, which are C values; sending a message may result -in the state of receiving object (or other objects) being changed, and a C -value being returned to the sender. - -Every object is a (direct) instance of some \emph{class}. The class -determines which slots its instances have, which messages its instances can -be sent, and which methods are invoked when those messages are received. The -Sod translator's main job is to read class definitions and convert them into -appropriate C declarations, tables, and functions. An object cannot +An \emph{object} maintains \emph{state} and exhibits \emph{behaviour}. +(Here, we're using the term `object' in the usual sense of `object-oriented +programming', rather than that of the ISO~C standard. Once we have defined +an `instance' below, we shall generally prefer that term, so as to prevent +further confusion between these two uses of the word.) + +An object's state is maintained in named \emph{slots}, each of which can +store a C value of an appropriate (scalar or aggregate) type. An object's +behaviour is stimulated by sending it \emph{messages}. A message has a name, +and may carry a number of arguments, which are C values; sending a message +may result in the state of receiving object (or other objects) being changed, +and a C value being returned to the sender. + +Every object is a \emph{direct instance} of exactly one \emph{class}. The +class determines which slots its instances have, which messages its instances +can be sent, and which methods are invoked when those messages are received. +The Sod translator's main job is to read class definitions and convert them +into appropriate C declarations, tables, and functions. An object cannot (usually) change its direct class, and the direct class of an object is not affected by, for example, the static type of a pointer to it. +If an object~$x$ is a direct instance of some class~$C$, then we say that $C$ +is \emph{the class of}~$x$. Note that the class of an object is a property +of the object's value at runtime, and not of C's compile-time type system. +We shall be careful in distinguishing C's compile-time notion of \emph{type} +from Sod's run-time notion of \emph{class}. + \subsection{Superclasses and inheritance} \label{sec:concepts.classes.inherit} @@ -120,7 +131,7 @@ class then the only superclass of $C$ is $C$ itself, and $C$ has no proper superclasses. If an object is a direct instance of class~$C$ then the object is also an -(indirect) instance of every superclass of $C$. +(indirect) \emph{instance} of every superclass of $C$. If $C$ has a proper superclass $B$, then $B$ must not have $C$ as a direct superclass. In different terms, if we construct a directed graph, whose @@ -302,13 +313,14 @@ qualified by the defining class's nickname. \subsubsection{Slot initializers} As well as defining slot names and types, a class can also associate an \emph{initial value} with each slot defined by itself or one of its -subclasses. A class $C$ provides an \emph{initialization message} (see -\xref{sec:concepts.lifecycle.birth}, and \xref{sec:structures.root.sodclass}) -whose methods set the slots of a \emph{direct} instance of the class to the -correct initial values. If several of $C$'s superclasses define initializers -for the same slot then the initializer from the most specific such class is -used. If none of $C$'s superclasses define an initializer for some slot then -that slot will be left uninitialized. +superclasses. A class $C$ provides an \emph{initialization message} (see +\xref[\instead{sections}]{sec:concepts.lifecycle.birth}, and +\ref{sec:structures.root.sodobject}) whose methods set the slots of a +\emph{direct} instance of the class to the correct initial values. If +several of $C$'s superclasses define initializers for the same slot then the +initializer from the most specific such class is used. If none of $C$'s +superclasses define an initializer for some slot then that slot will be left +uninitialized. The initializer for a slot with scalar type may be any C expression. The initializer for a slot with aggregate type must contain only constant @@ -334,6 +346,9 @@ details. \subsection{C language integration} \label{sec:concepts.classes.c} +It is very important to distinguish compile-time C \emph{types} from Sod's +run-time \emph{classes}: see \xref{sec:concepts.classes}. + For each class~$C$, the Sod translator defines a C type, the \emph{class type}, with the same name. This is the usual type used when considering an object as an instance of class~$C$. No entire object will normally have a @@ -343,6 +358,10 @@ class type,\footnote{% chains. See \xref{sec:structures.layout} for the full details.} % so access to instances is almost always via pointers. +Usually, a value of type pointer-to-class-type of class~$C$ will point into +an instance of class $C$. However, clever (or foolish) use of pointer +conversions can invalidate this relationship. + \subsubsection{Access to slots} The class type for a class~$C$ is actually a structure. It contains one member for each class in $C$'s superclass chain, named with that class's @@ -516,6 +535,13 @@ Keyword arguments can be provided in three ways. call, which is useful when writing wrapper functions. \end{enumerate} +Perhaps surprisingly, keyword arguments have a relatively small performance +impact. On the author's aging laptop, a call to a simple function, passing +two out of three keyword arguments, takes about 30 cycles longer than calling +a standard function which just takes integer arguments. On the other hand, +quite a lot of code is involved in decoding keyword arguments, so code size +will naturally suffer. + 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}); and they play an essential rôle in