git.fiddlerwoaroof.com
Browse code

feat(docs): update README, generate doc site and tests from it

Edward Langley authored on 16/03/2022 08:24:33
Showing 76 changed files
... ...
@@ -1,3 +1,8 @@
1
+#+TITLE: README for js-generic-functions
2
+#+AUTHOR: Ed L
3
+#+HTML_HEAD: <link rel="stylesheet" href="./colors.css"></link>
4
+#+EXPORT_FILE_NAME: docs/index.html
5
+
1 6
 * What is this?
2 7
 
3 8
 An implementation of generic functions based on CLOS and the protocols
... ...
@@ -13,18 +18,18 @@ between such specializers and subtyping are an open question.
13 18
 ** Basic Usage
14 19
 
15 20
 #+NAME: imports
16
-#+BEGIN_SRC js2
21
+#+BEGIN_SRC js
17 22
 import { defgeneric } from "./genfuns.js";
18 23
 #+END_SRC
19 24
 
20
-Defining a function works by calling src_js2{defgeneric} with some
25
+Defining a function works by calling src_js{defgeneric} with some
21 26
 information about the function name and arguments. Methods are then
22 27
 added by calling the appropriate methods with a pair of arguments: a
23 28
 list of specializers (prototypes in the simple case, although there
24 29
 are other options) and a function to run if those specializers match.
25 30
 
26 31
 #+NAME: basic-definition
27
-#+BEGIN_SRC js2
32
+#+BEGIN_SRC js
28 33
   const example1generic = defgeneric("example1", "a", "b")
29 34
     .primary([Number, Object], (n, __) => [1, n])
30 35
     .primary([Object, Number], (_, n) => [2, n])
... ...
@@ -32,10 +37,10 @@ are other options) and a function to run if those specializers match.
32 37
 #+END_SRC
33 38
 
34 39
 After a generic function has been defined, you can get the function to
35
-call it by accessing its src_js2{.fn} attribute.
40
+call it by accessing its src_js{.fn} attribute.
36 41
 
37 42
 #+NAME: call-the-function
38
-#+BEGIN_SRC js2
43
+#+BEGIN_SRC js
39 44
   const example1 = example1generic.fn;
40 45
 
41 46
   expect(example1(5, {})).toEqual([1, 5]);
... ...
@@ -49,7 +54,7 @@ If a separate reference to the generic function object is maintained,
49 54
 you can add methods like so:
50 55
 
51 56
 #+NAME: add-methods
52
-#+BEGIN_SRC js2
57
+#+BEGIN_SRC js
53 58
   example1generic
54 59
     .primary([String, Object], (s, __) => [3, s])
55 60
     .primary([Object, String], (_, s) => [4, s]);
... ...
@@ -58,8 +63,33 @@ you can add methods like so:
58 63
   expect(example1({}, "world")).toEqual([4, "world"]);
59 64
 #+END_SRC
60 65
 
66
+** Other sorts of specializers
67
+#+NAME: specializer-import
68
+#+BEGIN_SRC js
69
+  import { Shape, Eql } from "./genfuns.js";
70
+#+END_SRC
71
+
72
+
73
+
74
+#+NAME: specializer-examples
75
+#+BEGIN_SRC js
76
+  const example2 = defgeneric("example2", "inp")
77
+    .primary([Shape("a", "b")], inp => `a: ${inp.a} b: ${inp.b}`)
78
+    .primary([Shape("a")], inp => `a: ${inp.a} b: <missing>`)
79
+    .primary([Shape(["c", 1])], inp => `c: one`)
80
+    .primary([Shape(["c", 2])], inp => `c: two`)
81
+    .primary([Eql(1)], inp => "one").fn;
82
+
83
+  expect(example2({ a: 3, q: "whatever" })).toEqual("a: 3 b: <missing>");
84
+  expect(example2({ a: 3, b: 4, q: "whatever" })).toEqual("a: 3 b: 4");
85
+  expect(example2({ c: 1, q: "whatever" })).toEqual("c: one");
86
+  expect(example2({ c: 2, q: "whatever" })).toEqual("c: two");
87
+  expect(example2(1)).toEqual("one");
88
+#+END_SRC
89
+
61 90
 #+BEGIN_SRC js :tangle src/doc.test.js :comments noweb :noweb tangle :exports none
62 91
   <<imports>>
92
+  <<specializer-import>>
63 93
 
64 94
   describe("defgeneric", () => {
65 95
     test("methods get called appropriately", () => {
... ...
@@ -71,5 +101,8 @@ you can add methods like so:
71 101
 
72 102
       <<sample1>>
73 103
     });
104
+    test ('specializers work as expected', () => {
105
+      <<specializer-examples>>
106
+    })
74 107
   });
75 108
 #+END_SRC
