%%% -*-latex-*-
%%%
%%% Introduction to Sod and its object system
%%%
%%% (c) 2015 Straylight/Edgeware
%%%

%%%----- Licensing notice ---------------------------------------------------
%%%
%%% This file is part of the Sensible Object Design, an object system for C.
%%%
%%% SOD is free software; you can redistribute it and/or modify
%%% it under the terms of the GNU General Public License as published by
%%% the Free Software Foundation; either version 2 of the License, or
%%% (at your option) any later version.
%%%
%%% SOD is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%%% GNU General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with SOD; if not, write to the Free Software Foundation,
%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

\chapter{Introduction} \label{ch:intro}

Sod is an object system for the C programming language.

The software distribution for Sod contains two main parts:
\begin{itemize}
\item a translator, or preprocessor, similar in spirit to \man{lex}{1} or
  \man{yacc}{1}, which reads input files containing class definitions, and
  writes C source code and header files; and
\item a very small runtime library, containing the built-in base classes and
  some simple utility macros and functions for working with instances and
  classes.
\end{itemize}

%%%--------------------------------------------------------------------------
\section{About Sod's object system} \label{ch:intro.about}

Sod implements a fairly sophisticated object system, with multiple
inheritance, but only single dispatch.

\subsection{Ideology}

Object systems tend to come with ideology attached, so Sod is no exception;
but Sod's ideology is different from that of most object systems.
\begin{itemize}
\item Sod provides an object system, not a module system.  Sod provides no
  facilities for `information hiding'; there is no equivalent to the
  @|private| or @|protected| annotations in Java or \Cplusplus.  The author
  takes the view (a) that such facilities are propertly part of a module
  system, and that trying to abuse classes so that they become modules is a
  mistake; and (b) that much useful functionality is unnecessarily hidden
  away behind abstract interfaces, and a gentle-ish nudge towards greater
  openness is called for.
\item Sod's objective is to provide an effective tool for the expert
  programmer, in the classic `make easy things simple and, difficult things
  possible' mould.  It isn't intended to be useful in an environment
  containing unassisted novice programmers.  Sod tries to avoid placing
  technically unnecessary restrictions on programmers, and is likely to
  evolve in the direction of eliminating existing restrictions rather than
  growing new `safety' features.
\end{itemize}

\subsection{Comparison with other object systems}

Sod's object system is significantly different in flavour\footnote{%
  The pun was unintentional, but I'm happy with it.} %
from most popular object-ish languages.  Indeed, it bears far more similarity
to Flavors, CLOS, and Dylan than to \Cplusplus, \Csharp, or Java (and still
less to Go or Rust).

Of the popular languages, \Cplusplus's object system is probably closest to
Sod.  Both are statically compiled, statically typed, implement single
dispatch, and have relatively simple runtime metaprogramming facilities.
\Cplusplus\ has a rich compile-time template metalanguage; Sod instead allows
compile-time metaprogramming in Common Lisp, which is probably less
convenient for simple cases but rather more pleasant for doing difficult
things.  Significantly, Sod has the @|SodObject| class, of which all other
classes\footnote{%
  Unless you construct a new root class of your own, which you can totally
  do, but it's hard work.} %
are subclasses; \Cplusplus\ has no such root class.

Both systems provide multiple inheritance, but go about it very differently.
The most important difference is that \Cplusplus\ provides only \emph{static
  delegation}: if you have a class @|B| which defines some (virtual) member
function @|f|, and a derived class of @|D| which wants to \emph{extend} the
behaviour of @|f| on instances of @|D|, then you must explicitly call @|B::f|
at the appropriate point:
\begin{prog}
  \#include <iostream>                                          \\+
                                                                %
  class B \{                                                    \\
  public:                                                       \\ \ind
    virtual void f() \{ std::cout <{}< "B@\\n"; \}              \\
    virtual @~B() \{ \}                                       \-\\
  \};                                                           \\+
                                                                %
  class D: public B \{                                          \\
  public:                                                       \\ \ind
    void f() \{ B::f(); std::cout <{}< "D too@\\n"; \}        \-\\
  \};
\end{prog}

This works adequately when only single inheritance is involved.  But if we
now introduce multiple inheritance, we see the problem.
\begin{prog}
  \#include <iostream>                                          \\+
                                                                %
  class B \{                                                    \\
  public:                                                       \\ \ind
    virtual void f() \{ std::cout <{}< "B@\\n"; \}              \\
    virtual @~B() \{ \}                                       \-\\
  \};                                                           \\+
                                                                %
  class X: virtual public B \{                                  \\
  public:                                                       \\ \ind
    void f() \{ B::f(); std::cout <{}< "X after@\\n"; \}      \-\\
  \};                                                           \\+
                                                                %
  class Y: virtual public B \{                                  \\
  public:                                                       \\ \ind
    void f() \{ std::cout <{}< "Y before@\\n"; B::f(); \}     \-\\
  \};                                                           \\+
                                                                %
  class D: public X, public Y \{                                \\
  public:                                                       \\ \ind
    void f() \{ X::f(); Y::f(); \} // \comment{oh, dear}      \-\\
  \};
\end{prog}
The above prints
\begin{prog}
  B                                                             \\
  X after                                                       \\
  Y before                                                      \\
  B
\end{prog}
which is unlikely to be what was wanted: `B' prints twice, and the `before'
and `after' actions are both in the middle.\footnote{%
  Of course, one could have arranged to call @|Y::f| before @|X::f| -- but
  the important point is that one would have needed to \emph{know} that this
  was necessary.} %
The problem is that correctly composing behaviour from a collection of
superclasses requires knowledge of all of the superclasses involved and how
they're supposed to work together.

The obvious workaround is to separate the functionality -- here, printing the
messages -- from the plumbing, which arranges to do everything in the right
order.  You'd end up with a @|_f| member function in each class which wanted
print something, and then every class would have a virtual @|f| which calls
the various @|_f| functions in the right order, like this:
\begin{prog}
  \#include <iostream>                                          \\+
                                                                %
  class B \{                                                    \\
  protected:                                                    \\ \ind
    void _f() \{ std::cout <{}< "B@\\n"; \}                   \-\\
  public:                                                       \\ \ind
    virtual void f() \{ _f(); \}                                \\
    virtual ~B() \{ \}                                        \-\\
  \};                                                           \\+
                                                                %
  class X: virtual public B \{                                  \\
  protected:                                                    \\ \ind
    void _f() \{ std::cout <{}< "X after@\\n"; \}             \-\\
  public:                                                       \\ \ind
    void f() \{ B::_f(); _f(); \}                             \-\\
  \};                                                           \\+
                                                                %
  class Y: virtual public B \{                                  \\
  protected:                                                    \\ \ind
    void _f() \{ std::cout <{}< "Y before@\\n"; \}            \-\\
  public:                                                       \\ \ind
    void f() \{ _f(); B::_f(); \}                             \-\\
  \};                                                           \\+
                                                                %
  class D: public X, public Y \{                                \\
  public:                                                       \\ \ind
    void f() \{ Y::_f(); B::_f(); X::_f(); \}                 \-\\
  \};
\end{prog}
This is clearly much more cumbersome.  Most disastrously, it spreads
knowledge about how the various classes' contributions to the behaviour of
@|f| fit together throughout the class graph.  Also, even this approach is
only suitable for especially simple cases.  Suppose @|Y| needed to add
behaviour before \emph{and} after @|B| -- maybe @|Y| is taking out a lock,
and then releasing it.  Then this approach won't work any more; indeed, it's
hard to see any way to make this work without spreading knowledge about
@|Y|'s lock everywhere.

Compare Sod's approach.
\begin{prog}
  code c: includes \{                                           \\
  \#include <stdio.h>                                           \\-
  \#include <sod.h>                                             \\
  \#include "foo.h"                                             \\
  \}                                                            \\+
                                                                %
  class B: SodObject \{                                         \\ \ind
    void f() \{ puts("B"); \}                                 \-\\
  \}                                                            \\+
                                                                %
  class X: B \{                                                 \\ \ind
    void b.f() \{ CALL_NEXT_METHOD; puts("X after"); \}       \-\\
  \}                                                            \\
                                                                %
  class Y: B \{                                                 \\ \ind
    void b.f() \{ puts("Y before"); CALL_NEXT_METHOD; \}      \-\\
  \}                                                            \\+
                                                                %
  class D: X, Y \{ \}
\end{prog}
This prints
\begin{prog}
  Y before                                                      \\
  B                                                             \\
  X after
\end{prog}
as (I think) you'd hope.  @|CALL_NEXT_METHOD| here does the job of figuring
out what to do next, according to some rather complicated rules
(described in full in \xref{sec:concepts.methods.combination}).

Indeed, there's an even better way to write this particular case with Sod,
because Sod has dedicated \emph{method rôles}.
\begin{prog}
  code c: includes \{                                           \\
  \#include <stdio.h>                                           \\-
  \#include <sod.h>                                             \\
  \#include "foo.h"                                             \\
  \}                                                            \\+
                                                                %
  class B: SodObject \{                                         \\ \ind
    void f() \{ puts("B"); \}                                 \-\\
  \}                                                            \\+
                                                                %
  class X: B \{                                                 \\ \ind
    [role = after] void b.f() \{ puts("X after"); \}          \-\\
  \}                                                            \\
                                                                %
  class Y: B \{                                                 \\ \ind
    [role = before] void b.f() \{ puts("Y before"); \}        \-\\
  \}                                                            \\+
                                                                %
  class D: X, Y \{ \}
\end{prog}

%%%--------------------------------------------------------------------------
\section{About this manual}

This manual intends to provide complete documentation about Sod.

%%%----- That's all, folks --------------------------------------------------

%%% Local variables:
%%% mode: LaTeX
%%% TeX-master: "sod.tex"
%%% TeX-PDF-mode: t
%%% End:
