source: doc/theses/mike_brooks_MMath/programs/sharing-demo.cfa@ e0350e0

Last change on this file since e0350e0 was f85de47, checked in by Michael Brooks <mlbrooks@…>, 5 months ago

String chapter work.

General copy-editing throughout the chapter.

Rewrite and elaborate "RAII limitations."

Move "Logical overlap" up to features' section and integrate flow with assignment-semantics predecessor.

Re-brand "Memory management" as "General implementation," and move to front of "Storage Management."

Elaborate performance experiment descriptions, giving harness sketches.

Convert first performance experiment graph (peq-cppemu) to draw directly from benchmark result file, now included in git. Similar work on remaining graphs, and adding missing data, is forthcoming.

To build thesis may now require pip3 install pandas.

  • Property mode set to 100644
File size: 14.8 KB
Line 
1#include <string.hfa>
2#include <fstream.hfa>
3#include <assert.h>
4#define xstr(s) str(@s;@)
5#define str(s) #s
6
7ofstream outfile;
8
9void demo1() {
10 sout | sepOff;
11// sout | "Consider two strings @s1@ and @s1a@ that are in an aliasing relationship, and a third, @s2@, made by a simple copy from @s1@.";
12
13 #define S1 string s1 = "abc"
14 #define S1A string s1a = s1`share
15 #define S2 string s2 = s1a
16 S1;
17 S1A;
18 S2;
19 assert( s1 == "abc" );
20 assert( s1a == "abc" );
21 assert( s2 == "abc" );
22
23 open( outfile, "build/sharing1.tex" );
24 outfile | "\\begin{cquote}";
25 outfile | "\\begin{tabular}{@{}rlll@{}}";
26 outfile | "\t\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
27 outfile | xstr(S1) | "\t& @\"" | s1 | "\"@\t\\\\";
28 outfile | xstr(S1A) | "\t& \t& @\"" | s1a | "\"@\t\\\\";
29 outfile | xstr(S2) | "\t& \t& \t& @\"" | s2 | "\"@";
30 outfile | "\\end{tabular}";
31 outfile | "\\end{cquote}";
32 close( outfile );
33
34// sout | "Aliasing (@`share@) means that changes flow in both directions; with a simple copy, they do not.";
35 open( outfile, "build/sharing2.tex" );
36 outfile | "\\begin{cquote}";
37 outfile | "\\begin{tabular}{@{}rlll@{}}";
38 outfile | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
39 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
40
41 #define S1s1 s1[1] = '+'
42 S1s1;
43 assert( s1 == "a+c" );
44 outfile | xstr(S1s1) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
45
46 #define S1As1 s1a[1] = '-'
47 S1As1;
48 assert( s1a == "a-c" );
49 outfile | xstr(S1As1) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
50
51 #define S2s1 s2[1] = '|'
52 S2s1;
53 assert( s2 == "a|c" );
54 outfile | xstr(S2s1) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@";
55 outfile | "\\end{tabular}";
56 outfile | "\\end{cquote}";
57 close( outfile );
58
59// sout | "Assignment of a value is just a modificiation."
60// "\nThe aliasing relationship is established at construction and is unaffected by assignment of a value.";
61 open( outfile, "build/sharing3.tex" );
62 outfile | "\\begin{cquote}";
63 outfile | "\\begin{tabular}{@{}rlll@{}}";
64 outfile | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
65 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
66
67 #define S1qrs s1 = "qrs"
68 S1qrs;
69 assert( s1 == "qrs" );
70 outfile | xstr(S1qrs) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
71
72 #define S1Atuv s1a = "tuv"
73 S1Atuv;
74 assert( s1a == "tuv" );
75 outfile | xstr(S1Atuv) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
76
77 #define S2wxy s2 = "wxy"
78 S2wxy;
79 assert( s2 == "wxy" );
80 outfile | xstr(S2wxy) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@";
81 outfile | "\\end{tabular}";
82 outfile | "\\end{cquote}";
83 close( outfile );
84
85// sout | "Assignment from a string is just assignment of a value."
86// "\nWhether of not the RHS participates in aliasing is irrelevant. Any aliasing of the LHS is unaffected.";
87 open( outfile, "build/sharing4.tex" );
88 outfile | "\\begin{cquote}";
89 outfile | "\\begin{tabular}{@{}rlll@{}}";
90 outfile | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
91 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
92
93 #define S1S2 s1 = s2
94 S1S2;
95 assert( s1 == "wxy" );
96 assert( s1a == "wxy" );
97 assert( s2 == "wxy" );
98 outfile | xstr(S1S2) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
99
100 #define S1aaa s1 = "aaa"
101 S1aaa;
102 assert( s1 == "aaa" );
103 assert( s1a == "aaa" );
104 assert( s2 == "wxy" );
105 outfile | xstr(S1aaa) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
106
107 #define S2S1 s2 = s1
108 S2S1;
109 assert( s1 == "aaa" );
110 assert( s1a == "aaa" );
111 assert( s2 == "aaa" );
112 outfile | xstr(S2S1) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
113
114 #define S2bbb s2 = "bbb"
115 S2bbb;
116 assert( s1 == "aaa" );
117 assert( s1a == "aaa" );
118 assert( s2 == "bbb" );
119 outfile | xstr(S2bbb) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
120
121 #define S2S1a s2 = s1a
122 S2S1a;
123 assert( s1 == "aaa" );
124 assert( s1a == "aaa" );
125 assert( s2 == "aaa" );
126 outfile | xstr(S2S1a) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
127
128 #define S2ccc s2 = "ccc"
129 S2ccc;
130 assert( s1 == "aaa" );
131 assert( s1a == "aaa" );
132 assert( s2 == "ccc" );
133 outfile | xstr(S2ccc) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@\t\\\\";
134
135 #define S1xxx s1 = "xxx"
136 S1xxx;
137 assert( s1 == "xxx" );
138 assert( s1a == "xxx" );
139 assert( s2 == "ccc" );
140 outfile | xstr(S1xxx) | "\t& @\"" | s1 | "\"@\t& @\"" | s1a | "\"@\t& @\"" | s2 | "\"@";
141 outfile | "\\end{tabular}";
142 outfile | "\\end{cquote}";
143 close( outfile );
144}
145
146
147void demo2() {
148// sout | "Consider new strings @s1_mid@ being an alias for a run in the middle of @s1@, along with @s2@, made by a simple copy from the middle of @s1@.";
149 open( outfile, "build/sharing5.tex" );
150 outfile | "\\begin{cquote}";
151 outfile | "\\begin{tabular}{@{}rlll@{}}";
152 outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
153
154 #define D2_s1_abcd string s1 = "abcd"
155 D2_s1_abcd;
156 outfile | xstr(D2_s1_abcd) | "\t& @\"" | s1 | "\"@\t\\\\";
157
158 #define D2_s1mid_s1 string s1_mid = s1(1,2)`share
159 D2_s1mid_s1;
160 outfile | xstr(D2_s1mid_s1) | "\t& \t& @\"" | s1_mid | "\"@\t\\\\";
161
162 #define D2_s2_s1 string s2 = s1_mid(0,2)
163 D2_s2_s1;
164 assert( s1 == "abcd" );
165 assert( s1_mid == "bc" );
166 assert( s2 == "bc" );
167 outfile | xstr(D2_s2_s1) | "\t& \t& \t& @\"" | s2 | "\"@";
168 outfile | "\\end{tabular}";
169 outfile | "\\end{cquote}";
170 close( outfile );
171
172// sout | "Again, @`share@ passes changes in both directions; copy does not. Note the difference in index values, with the \\emph{b} position being 1 in the longer string and 0 in the shorter strings. In the case of s1 aliasing with @s1_mid@, the very same character is being accessed by different postitions.";
173 open( outfile, "build/sharing6.tex" );
174 outfile | "\\begin{cquote}";
175 outfile | "\\begin{tabular}{@{}rlll@{}}";
176 outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
177 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t\\\\";
178
179 #define D2_s1_plus s1 [1] = '+'
180 D2_s1_plus;
181 assert( s1 == "a+cd" );
182 assert( s1_mid == "+c" );
183 assert( s2 == "bc" );
184 outfile | xstr(D2_s1_plus) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t\\\\";
185
186 #define D2_s1mid_minus s1_mid[0] = '-'
187 D2_s1mid_minus;
188 assert( s1 == "a-cd" );
189 assert( s1_mid == "-c" );
190 assert( s2 == "bc" );
191 outfile | xstr(D2_s1mid_minus) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t\\\\";
192
193 #define D2_s2_pipe s2 [0] = '|'
194 D2_s2_pipe;
195 assert( s1 == "a-cd" );
196 assert( s1_mid == "-c" );
197 assert( s2 == "|c" );
198 outfile | xstr(D2_s2_pipe) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t";
199 outfile | "\\end{tabular}";
200 outfile | "\\end{cquote}";
201 close( outfile );
202
203// sout | "Once again, assignment of a value is a modificiation that flows through the aliasing relationship, without affecting its structure.";
204 open( outfile, "build/sharing7.tex" );
205 outfile | "\\begin{cquote}";
206 outfile | "\\begin{tabular}{@{}rlll@{}}";
207 outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
208 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t\\\\";
209
210 #define D2_s1mid_ff s1_mid = "ff"
211 D2_s1mid_ff;
212 assert( s1 == "affd" );
213 assert( s1_mid == "ff" );
214 assert( s2 == "|c" );
215 outfile | xstr(D2_s1mid_ff) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t\\\\";
216
217 #define D2_s2_gg s2 = "gg"
218 D2_s2_gg;
219 assert( s1 == "affd" );
220 assert( s1_mid == "ff" );
221 assert( s2 == "gg" );
222 outfile | xstr(D2_s2_gg) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s2 | "\"@\t";
223 outfile | "\\end{tabular}";
224 outfile | "\\end{cquote}";
225 close( outfile );
226
227// sout | "In the \\emph{ff} step, which is a positive example of flow across an aliasing relationship, the result is straightforward to accept because the flow direction is from contained (small) to containing (large). The following rules for edits through aliasing substrings will guide how to flow in the opposite direction.";
228// sout | "\\par";
229
230
231// sout | "Growth and shrinkage are natural extensions. An empty substring is a real thing, at a well-defined location, whose meaning is extrapolated from the examples so far. The intended metaphor is to operating a GUI text editor. Having an aliasing substring is like using the mouse to select a few words. Assigning onto an aliasign substring is like typing from having a few words selected: depending how much you type, the file being edited can get shorter or longer.";
232 open( outfile, "build/sharing8.tex" );
233 outfile | "\\begin{cquote}";
234 outfile | "\\begin{tabular}{@{}rll@{}}";
235 outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t\\\\";
236 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t\\\\";
237
238 assert( s1 == "affd" );
239// assert( s1_mid == "fc" ); // ????????? bug?
240// outfile | xstr(D2_s2_gg) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t\\\\";
241
242 #define D2_s1mid_hhhh s1_mid = "hhhh"
243 D2_s1mid_hhhh;
244 assert( s1 == "ahhhhd" );
245 assert( s1_mid == "hhhh" );
246 outfile | xstr(D2_s1mid_hhhh) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t\\\\";
247
248 #define D2_s1mid_i s1_mid = "i"
249 D2_s1mid_i;
250 assert( s1 == "aid" );
251 assert( s1_mid == "i" );
252 outfile | xstr(D2_s1mid_i) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t\\\\";
253
254 #define D2_s1mid_empty s1_mid = ""
255 D2_s1mid_empty;
256 assert( s1 == "ad" );
257 // assert( s1_mid == "" ); ------ Should be so, but fails
258 outfile | xstr(D2_s1mid_empty) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t\\\\";
259
260 #define D2_s1mid_jj s1_mid = "jj"
261 D2_s1mid_jj;
262 assert( s1 == "ajjd" );
263 assert( s1_mid == "jj" );
264 outfile | xstr(D2_s1mid_jj) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_mid | "\"@\t";
265 outfile | "\\end{tabular}";
266 outfile | "\\end{cquote}";
267 close( outfile );
268
269// sout | "Multiple portions can be aliased. When there are several aliasing substrings at once, the text editor analogy becomes an online multi-user editor. I should be able to edit a paragraph in one place (changing the document's length), without my edits affecting which letters are within a mouse-selection that you had made previously, somewhere else.";
270 open( outfile, "build/sharing9.tex" );
271 outfile | "\\begin{cquote}";
272 outfile | "\\begin{tabular}{@{}rllll@{}}";
273 outfile | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_mid@\t& @s1_end@\t\\\\";
274 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& & @\"" | s1_mid | "\"@\t\\\\";
275
276 #define D2_s1bgn_s1 string s1_bgn = s1(0, 1)`share
277 D2_s1bgn_s1;
278 outfile | xstr(D2_s1bgn_s1) | "\t& \t& @\"" | s1_bgn | "\"@\t\\\\";
279
280 #define D2_s1end_s1 string s1_end = s1(3, 1)`share
281 D2_s1end_s1;
282 outfile | xstr(D2_s1end_s1) | "\t& \t& \t& \t& @\"" | s1_end | "\"@\t\\\\";
283 assert( s1 == "ajjd" );
284 assert( s1_bgn == "a" );
285 assert( s1_mid == "jj" );
286 assert( s1_end == "d" );
287
288 #define D1_s1bgn_zzz s1_bgn = "zzzz"
289 D1_s1bgn_zzz;
290 assert( s1 == "zzzzjjd" );
291 assert( s1_bgn == "zzzz" );
292 assert( s1_mid == "jj" );
293 assert( s1_end == "d" );
294 outfile | xstr(D1_s1bgn_zzz) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_bgn | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s1_end | "\"@\t";
295 outfile | "\\end{tabular}";
296 outfile | "\\end{cquote}";
297 close( outfile );
298
299// sout | "When an edit happens on an aliasing substring that overlaps another, an effect is unavoidable. Here, the passive party sees its selection shortened, to exclude the characters that were not part of the original selection.";
300 open( outfile, "build/sharing10.tex" );
301 outfile | "\\begin{cquote}";
302 outfile | "\\begin{tabular}{@{}rlllll@{}}";
303 outfile | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_crs@\t& @s1_mid@\t& @s1_end@\t\\\\";
304 outfile | "\\multicolumn{1}{r}{initial} & @\"" | s1 | "\"@\t& @\"" | s1_bgn | "\"@\t& & @\"" | s1_mid | "\"@\t& @\"" | s1_end | "\"@\t\\\\";
305
306 #define D2_s1crs_s1 string s1_crs = s1(3, 2)`share
307 D2_s1crs_s1;
308 assert( s1 == "zzzzjjd" );
309 assert( s1_bgn == "zzzz" );
310 assert( s1_crs == "zj" );
311 assert( s1_mid == "jj" );
312 assert( s1_end == "d" );
313 outfile | xstr(D2_s1crs_s1) | "\t& \t& \t& @\"" | s1_crs | "\"@\t\\\\";
314
315 #define D2_s1crs_ppp s1_crs = "+++"
316 D2_s1crs_ppp;
317 assert( s1 == "zzz+++jd" );
318 assert( s1_bgn == "zzz" );
319 assert( s1_crs == "+++" );
320 assert( s1_mid == "j" );
321 assert( s1_end == "d" );
322 outfile | xstr(D2_s1crs_ppp) | "\t& @\"" | s1 | "\"@\t& @\"" | s1_bgn | "\"@\t& @\"" | s1_crs | "\"@\t& @\"" | s1_mid | "\"@\t& @\"" | s1_end | "\"@\t";
323 outfile | "\\end{tabular}";
324 outfile | "\\end{cquote}";
325 close( outfile );
326
327 // "This shortening behaviour means that a modification has to occur entirely inside a substring, to show up in that substring. Sharing changes through the intersection of partially overlapping aliases is still possible, so long as the receiver's boundary is not inside the edit."
328
329 string word = "Phi";
330 string consonants = word(0,2)`share;
331 string miniscules = word(1,2)`share;
332 assert( word == "Phi" );
333 assert( consonants == "Ph" );
334 assert( miniscules == "hi" );
335
336 consonants[1] = 's';
337 assert( word == "Psi" );
338 assert( consonants == "Ps" );
339 assert( miniscules == "si" );
340
341 // "The extreme form of this shortening happens when a bystander alias is a proper substring of an edit. The bystander becomes an empty substring."
342
343 string all = "They said hello again";
344 string greet = all(10,5)`share;
345 string greet_bgn = all(10,1)`share;
346 string greet_end = all(14,1)`share;
347
348 assert( all == "They said hello again" );
349 assert( greet == "hello" );
350 assert( greet_bgn == "h" );
351 assert( greet_end == "o" );
352
353
354 greet = "sup";
355 assert( all == "They said sup again" );
356 assert( greet == "sup" );
357 // assert( greet_bgn == "" ); ------ Should be so, but fails
358 // assert( greet_end == "" );
359
360
361
362
363
364 /* As in the earlier step where \emph{aj} becomes \emph{ajjd}, such empty substrings maintain their places in the total string, and can be used for filling it. Because @greet_bgn@ was orginally at the start of the edit, in the outcome, the empty @greet_bgn@ sits just before the written value. Similarly @greed_end@ goes after. Though not shown, an overwritten substring at neither side goes arbitrarily to the before side. */
365
366
367
368
369 greet_bgn = "what";
370
371
372 assert( all == "They said whatsup again" );
373
374 assert( greet == "sup" );
375
376 assert( greet_bgn == "what" );
377 // assert( greet_end == "" ); ------ Should be so, but fails
378
379
380 greet_end = "...";
381
382
383 assert( all == "They said whatsup... again" );
384
385 assert( greet == "sup" );
386
387 assert( greet_bgn == "what" );
388
389 assert( greet_end == "..." );
390
391
392
393
394
395 /* Though these empty substrings hold their places in the total string, an empty string only belongs to bigger strings when it occurs completely inside them. There is no such state as including an empty substring at an edge. For this reason, @word@ gains the characters added by assigning to @greet_bgn@ and @greet_end@, but the string @greet@ does not. */
396
397
398}
399
400
401int main(int argc, char ** argv) {
402
403 demo1();
404 demo2();
405// printf("%% %s done running\n", argv[0]);
406}
Note: See TracBrowser for help on using the repository browser.