about summary refs log tree commit diff stats
path: root/html/000organization.cc.html
blob: d074f97ea2d5454b3145b1494ec188376e3a1c8a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 000organization.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.Delimiter { color: #800080; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Identifier { color: #fcb165; }
.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; }
.PreProc { color: #800080; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">//: You guessed right: the '000' prefix means you should start reading here.</span>
<span class="Comment">//:</span>
<span class="Comment">//: This project is set up to load all files with a numeric prefix. Just</span>
<span class="Comment">//: create a new file and start hacking.</span>
<span class="Comment">//:</span>
<span class="Comment">//: The first few files (00*) are independent of what this program does, an</span>
<span class="Comment">//: experimental skeleton that will hopefully make it both easier for others to</span>
<span class="Comment">//: understand and more malleable, easier to rewrite and remould into radically</span>
<span class="Comment">//: different shapes without breaking in subtle corner cases. The premise is</span>
<span class="Comment">//: that understandability and rewrite-friendliness are related in a virtuous</span>
<span class="Comment">//: cycle. Doing one well makes it easier to do the other.</span>
<span class="Comment">//:</span>
<span class="Comment">//: Lower down, this file contains a legal, bare-bones C++ program. It doesn't</span>
<span class="Comment">//: do anything yet; subsequent files will contain :(...) directives to insert</span>
<span class="Comment">//: lines into it. For example:</span>
<span class="Comment">//:   :(after &quot;more events&quot;)</span>
<span class="Comment">//: This directive means: insert the following lines after a line in the</span>
<span class="Comment">//: program containing the words &quot;more events&quot;.</span>
<span class="Comment">//:</span>
<span class="Comment">//: A simple tool is included to 'tangle' all the files together in sequence</span>
<span class="Comment">//: according to their directives into a single source file containing all the</span>
<span class="Comment">//: code for the project, and then feed the source file to the compiler.</span>
<span class="Comment">//: (It'll drop these comments starting with a '//:' prefix that only make</span>
<span class="Comment">//: sense before tangling.)</span>
<span class="Comment">//:</span>
<span class="Comment">//: Directives free up the programmer to order code for others to read rather</span>
<span class="Comment">//: than as forced by the computer or compiler. Each individual feature can be</span>
<span class="Comment">//: organized in a self-contained 'layer' that adds code to many different data</span>
<span class="Comment">//: structures and functions all over the program. The right decomposition into</span>
<span class="Comment">//: layers will let each layer make sense in isolation.</span>
<span class="Comment">//:</span>
<span class="Comment">//:   &quot;If I look at any small part of it, I can see what is going on -- I don't</span>
<span class="Comment">//:   need to refer to other parts to understand what something is doing.</span>
<span class="Comment">//:</span>
<span class="Comment">//:   If I look at any large part in overview, I can see what is going on -- I</span>
<span class="Comment">//:   don't need to know all the details to get it.</span>
<span class="Comment">//:</span>
<span class="Comment">//:   Every level of detail is as locally coherent and as well thought-out as</span>
<span class="Comment">//:   any other level.&quot;</span>
<span class="Comment">//:</span>
<span class="Comment">//:       -- Richard Gabriel, &quot;The Quality Without A Name&quot;</span>
<span class="Comment">//:          (<a href="http://dreamsongs.com/Files/PatternsOfSoftware.pdf">http://dreamsongs.com/Files/PatternsOfSoftware.pdf</a>, page 42)</span>
<span class="Comment">//:</span>
<span class="Comment">//: Directives are powerful; they permit inserting or modifying any point in</span>
<span class="Comment">//: the program. Using them tastefully requires mapping out specific lines as</span>
<span class="Comment">//: waypoints for future layers to hook into. Often such waypoints will be in</span>
<span class="Comment">//: comments, capitalized to hint that other layers rely on their presence.</span>
<span class="Comment">//:</span>
<span class="Comment">//: A single waypoint might have many different code fragments hooking into</span>
<span class="Comment">//: it from all over the codebase. Use 'before' directives to insert</span>
<span class="Comment">//: code at a location in order, top to bottom, and 'after' directives to</span>
<span class="Comment">//: insert code in reverse order. By convention waypoints intended for insertion</span>
<span class="Comment">//: before begin with 'End'. Notice below how the layers line up above the &quot;End</span>
<span class="Comment">//: Foo&quot; waypoint.</span>
<span class="Comment">//:</span>
<span class="Comment">//:   File 001          File 002                File 003</span>
<span class="Comment">//:   ============      ===================     ===================</span>
<span class="Comment">//:   // Foo</span>
<span class="Comment">//:   ------------</span>
<span class="Comment">//:              &lt;----  :(before &quot;End Foo&quot;)</span>
<span class="Comment">//:                     ....</span>
<span class="Comment">//:                     ...</span>
<span class="Comment">//:   ------------</span>
<span class="Comment">//:              &lt;----------------------------  :(before &quot;End Foo&quot;)</span>
<span class="Comment">//:                                             ....</span>
<span class="Comment">//:                                             ...</span>
<span class="Comment">//:   // End Foo</span>
<span class="Comment">//:   ============</span>
<span class="Comment">//:</span>
<span class="Comment">//: Here's part of a layer in color: <a href="http://i.imgur.com/0eONnyX.png">http://i.imgur.com/0eONnyX.png</a>. Directives</span>
<span class="Comment">//: are shaded dark.</span>
<span class="Comment">//:</span>
<span class="Comment">//: Layers do more than just shuffle code around. In a well-organized codebase</span>
<span class="Comment">//: it should be possible to stop loading after any file/layer, build and run</span>
<span class="Comment">//: the program, and pass all tests for loaded features. (Relevant is</span>
<span class="Comment">//: <a href="http://youtube.com/watch?v=c8N72t7aScY">http://youtube.com/watch?v=c8N72t7aScY</a>, a scene from &quot;2001: A Space</span>
<span class="Comment">//: Odyssey&quot;.) Get into the habit of running the included script called</span>
<span class="Comment">//: 'test_layers' before you commit any changes.</span>
<span class="Comment">//:</span>
<span class="Comment">//: This 'subsetting guarantee' ensures that this directory contains a</span>
<span class="Comment">//: cleaned-up narrative of the evolution of this codebase. Organizing</span>
<span class="Comment">//: autobiographically allows a newcomer to rapidly orient himself, reading the</span>
<span class="Comment">//: first few files to understand a simple gestalt of a program's core purpose</span>
<span class="Comment">//: and features, and later gradually working his way through other features as</span>
<span class="Comment">//: the need arises.</span>
<span class="Comment">//:</span>
<span class="Comment">//: Programmers shouldn't need to understand everything about a program to hack</span>
<span class="Comment">//: on it. But they shouldn't be prevented from a thorough understanding of</span>
<span class="Comment">//: each aspect either. The goal of layers is to reward curiosity.</span>

<span class="Comment">// Includes</span>
<span class="Comment">// End Includes</span>

<span class="Comment">// Types</span>
<span class="Comment">// End Types</span>

<span class="Comment">// Prototypes are auto-generated in the makefile; define your functions in any</span>
<span class="Comment">// order. Just be sure to declare each function header all on one line. Our</span>
<span class="Comment">// auto-generation scripts are too minimal and simple-minded to handle</span>
<span class="Comment">// anything else.</span>
<span class="PreProc">#include </span><span class="Constant">&quot;function_list&quot;</span>  <span class="Comment">// by convention, files ending with '_list' are auto-generated</span>

<span class="Comment">// Globals</span>
<span class="Comment">//</span>
<span class="Comment">// All statements in this section should always define a single variable on a</span>
<span class="Comment">// single line. The makefile will simple-mindedly auto-generate extern</span>
<span class="Comment">// declarations for them. Don't forget to define (not just declare) constants</span>
<span class="Comment">// with extern linkage in this section, since C++ global constants have</span>
<span class="Comment">// internal linkage by default.</span>
<span class="Comment">//</span>
<span class="Comment">// End Globals</span>

<span class="Normal">int</span> main<span class="Delimiter">(</span><span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  atexit<span class="Delimiter">(</span>teardown<span class="Delimiter">);</span>

  <span class="Comment">// End One-time Setup</span>

  <span class="Comment">// Commandline Parsing</span>
  <span class="Comment">// End Commandline Parsing</span>

  <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>  <span class="Comment">// End Main</span>
<span class="Delimiter">}</span>

<span class="Comment">// Unit Tests</span>
<span class="Comment">// End Unit Tests</span>

<span class="Comment">//: our first directive; will move the include above the program</span>
<span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span>

<span class="Comment">//: Without directives or with the :(code) directive, lines get added at the</span>
<span class="Comment">//: end.</span>
<span class="Delimiter">:(code)</span>
<span class="Normal">void</span> setup<span class="Delimiter">()</span> <span class="Delimiter">{</span>
  <span class="Comment">// End Setup</span>
<span class="Delimiter">}</span>

<span class="Normal">void</span> teardown<span class="Delimiter">()</span> <span class="Delimiter">{</span>
  <span class="Comment">// End Teardown</span>
<span class="Delimiter">}</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->