76 109
new file mode 100644
... ...
@@ -0,0 +1,88 @@
1
+@import url(./latofonts.css);
2
+
3
+:root {
4
+  --zenburn-fg-plus-2: #ffffef;
5
+  --zenburn-fg-plus-1: #f5f5d6;
6
+  --zenburn-fg: #dcdccc;
7
+  --zenburn-fg-1: #a6a689;
8
+  --zenburn-fg-2: #656555;
9
+  --zenburn-black: #000000;
10
+  --zenburn-bg-2: #000000;
11
+  --zenburn-bg-1: #111112;
12
+  --zenburn-bg-05: #383838;
13
+  --zenburn-bg: #2a2b2e;
14
+  --zenburn-bg-plus-05: #494949;
15
+  --zenburn-bg-plus-1: #4f4f4f;
16
+  --zenburn-bg-plus-2: #5f5f5f;
17
+  --zenburn-bg-plus-3: #6f6f6f;
18
+  --zenburn-red-plus-2: #ecb3b3;
19
+  --zenburn-red-plus-1: #dca3a3;
20
+  --zenburn-red: #cc9393;
21
+  --zenburn-red-1: #bc8383;
22
+  --zenburn-red-2: #ac7373;
23
+  --zenburn-red-3: #9c6363;
24
+  --zenburn-red-4: #8c5353;
25
+  --zenburn-red-5: #7c4343;
26
+  --zenburn-red-6: #6c3333;
27
+  --zenburn-orange: #dfaf8f;
28
+  --zenburn-yellow: #f0dfaf;
29
+  --zenburn-yellow-1: #e0cf9f;
30
+  --zenburn-yellow-2: #d0bf8f;
31
+  --zenburn-green-5: #2f4f2f;
32
+  --zenburn-green-4: #3f5f3f;
33
+  --zenburn-green-3: #4f6f4f;
34
+  --zenburn-green-2: #5f7f5f;
35
+  --zenburn-green-1: #6f8f6f;
36
+  --zenburn-green: #7f9f7f;
37
+  --zenburn-green-plus-1: #8fb28f;
38
+  --zenburn-green-plus-2: #9fc59f;
39
+  --zenburn-green-plus-3: #afd8af;
40
+  --zenburn-green-plus-4: #bfebbf;
41
+  --zenburn-cyan: #93e0e3;
42
+  --zenburn-blue-plus-3: #bde0f3;
43
+  --zenburn-blue-plus-2: #ace0e3;
44
+  --zenburn-blue-plus-1: #94bff3;
45
+  --zenburn-blue: #8cd0d3;
46
+  --zenburn-blue-1: #7cb8bb;
47
+  --zenburn-blue-2: #6ca0a3;
48
+  --zenburn-blue-3: #5c888b;
49
+  --zenburn-blue-4: #4c7073;
50
+  --zenburn-blue-5: #366060;
51
+  --zenburn-magenta: #dc8cc3;
52
+}
53
+
54
+html {
55
+  --background: var(--zenburn-bg);
56
+  --foreground: var(--zenburn-fg);
57
+  --background-hl: var(--zenburn-bg-plus-1);
58
+  --foreground-hl: var(--zenburn-fg-plus-1);
59
+  --accent: var(--zenburn-green);
60
+  --link: var(--zenburn-blue);
61
+}
62
+
63
+body {
64
+  background: var(--background);
65
+  color: var(--foreground);
66
+}
67
+
68
+pre {
69
+  background: var(--background-hl);
70
+  color: var(--foreground-hl);
71
+}
72
+
73
+h1,
74
+h2,
75
+h3,
76
+h4,
77
+h5,
78
+h6 {
79
+  color: var(--accent);
80
+}
81
+
82
+body {
83
+  font-family: "LatoWeb", sans-serif;
84
+}
85
+
86
+a {
87
+  color: var(--link);
88
+}
0 89
new file mode 100644
1 90
Binary files /dev/null and b/docs/fonts/Lato-Black.eot differ
2 91
new file mode 100644
3 92
Binary files /dev/null and b/docs/fonts/Lato-Black.ttf differ
4 93
new file mode 100644
5 94
Binary files /dev/null and b/docs/fonts/Lato-Black.woff differ
6 95
new file mode 100644
7 96
Binary files /dev/null and b/docs/fonts/Lato-Black.woff2 differ
8 97
new file mode 100644
9 98
Binary files /dev/null and b/docs/fonts/Lato-BlackItalic.eot differ
10 99
new file mode 100644
11 100
Binary files /dev/null and b/docs/fonts/Lato-BlackItalic.ttf differ
12 101
new file mode 100644
13 102
Binary files /dev/null and b/docs/fonts/Lato-BlackItalic.woff differ
14 103
new file mode 100644
15 104
Binary files /dev/null and b/docs/fonts/Lato-BlackItalic.woff2 differ
16 105
new file mode 100644
17 106
Binary files /dev/null and b/docs/fonts/Lato-Bold.eot differ
18 107
new file mode 100644
19 108
Binary files /dev/null and b/docs/fonts/Lato-Bold.ttf differ
20 109
new file mode 100644
21 110
Binary files /dev/null and b/docs/fonts/Lato-Bold.woff differ
22 111
new file mode 100644
23 112
Binary files /dev/null and b/docs/fonts/Lato-Bold.woff2 differ
24 113
new file mode 100644
25 114
Binary files /dev/null and b/docs/fonts/Lato-BoldItalic.eot differ
26 115
new file mode 100644
27 116
Binary files /dev/null and b/docs/fonts/Lato-BoldItalic.ttf differ
28 117
new file mode 100644
29 118
Binary files /dev/null and b/docs/fonts/Lato-BoldItalic.woff differ
30 119
new file mode 100644
31 120
Binary files /dev/null and b/docs/fonts/Lato-BoldItalic.woff2 differ
32 121
new file mode 100644
33 122
Binary files /dev/null and b/docs/fonts/Lato-Hairline.eot differ
34 123
new file mode 100644
35 124
Binary files /dev/null and b/docs/fonts/Lato-Hairline.ttf differ
36 125
new file mode 100644
37 126
Binary files /dev/null and b/docs/fonts/Lato-Hairline.woff differ
38 127
new file mode 100644
39 128
Binary files /dev/null and b/docs/fonts/Lato-Hairline.woff2 differ
40 129
new file mode 100644
41 130
Binary files /dev/null and b/docs/fonts/Lato-HairlineItalic.eot differ
42 131
new file mode 100644
43 132
Binary files /dev/null and b/docs/fonts/Lato-HairlineItalic.ttf differ
44 133
new file mode 100644
45 134
Binary files /dev/null and b/docs/fonts/Lato-HairlineItalic.woff differ
46 135
new file mode 100644
47 136
Binary files /dev/null and b/docs/fonts/Lato-HairlineItalic.woff2 differ
48 137
new file mode 100644
49 138
Binary files /dev/null and b/docs/fonts/Lato-Heavy.eot differ
50 139
new file mode 100644
51 140
Binary files /dev/null and b/docs/fonts/Lato-Heavy.ttf differ
52 141
new file mode 100644
53 142
Binary files /dev/null and b/docs/fonts/Lato-Heavy.woff differ
54 143
new file mode 100644
55 144
Binary files /dev/null and b/docs/fonts/Lato-Heavy.woff2 differ
56 145
new file mode 100644
57 146
Binary files /dev/null and b/docs/fonts/Lato-HeavyItalic.eot differ
58 147
new file mode 100644
59 148
Binary files /dev/null and b/docs/fonts/Lato-HeavyItalic.ttf differ
60 149
new file mode 100644
61 150
Binary files /dev/null and b/docs/fonts/Lato-HeavyItalic.woff differ
62 151
new file mode 100644
63 152
Binary files /dev/null and b/docs/fonts/Lato-HeavyItalic.woff2 differ
64 153
new file mode 100644
65 154
Binary files /dev/null and b/docs/fonts/Lato-Italic.eot differ
66 155
new file mode 100644
67 156
Binary files /dev/null and b/docs/fonts/Lato-Italic.ttf differ
68 157
new file mode 100644
69 158
Binary files /dev/null and b/docs/fonts/Lato-Italic.woff differ
70 159
new file mode 100644
71 160
Binary files /dev/null and b/docs/fonts/Lato-Italic.woff2 differ
72 161
new file mode 100644
73 162
Binary files /dev/null and b/docs/fonts/Lato-Light.eot differ
74 163
new file mode 100644
75 164
Binary files /dev/null and b/docs/fonts/Lato-Light.ttf differ
76 165
new file mode 100644
77 166
Binary files /dev/null and b/docs/fonts/Lato-Light.woff differ
78 167
new file mode 100644
79 168
Binary files /dev/null and b/docs/fonts/Lato-Light.woff2 differ
80 169
new file mode 100644
81 170
Binary files /dev/null and b/docs/fonts/Lato-LightItalic.eot differ
82 171
new file mode 100644
83 172
Binary files /dev/null and b/docs/fonts/Lato-LightItalic.ttf differ
84 173
new file mode 100644
85 174
Binary files /dev/null and b/docs/fonts/Lato-LightItalic.woff differ
86 175
new file mode 100644
87 176
Binary files /dev/null and b/docs/fonts/Lato-LightItalic.woff2 differ
88 177
new file mode 100644
89 178
Binary files /dev/null and b/docs/fonts/Lato-Medium.eot differ
90 179
new file mode 100644
91 180
Binary files /dev/null and b/docs/fonts/Lato-Medium.ttf differ
92 181
new file mode 100644
93 182
Binary files /dev/null and b/docs/fonts/Lato-Medium.woff differ
94 183
new file mode 100644
95 184
Binary files /dev/null and b/docs/fonts/Lato-Medium.woff2 differ
96 185
new file mode 100644
97 186
Binary files /dev/null and b/docs/fonts/Lato-MediumItalic.eot differ
98 187
new file mode 100644
99 188
Binary files /dev/null and b/docs/fonts/Lato-MediumItalic.ttf differ
100 189
new file mode 100644
101 190
Binary files /dev/null and b/docs/fonts/Lato-MediumItalic.woff differ
102 191
new file mode 100644
103 192
Binary files /dev/null and b/docs/fonts/Lato-MediumItalic.woff2 differ
104 193
new file mode 100644
105 194
Binary files /dev/null and b/docs/fonts/Lato-Regular.eot differ
106 195
new file mode 100644
107 196
Binary files /dev/null and b/docs/fonts/Lato-Regular.ttf differ
108 197
new file mode 100644
109 198
Binary files /dev/null and b/docs/fonts/Lato-Regular.woff differ
110 199
new file mode 100644
111 200
Binary files /dev/null and b/docs/fonts/Lato-Regular.woff2 differ
112 201
new file mode 100644
113 202
Binary files /dev/null and b/docs/fonts/Lato-Semibold.eot differ
114 203
new file mode 100644
115 204
Binary files /dev/null and b/docs/fonts/Lato-Semibold.ttf differ
116 205
new file mode 100644
117 206
Binary files /dev/null and b/docs/fonts/Lato-Semibold.woff differ
118 207
new file mode 100644
119 208
Binary files /dev/null and b/docs/fonts/Lato-Semibold.woff2 differ
120 209
new file mode 100644
121 210
Binary files /dev/null and b/docs/fonts/Lato-SemiboldItalic.eot differ
122 211
new file mode 100644
123 212
Binary files /dev/null and b/docs/fonts/Lato-SemiboldItalic.ttf differ
124 213
new file mode 100644
125 214
Binary files /dev/null and b/docs/fonts/Lato-SemiboldItalic.woff differ
126 215
new file mode 100644
127 216
Binary files /dev/null and b/docs/fonts/Lato-SemiboldItalic.woff2 differ
128 217
new file mode 100644
129 218
Binary files /dev/null and b/docs/fonts/Lato-Thin.eot differ
130 219
new file mode 100644
131 220
Binary files /dev/null and b/docs/fonts/Lato-Thin.ttf differ
132 221
new file mode 100644
133 222
Binary files /dev/null and b/docs/fonts/Lato-Thin.woff differ
134 223
new file mode 100644
135 224
Binary files /dev/null and b/docs/fonts/Lato-Thin.woff2 differ
136 225
new file mode 100644
137 226
Binary files /dev/null and b/docs/fonts/Lato-ThinItalic.eot differ
138 227
new file mode 100644
139 228
Binary files /dev/null and b/docs/fonts/Lato-ThinItalic.ttf differ
140 229
new file mode 100644
141 230
Binary files /dev/null and b/docs/fonts/Lato-ThinItalic.woff differ
142 231
new file mode 100644
143 232
Binary files /dev/null and b/docs/fonts/Lato-ThinItalic.woff2 differ
144 233
new file mode 100644
... ...
@@ -0,0 +1,327 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
+<head>
6
+<!-- 2022-03-16 Wed 01:22 -->
7
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
+<meta name="viewport" content="width=device-width, initial-scale=1" />
9
+<title>README for js-generic-functions</title>
10
+<meta name="author" content="Ed L" />
11
+<meta name="generator" content="Org Mode" />
12
+<style>
13
+  #content { max-width: 60em; margin: auto; }
14
+  .title  { text-align: center;
15
+             margin-bottom: .2em; }
16
+  .subtitle { text-align: center;
17
+              font-size: medium;
18
+              font-weight: bold;
19
+              margin-top:0; }
20
+  .todo   { font-family: monospace; color: red; }
21
+  .done   { font-family: monospace; color: green; }
22
+  .priority { font-family: monospace; color: orange; }
23
+  .tag    { background-color: #eee; font-family: monospace;
24
+            padding: 2px; font-size: 80%; font-weight: normal; }
25
+  .timestamp { color: #bebebe; }
26
+  .timestamp-kwd { color: #5f9ea0; }
27
+  .org-right  { margin-left: auto; margin-right: 0px;  text-align: right; }
28
+  .org-left   { margin-left: 0px;  margin-right: auto; text-align: left; }
29
+  .org-center { margin-left: auto; margin-right: auto; text-align: center; }
30
+  .underline { text-decoration: underline; }
31
+  #postamble p, #preamble p { font-size: 90%; margin: .2em; }
32
+  p.verse { margin-left: 3%; }
33
+  pre {
34
+    border: 1px solid #e6e6e6;
35
+    border-radius: 3px;
36
+    background-color: #f2f2f2;
37
+    padding: 8pt;
38
+    font-family: monospace;
39
+    overflow: auto;
40
+    margin: 1.2em;
41
+  }
42
+  pre.src {
43
+    position: relative;
44
+    overflow: auto;
45
+  }
46
+  pre.src:before {
47
+    display: none;
48
+    position: absolute;
49
+    top: -8px;
50
+    right: 12px;
51
+    padding: 3px;
52
+    color: #555;
53
+    background-color: #f2f2f299;
54
+  }
55
+  pre.src:hover:before { display: inline; margin-top: 14px;}
56
+  /* Languages per Org manual */
57
+  pre.src-asymptote:before { content: 'Asymptote'; }
58
+  pre.src-awk:before { content: 'Awk'; }
59
+  pre.src-authinfo::before { content: 'Authinfo'; }
60
+  pre.src-C:before { content: 'C'; }
61
+  /* pre.src-C++ doesn't work in CSS */
62
+  pre.src-clojure:before { content: 'Clojure'; }
63
+  pre.src-css:before { content: 'CSS'; }
64
+  pre.src-D:before { content: 'D'; }
65
+  pre.src-ditaa:before { content: 'ditaa'; }
66
+  pre.src-dot:before { content: 'Graphviz'; }
67
+  pre.src-calc:before { content: 'Emacs Calc'; }
68
+  pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
69
+  pre.src-fortran:before { content: 'Fortran'; }
70
+  pre.src-gnuplot:before { content: 'gnuplot'; }
71
+  pre.src-haskell:before { content: 'Haskell'; }
72
+  pre.src-hledger:before { content: 'hledger'; }
73
+  pre.src-java:before { content: 'Java'; }
74
+  pre.src-js:before { content: 'Javascript'; }
75
+  pre.src-latex:before { content: 'LaTeX'; }
76
+  pre.src-ledger:before { content: 'Ledger'; }
77
+  pre.src-lisp:before { content: 'Lisp'; }
78
+  pre.src-lilypond:before { content: 'Lilypond'; }
79
+  pre.src-lua:before { content: 'Lua'; }
80
+  pre.src-matlab:before { content: 'MATLAB'; }
81
+  pre.src-mscgen:before { content: 'Mscgen'; }
82
+  pre.src-ocaml:before { content: 'Objective Caml'; }
83
+  pre.src-octave:before { content: 'Octave'; }
84
+  pre.src-org:before { content: 'Org mode'; }
85
+  pre.src-oz:before { content: 'OZ'; }
86
+  pre.src-plantuml:before { content: 'Plantuml'; }
87
+  pre.src-processing:before { content: 'Processing.js'; }
88
+  pre.src-python:before { content: 'Python'; }
89
+  pre.src-R:before { content: 'R'; }
90
+  pre.src-ruby:before { content: 'Ruby'; }
91
+  pre.src-sass:before { content: 'Sass'; }
92
+  pre.src-scheme:before { content: 'Scheme'; }
93
+  pre.src-screen:before { content: 'Gnu Screen'; }
94
+  pre.src-sed:before { content: 'Sed'; }
95
+  pre.src-sh:before { content: 'shell'; }
96
+  pre.src-sql:before { content: 'SQL'; }
97
+  pre.src-sqlite:before { content: 'SQLite'; }
98
+  /* additional languages in org.el's org-babel-load-languages alist */
99
+  pre.src-forth:before { content: 'Forth'; }
100
+  pre.src-io:before { content: 'IO'; }
101
+  pre.src-J:before { content: 'J'; }
102
+  pre.src-makefile:before { content: 'Makefile'; }
103
+  pre.src-maxima:before { content: 'Maxima'; }
104
+  pre.src-perl:before { content: 'Perl'; }
105
+  pre.src-picolisp:before { content: 'Pico Lisp'; }
106
+  pre.src-scala:before { content: 'Scala'; }
107
+  pre.src-shell:before { content: 'Shell Script'; }
108
+  pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
109
+  /* additional language identifiers per "defun org-babel-execute"
110
+       in ob-*.el */
111
+  pre.src-cpp:before  { content: 'C++'; }
112
+  pre.src-abc:before  { content: 'ABC'; }
113
+  pre.src-coq:before  { content: 'Coq'; }
114
+  pre.src-groovy:before  { content: 'Groovy'; }
115
+  /* additional language identifiers from org-babel-shell-names in
116
+     ob-shell.el: ob-shell is the only babel language using a lambda to put
117
+     the execution function name together. */
118
+  pre.src-bash:before  { content: 'bash'; }
119
+  pre.src-csh:before  { content: 'csh'; }
120
+  pre.src-ash:before  { content: 'ash'; }
121
+  pre.src-dash:before  { content: 'dash'; }
122
+  pre.src-ksh:before  { content: 'ksh'; }
123
+  pre.src-mksh:before  { content: 'mksh'; }
124
+  pre.src-posh:before  { content: 'posh'; }
125
+  /* Additional Emacs modes also supported by the LaTeX listings package */
126
+  pre.src-ada:before { content: 'Ada'; }
127
+  pre.src-asm:before { content: 'Assembler'; }
128
+  pre.src-caml:before { content: 'Caml'; }
129
+  pre.src-delphi:before { content: 'Delphi'; }
130
+  pre.src-html:before { content: 'HTML'; }
131
+  pre.src-idl:before { content: 'IDL'; }
132
+  pre.src-mercury:before { content: 'Mercury'; }
133
+  pre.src-metapost:before { content: 'MetaPost'; }
134
+  pre.src-modula-2:before { content: 'Modula-2'; }
135
+  pre.src-pascal:before { content: 'Pascal'; }
136
+  pre.src-ps:before { content: 'PostScript'; }
137
+  pre.src-prolog:before { content: 'Prolog'; }
138
+  pre.src-simula:before { content: 'Simula'; }
139
+  pre.src-tcl:before { content: 'tcl'; }
140
+  pre.src-tex:before { content: 'TeX'; }
141
+  pre.src-plain-tex:before { content: 'Plain TeX'; }
142
+  pre.src-verilog:before { content: 'Verilog'; }
143
+  pre.src-vhdl:before { content: 'VHDL'; }
144
+  pre.src-xml:before { content: 'XML'; }
145
+  pre.src-nxml:before { content: 'XML'; }
146
+  /* add a generic configuration mode; LaTeX export needs an additional
147
+     (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
148
+  pre.src-conf:before { content: 'Configuration File'; }
149
+
150
+  table { border-collapse:collapse; }
151
+  caption.t-above { caption-side: top; }
152
+  caption.t-bottom { caption-side: bottom; }
153
+  td, th { vertical-align:top;  }
154
+  th.org-right  { text-align: center;  }
155
+  th.org-left   { text-align: center;   }
156
+  th.org-center { text-align: center; }
157
+  td.org-right  { text-align: right;  }
158
+  td.org-left   { text-align: left;   }
159
+  td.org-center { text-align: center; }
160
+  dt { font-weight: bold; }
161
+  .footpara { display: inline; }
162
+  .footdef  { margin-bottom: 1em; }
163
+  .figure { padding: 1em; }
164
+  .figure p { text-align: center; }
165
+  .equation-container {
166
+    display: table;
167
+    text-align: center;
168
+    width: 100%;
169
+  }
170
+  .equation {
171
+    vertical-align: middle;
172
+  }
173
+  .equation-label {
174
+    display: table-cell;
175
+    text-align: right;
176
+    vertical-align: middle;
177
+  }
178
+  .inlinetask {
179
+    padding: 10px;
180
+    border: 2px solid gray;
181
+    margin: 10px;
182
+    background: #ffffcc;
183
+  }
184
+  #org-div-home-and-up
185
+   { text-align: right; font-size: 70%; white-space: nowrap; }
186
+  textarea { overflow-x: auto; }
187
+  .linenr { font-size: smaller }
188
+  .code-highlighted { background-color: #ffff00; }
189
+  .org-info-js_info-navigation { border-style: none; }
190
+  #org-info-js_console-label
191
+    { font-size: 10px; font-weight: bold; white-space: nowrap; }
192
+  .org-info-js_search-highlight
193
+    { background-color: #ffff00; color: #000000; font-weight: bold; }
194
+  .org-svg { width: 90%; }
195
+</style>
196
+<link rel="stylesheet" href="./colors.css"></link>
197
+</head>
198
+<body>
199
+<div id="content" class="content">
200
+<h1 class="title">README for js-generic-functions</h1>
201
+<div id="table-of-contents" role="doc-toc">
202
+<h2>Table of Contents</h2>
203
+<div id="text-table-of-contents" role="doc-toc">
204
+<ul>
205
+<li><a href="#orgfafc37c">1. What is this?</a></li>
206
+<li><a href="#org9f23f39">2. Docs</a>
207
+<ul>
208
+<li><a href="#orgd157493">2.1. Basic Usage</a></li>
209
+<li><a href="#orgfff236b">2.2. Other sorts of specializers</a></li>
210
+</ul>
211
+</li>
212
+</ul>
213
+</div>
214
+</div>
215
+
216
+<div id="outline-container-orgfafc37c" class="outline-2">
217
+<h2 id="orgfafc37c"><span class="section-number-2">1.</span> What is this?</h2>
218
+<div class="outline-text-2" id="text-1">
219
+<p>
220
+An implementation of generic functions based on CLOS and the protocols
221
+defined in the Art of the Metaobject protocol, adapted for JS.  These
222
+adaptations include using the prototype chain instead of classes and
223
+additionally providing extensible specializers (as in
224
+<a href="https://github.com/sbcl/specializable">https://github.com/sbcl/specializable</a>). For the moment, this is only
225
+used to provide a Shape specializer, as the details of the interaction
226
+between such specializers and subtyping are an open question.
227
+</p>
228
+</div>
229
+</div>
230
+
231
+<div id="outline-container-org9f23f39" class="outline-2">
232
+<h2 id="org9f23f39"><span class="section-number-2">2.</span> Docs</h2>
233
+<div class="outline-text-2" id="text-2">
234
+</div>
235
+<div id="outline-container-orgd157493" class="outline-3">
236
+<h3 id="orgd157493"><span class="section-number-3">2.1.</span> Basic Usage</h3>
237
+<div class="outline-text-3" id="text-2-1">
238
+<div class="org-src-container">
239
+<pre class="src src-js" id="org5053093"><span style="color: #F0DFAF;">import</span> { defgeneric } from <span style="color: #D0BF8F;">"./genfuns.js"</span>;
240
+</pre>
241
+</div>
242
+
243
+<p>
244
+Defining a function works by calling with some
245
+information about the function name and arguments. Methods are then
246
+added by calling the appropriate methods with a pair of arguments: a
247
+list of specializers (prototypes in the simple case, although there
248
+are other options) and a function to run if those specializers match.
249
+</p>
250
+
251
+<div class="org-src-container">
252
+<pre class="src src-js" id="orgbfcefb2"><span style="color: #F0DFAF;">const</span> <span style="color: #DC8CC3;">example1generic</span> = defgeneric(<span style="color: #D0BF8F;">"example1"</span>, <span style="color: #D0BF8F;">"a"</span>, <span style="color: #D0BF8F;">"b"</span>)
253
+  .primary([Number, Object], (n, __) =&gt; [1, n])
254
+  .primary([Object, Number], (_, n) =&gt; [2, n])
255
+  .primary([Object, Object], (_, __) =&gt; [5, <span style="font-weight: bold;">null</span>]);
256
+</pre>
257
+</div>
258
+
259
+<p>
260
+After a generic function has been defined, you can get the function to
261
+call it by accessing its attribute.
262
+</p>
263
+
264
+<div class="org-src-container">
265
+<pre class="src src-js" id="orgcb5dfea"><span style="color: #F0DFAF;">const</span> <span style="color: #DC8CC3;">example1</span> = example1generic.fn;
266
+
267
+expect(example1(5, {})).toEqual([1, 5]);
268
+expect(example1({}, 6)).toEqual([2, 6]);
269
+expect(example1(<span style="color: #D0BF8F;">"hello"</span>, {})).toEqual([5, <span style="font-weight: bold;">null</span>]);
270
+expect(example1({}, <span style="color: #D0BF8F;">"world"</span>)).toEqual([5, <span style="font-weight: bold;">null</span>]);
271
+expect(example1({}, {})).toEqual([5, <span style="font-weight: bold;">null</span>]);
272
+</pre>
273
+</div>
274
+
275
+<p>
276
+If a separate reference to the generic function object is maintained,
277
+you can add methods like so:
278
+</p>
279
+
280
+<div class="org-src-container">
281
+<pre class="src src-js" id="orgda77441">example1generic
282
+  .primary([String, Object], (s, __) =&gt; [3, s])
283
+  .primary([Object, String], (_, s) =&gt; [4, s]);
284
+
285
+expect(example1(<span style="color: #D0BF8F;">"hello"</span>, {})).toEqual([3, <span style="color: #D0BF8F;">"hello"</span>]);
286
+expect(example1({}, <span style="color: #D0BF8F;">"world"</span>)).toEqual([4, <span style="color: #D0BF8F;">"world"</span>]);
287
+</pre>
288
+</div>
289
+</div>
290
+</div>
291
+
292
+<div id="outline-container-orgfff236b" class="outline-3">
293
+<h3 id="orgfff236b"><span class="section-number-3">2.2.</span> Other sorts of specializers</h3>
294
+<div class="outline-text-3" id="text-2-2">
295
+<div class="org-src-container">
296
+<pre class="src src-js" id="org0346038"><span style="color: #F0DFAF;">import</span> { Shape, Eql } from <span style="color: #D0BF8F;">"./genfuns.js"</span>;
297
+</pre>
298
+</div>
299
+
300
+
301
+
302
+<div class="org-src-container">
303
+<pre class="src src-js" id="org89b4645"><span style="color: #F0DFAF;">const</span> <span style="color: #DC8CC3;">example2</span> = defgeneric(<span style="color: #D0BF8F;">"example2"</span>, <span style="color: #D0BF8F;">"inp"</span>)
304
+  .primary([Shape(<span style="color: #D0BF8F;">"a"</span>, <span style="color: #D0BF8F;">"b"</span>)], inp =&gt; <span style="color: #D0BF8F;">`a: ${inp.a} b: ${inp.b}`</span>)
305
+  .primary([Shape(<span style="color: #D0BF8F;">"a"</span>)], inp =&gt; <span style="color: #D0BF8F;">`a: ${inp.a} b: &lt;missing&gt;`</span>)
306
+  .primary([Shape([<span style="color: #D0BF8F;">"c"</span>, 1])], inp =&gt; <span style="color: #D0BF8F;">`c: one`</span>)
307
+  .primary([Shape([<span style="color: #D0BF8F;">"c"</span>, 2])], inp =&gt; <span style="color: #D0BF8F;">`c: two`</span>)
308
+  .primary([Eql(1)], inp =&gt; <span style="color: #D0BF8F;">"one"</span>).fn;
309
+
310
+expect(example2({ a: 3, q: <span style="color: #D0BF8F;">"whatever"</span> })).toEqual(<span style="color: #D0BF8F;">"a: 3 b: &lt;missing&gt;"</span>);
311
+expect(example2({ a: 3, b: 4, q: <span style="color: #D0BF8F;">"whatever"</span> })).toEqual(<span style="color: #D0BF8F;">"a: 3 b: 4"</span>);
312
+expect(example2({ c: 1, q: <span style="color: #D0BF8F;">"whatever"</span> })).toEqual(<span style="color: #D0BF8F;">"c: one"</span>);
313
+expect(example2({ c: 2, q: <span style="color: #D0BF8F;">"whatever"</span> })).toEqual(<span style="color: #D0BF8F;">"c: two"</span>);
314
+expect(example2(1)).toEqual(<span style="color: #D0BF8F;">"one"</span>);
315
+</pre>
316
+</div>
317
+</div>
318
+</div>
319
+</div>
320
+</div>
321
+<div id="postamble" class="status">
322
+<p class="author">Author: Ed L</p>
323
+<p class="date">Created: 2022-03-16 Wed 01:22</p>
324
+<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
325
+</div>
326
+</body>
327
+</html>
0 328
new file mode 100644
... ...
@@ -0,0 +1,56 @@
1
+// [[file:../README.org::*Other sorts of specializers][Other sorts of specializers:3]]
2
+// [[[[file:~/git_repos/git.fiddlerwoaroof.com/js-generic-functions/README.org::imports][imports]]][imports]]
3
+import { defgeneric } from "./genfuns.js";
4
+// imports ends here
5
+// [[[[file:~/git_repos/git.fiddlerwoaroof.com/js-generic-functions/README.org::specializer-import][specializer-import]]][specializer-import]]
6
+import { Shape, Eql } from "./genfuns.js";
7
+// specializer-import ends here
8
+
9
+describe("defgeneric", () => {
10
+  test("methods get called appropriately", () => {
11
+    // [[[[file:~/git_repos/git.fiddlerwoaroof.com/js-generic-functions/README.org::basic-definition][basic-definition]]][basic-definition]]
12
+    const example1generic = defgeneric("example1", "a", "b")
13
+      .primary([Number, Object], (n, __) => [1, n])
14
+      .primary([Object, Number], (_, n) => [2, n])
15
+      .primary([Object, Object], (_, __) => [5, null]);
16
+    // basic-definition ends here
17
+
18
+    // [[[[file:~/git_repos/git.fiddlerwoaroof.com/js-generic-functions/README.org::call-the-function][call-the-function]]][call-the-function]]
19
+    const example1 = example1generic.fn;
20
+    
21
+    expect(example1(5, {})).toEqual([1, 5]);
22
+    expect(example1({}, 6)).toEqual([2, 6]);
23
+    expect(example1("hello", {})).toEqual([5, null]);
24
+    expect(example1({}, "world")).toEqual([5, null]);
25
+    expect(example1({}, {})).toEqual([5, null]);
26
+    // call-the-function ends here
27
+
28
+    // [[[[file:~/git_repos/git.fiddlerwoaroof.com/js-generic-functions/README.org::add-methods][add-methods]]][add-methods]]
29
+    example1generic
30
+      .primary([String, Object], (s, __) => [3, s])
31
+      .primary([Object, String], (_, s) => [4, s]);
32
+    
33
+    expect(example1("hello", {})).toEqual([3, "hello"]);
34
+    expect(example1({}, "world")).toEqual([4, "world"]);
35
+    // add-methods ends here
36
+
37
+    
38
+  });
39
+  test ('specializers work as expected', () => {
40
+    // [[[[file:~/git_repos/git.fiddlerwoaroof.com/js-generic-functions/README.org::specializer-examples][specializer-examples]]][specializer-examples]]
41
+    const example2 = defgeneric("example2", "inp")
42
+      .primary([Shape("a", "b")], inp => `a: ${inp.a} b: ${inp.b}`)
43
+      .primary([Shape("a")], inp => `a: ${inp.a} b: <missing>`)
44
+      .primary([Shape(["c", 1])], inp => `c: one`)
45
+      .primary([Shape(["c", 2])], inp => `c: two`)
46
+      .primary([Eql(1)], inp => "one").fn;
47
+    
48
+    expect(example2({ a: 3, q: "whatever" })).toEqual("a: 3 b: <missing>");
49
+    expect(example2({ a: 3, b: 4, q: "whatever" })).toEqual("a: 3 b: 4");
50
+    expect(example2({ c: 1, q: "whatever" })).toEqual("c: one");
51
+    expect(example2({ c: 2, q: "whatever" })).toEqual("c: two");
52
+    expect(example2(1)).toEqual("one");
53
+    // specializer-examples ends here
54
+  })
55
+});
56
+// Other sorts of specializers:3 ends here