chiark / gitweb /
Very ragged work-in-progress.
[sod] / sod-tut.tex
1 %%% -*-latex-*-
2 %%%
3 %%% Tutorial information
4 %%%
5 %%% (c) 2009 Straylight/Edgeware
6 %%%
7
8 %%%----- Licensing notice ---------------------------------------------------
9 %%%
10 %%% This file is part of the Simple Object Definition system.
11 %%%
12 %%% SOD is free software; you can redistribute it and/or modify
13 %%% it under the terms of the GNU General Public License as published by
14 %%% the Free Software Foundation; either version 2 of the License, or
15 %%% (at your option) any later version.
16 %%%
17 %%% SOD is distributed in the hope that it will be useful,
18 %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
19 %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 %%% GNU General Public License for more details.
21 %%%
22 %%% You should have received a copy of the GNU General Public License
23 %%% along with SOD; if not, write to the Free Software Foundation,
24 %%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26 \chapter{Tutorial}
27 \label{ch:tut}
28
29 This chapter provides a tutorial introduction to the Sod object system.  It
30 intentionally misses out nitty-gritty details.  If you want those, the
31 remaining chapters provide a complete reference to Sod.
32
33 The author isn't terribly good at writing tutorial-style documentation.
34 You'll have to bear with him.  If you think you can do a better job, I'm sure
35 that he'll be grateful for your contribution.
36
37 %%%--------------------------------------------------------------------------
38 \section{Introduction} \label{sec:tut.intro}
39
40 Sod is an object system for the C~programming language.  Because it doesn't
41 have enough already.  Actually, that's not right: it's got plenty already.
42 But Sod is a Sensible Object Design, and C doesn't have any of those.
43
44 What does that mean when the author's not off on one of his tirades?  It
45 means that is has the following features.
46 \begin{itemize}
47 \item It has a \emph{minimal runtime system}.  Sod isn't likely to interfere
48   with other language runtimes or be difficult to deal with from a practical
49   point of view.
50 \item It provides \emph{multiple inheritance}.  Rather than having a single
51   superclass, Sod allows a class to specify any number of superclasses.
52   Moreover, it implements multiple inheritance using \emph{superclass
53     linearization}, which means that it's not a nightmare to deal with.
54 \item It provides multiple \emph{method rĂ´les}, including `before', `after'
55   and `around' methods, which makes constructing object protocols rather more
56   straightforward.
57 \item It provides a number of \emph{method combinations}.  For those coming
58   from languages other than Lisp, a method combination is a rule for deciding
59   how to invoke the various methods which might be used to respond to a
60   message.  (This might still sound like a strange idea.  We'll deal with it
61   in detail later.)
62 \item It allows \emph{user-defined method combinations}.  It does a whole lot
63   more: there's an entire translation-time \emph{meta-object protocol}, so
64   that extensions can modify many different aspects of the object system.
65   The downside is that you have to learn Common Lisp and roll up your sleeves
66   if you want to do any of this.
67 \end{itemize}
68 There's a good chance that half of that didn't mean anything to you.  Bear
69 with me, though, because we'll explain it all eventually.
70
71 \subsection{Building programs with Sod} \label{sec:tut.intro.build}
72
73 Sod is basically a fancy preprocessor, in the same vein as Lex and Yacc.  It
74 reads source files written in a vaguely C-like language.  It produces output
75 files which are actually C code (both header files and standalone sources),
76 and which contain chunks of the input files verbatim.
77
78 The main consequences of this are as follows.
79 \begin{itemize}
80 \item The output is completely portable between different machines and
81   compilers.  If you're preparing a source distribution for general release,
82   it's probably a good idea to provide the generated C~source as well as your
83   Sod sources.
84 \item Sod hasn't made any attempt to improve C's syntax.  It's just as
85   hostile to object-oriented programming as it ever was.  This means that
86   you'll end up writing ugly things like
87   \begin{prog}%
88     thing->_vt->foo.frob(thing, mumble);%
89   \end{prog}
90   fairly frequently.  This can be made somewhat less painful using macros,
91   but we're basically stuck with C.  The upside is that you know exactly what
92   you're getting.  A common complaint about \Cplusplus\ is that it has a
93   tendency to hide arbitrarily complicated runtime behaviour behind
94   apparently innocent syntax: you don't get any of that with Sod.  Some
95   people might even think this is a benefit.
96 \end{itemize}
97 Of course, this means that your build system needs to become more
98 complicated.  If you use \man{make}{1}, then something like
99 \begin{prog}%
100   SOD = sod
101
102   .SUFFIXES: .sod .c .h
103   .sod.c:; \$(SOD) -gc -o \$@@ \$<
104   .sod.h:; \$(SOD) -gh -o \$@@ \$< %
105 \end{prog}
106 ought to do the job.
107
108 %%%--------------------------------------------------------------------------
109 \section{A traditional trivial introduction}
110
111 The following is a simple Sod input file.
112 \begin{prog}\quad\=\quad\=\kill%
113 /* -*-sod-*- */
114
115 code c : includes \{
116 \#include "greeter.h"
117 \}
118
119 code h : includes \{
120 \#include <stdio.h>
121 \#include <sod.h>
122 \}
123
124 class Greeter : SodObject \{ \+
125   void greet(FILE *fp) \{ \+
126     fputs("Hello, world!\textbackslash n", fp); \-
127   \} \-
128 \} %
129 \end{prog}
130 Save it as @"greeter.sod", and run
131 \begin{prog}%
132 sod --gc --gh greeter %
133 \end{prog}
134 This will create files @"greeter.c" and @"greeter.h" in the current
135 directory.  Here's how we might use such a simple thing.
136 \begin{prog}\quad\=\kill%
137 \#include "greeter.h"
138
139 int main(void)
140 \{ \+
141   struct Greeter__ilayout g_obj;
142   Greeter *g = Greeter__class->cls.init(\&g_obj);
143
144   g->_vt.greeter.greet(g, stdout);
145   return (0); \-
146 \} %
147 \end{prog}
148 Compare this to the traditional
149 \begin{prog}\quad\=\kill%
150 \#include <stdio.h>
151
152 int main(void) \+
153   \{ fputs("Hello, world\\n", stdout); return (0); \} %
154 \end{prog}
155 and I'm sure you'll appreciate the benefits of using Sod already -- mostly to
156 do with finger exercise.  Trust me, it gets more useful.
157
158 The @".sod" file was almost comprehensible.  There are two important parts to
159 it (after the comment which tells Emacs how to cope with it).
160
161 The first part consists of the two @"code" stanzas.  Both of them define
162 gobbets of raw C code to copy into output files.  The first one, @"code~:
163 c"~\ldots, says that
164 \begin{prog}%
165   \#include "greeter.h" %
166 \end{prog}
167 needs to appear in the generated @|greeter.c| file; the second says that
168 \begin{prog}%
169   \#include <stdio.h>
170   \#include <sod.h> %
171 \end{prog}
172 needs to appear in the header file @|greeter.h|.  The generated C files need
173 to get declarations for external types and functions (e.g., @"FILE" and
174 @"fputs") from somewhere, and the generated @".c" file will need the
175 declarations from the corresponding @".h" file.  Sod takes a very simple
176 approach to all of this: it expects you, the programmer, to deal with it.
177
178 The basic syntax for @"code" stanzas is
179 \begin{prog}\quad\=\kill%
180   code @<file-label> : @<section> \{
181   \>  @<code>
182   \} %
183 \end{prog}
184 The @<file-label> is either @"c" or @"h", and says which output file the code
185 wants to be written to.  The @<section> is a name which explains where in the
186 output file to place the code.  The @"includes" section is the usual choice:
187 it's the `right' place for @`\#include' directives and similar declarations.
188
189 The remaining part, the `meat' of the file, defines a class called
190 @"greeter".  The class can respond to a single message, named @"greet", and
191 in response, it writes a traditional greeting to the file passed in with the
192 message.
193
194 So far, so good.  The C code, which we thought we understood, contains some
195 bizarre looking runes.  Let's take it one step at a time.
196 \begin{prog}%
197   struct Greeter__ilayout g_obj; %
198 \end{prog}
199 allocates space for an instance of class @"Greeter".  We're not going to use
200 this space directly.  Instead, we do this frightening looking thing.
201 \begin{prog}%
202   Greeter *g = Greeter__class->cls.init(\&g_obj); %
203 \end{prog}
204 Taking it slowly: @"Greeter__class" is a pointer to the object that
205 represents our class @"Greeter".  This object contains a member, named
206 @"cls.init", which points to a function whose job is to turn uninitialized
207 storage space into working instances of the class.  It returns a pointer to
208 the instance, which we use in preference to grovelling about in the
209 @"ilayout" structure.
210
211 Having done this, we `send the instance a message':
212 \begin{prog}%
213   g->_vt->greeter.greet(g, stdout); %
214 \end{prog}
215 This looks horrific, and seems to repeat itself quite unnecessarily.  The
216 first @"g" is the recipient of our `message'.  The second is indeed a copy of
217 the first: we have to tell it who it is.  (Sod doesn't extend C's syntax, so
218 this is the sort of thing we just have to put up with.)  The lowercase
219 @"greeter" is our class's `nickname': we didn't choose one explicitly, so Sod
220 picked one by forcing the classname to lowercase.
221
222 %%%----- That's all, folks --------------------------------------------------
223
224 %%% Local variables:
225 %%% mode: LaTeX
226 %%% TeX-master: "sod.tex"
227 %%% TeX-PDF-mode: t
228 %%% End: