@thi.ng/pointfree 3.1.53 → 3.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-12-03T12:13:31Z
3
+ - **Last updated**: 2023-12-11T10:07:09Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
package/README.md CHANGED
@@ -213,7 +213,7 @@ For Node.js REPL:
213
213
  const pointfree = await import("@thi.ng/pointfree");
214
214
  ```
215
215
 
216
- Package sizes (brotli'd, pre-treeshake): ESM: 3.24 KB
216
+ Package sizes (brotli'd, pre-treeshake): ESM: 3.23 KB
217
217
 
218
218
  ## Dependencies
219
219
 
package/api.js CHANGED
@@ -1 +0,0 @@
1
- export {};
package/array.js CHANGED
@@ -6,372 +6,164 @@ import { defOp1, defOp2, defOp2v } from "./ops.js";
6
6
  import { $, $n } from "./safe.js";
7
7
  import { invrot, swap } from "./stack.js";
8
8
  import { $stackFn, defWord } from "./word.js";
9
- //////////////////// Array / list ops ////////////////////
10
- /**
11
- * Pushes a new empty array on the d-stack. While it's easily possible to
12
- * use `[]` as part of a stack program, the `list` word is intended to
13
- * be used as part of re-usuable {@link word} definitions to ensure a new
14
- * array is being created for every single invocation of the word (else
15
- * only a single instance is created due to the mutable nature of JS
16
- * arrays).
17
- *
18
- * Compare:
19
- *
20
- * ```
21
- * // using array literal within word definition
22
- * foo = pf.word([ [], 1, pf.pushl ])
23
- * pf.runU(foo)
24
- * // [ 1 ]
25
- * pf.runU(foo)
26
- * // [ 1, 1 ] // wrong!
27
- *
28
- * // using `list` instead
29
- * bar = pf.word([ pf.list, 1, pf.pushl ])
30
- * pf.runU(bar)
31
- * // [ 1 ]
32
- * pf.runU(bar)
33
- * // [ 1 ] // correct!
34
- * ```
35
- *
36
- * ( -- [] )
37
- *
38
- * @param ctx -
39
- */
40
- export const list = (ctx) => (ctx[0].push([]), ctx);
41
- /**
42
- * Pushes new empty JS object on d-stack.
43
- * Same reasoning as for {@link list}.
44
- *
45
- * ( -- {} )
46
- *
47
- * @param ctx -
48
- */
49
- export const obj = (ctx) => (ctx[0].push({}), ctx);
50
- /**
51
- * Pushes `val` on the LHS of array.
52
- *
53
- * ( val arr -- arr )
54
- *
55
- * @param ctx -
56
- */
57
- export const pushl = (ctx) => {
58
- $(ctx[0], 2);
59
- const stack = ctx[0];
60
- const a = stack.pop();
61
- a.unshift(stack.pop());
62
- stack.push(a);
63
- return ctx;
9
+ const list = (ctx) => (ctx[0].push([]), ctx);
10
+ const obj = (ctx) => (ctx[0].push({}), ctx);
11
+ const pushl = (ctx) => {
12
+ $(ctx[0], 2);
13
+ const stack = ctx[0];
14
+ const a = stack.pop();
15
+ a.unshift(stack.pop());
16
+ stack.push(a);
17
+ return ctx;
64
18
  };
65
- /**
66
- * Pushes `val` on the RHS of array.
67
- *
68
- * ( arr val -- arr )
69
- *
70
- * @param ctx -
71
- */
72
- export const pushr = (ctx) => {
73
- const stack = ctx[0];
74
- const n = stack.length - 2;
75
- $n(n, 0);
76
- stack[n].push(stack[n + 1]);
77
- stack.length--;
78
- return ctx;
19
+ const pushr = (ctx) => {
20
+ const stack = ctx[0];
21
+ const n = stack.length - 2;
22
+ $n(n, 0);
23
+ stack[n].push(stack[n + 1]);
24
+ stack.length--;
25
+ return ctx;
79
26
  };
80
- /**
81
- * Removes RHS from array as new TOS on d-stack.
82
- * Throws error is `arr` is empty.
83
- *
84
- * ( arr -- arr arr[-1] )
85
- *
86
- * @param ctx -
87
- */
88
- export const popr = (ctx) => {
89
- const stack = ctx[0];
90
- const n = stack.length - 1;
91
- $n(n, 0);
92
- const a = stack[n];
93
- !a.length && illegalState("can't pop empty array");
94
- stack.push(a.pop());
95
- return ctx;
27
+ const popr = (ctx) => {
28
+ const stack = ctx[0];
29
+ const n = stack.length - 1;
30
+ $n(n, 0);
31
+ const a = stack[n];
32
+ !a.length && illegalState("can't pop empty array");
33
+ stack.push(a.pop());
34
+ return ctx;
96
35
  };
97
- export const pull = defWord([popr, swap]);
98
- export const pull2 = defWord([pull, pull]);
99
- export const pull3 = defWord([pull2, pull]);
100
- export const pull4 = defWord([pull2, pull2]);
101
- export const vadd = defOp2v((b, a) => a + b);
102
- export const vsub = defOp2v((b, a) => a - b);
103
- export const vmul = defOp2v((b, a) => a * b);
104
- export const vdiv = defOp2v((b, a) => a / b);
105
- /**
106
- * Splits vector / array at given index `x`.
107
- *
108
- * ( arr x -- [...] [...] )
109
- *
110
- * @param ctx -
111
- */
112
- export const split = (ctx) => {
113
- const stack = ctx[0];
114
- const n = stack.length - 2;
115
- $n(n, 0);
116
- const a = stack[n];
117
- const b = stack[n + 1];
118
- stack[n + 1] = a.splice(b, a.length - b);
119
- return ctx;
36
+ const pull = defWord([popr, swap]);
37
+ const pull2 = defWord([pull, pull]);
38
+ const pull3 = defWord([pull2, pull]);
39
+ const pull4 = defWord([pull2, pull2]);
40
+ const vadd = defOp2v((b, a) => a + b);
41
+ const vsub = defOp2v((b, a) => a - b);
42
+ const vmul = defOp2v((b, a) => a * b);
43
+ const vdiv = defOp2v((b, a) => a / b);
44
+ const split = (ctx) => {
45
+ const stack = ctx[0];
46
+ const n = stack.length - 2;
47
+ $n(n, 0);
48
+ const a = stack[n];
49
+ const b = stack[n + 1];
50
+ stack[n + 1] = a.splice(b, a.length - b);
51
+ return ctx;
120
52
  };
121
- /**
122
- * Concatenates `arr2` onto `arr1`:
123
- *
124
- * ( arr1 arr2 -- arr )
125
- *
126
- * @param ctx -
127
- */
128
- export const cat = (ctx) => {
129
- const stack = ctx[0];
130
- const n = stack.length - 2;
131
- $n(n, 0);
132
- stack[n] = stack[n].concat(stack.pop());
133
- return ctx;
53
+ const cat = (ctx) => {
54
+ const stack = ctx[0];
55
+ const n = stack.length - 2;
56
+ $n(n, 0);
57
+ stack[n] = stack[n].concat(stack.pop());
58
+ return ctx;
134
59
  };
135
- /**
136
- * Similar to {@link cat}, but concatenates `arr1` onto `arr2`:
137
- *
138
- * ( arr1 arr2 -- arr )
139
- *
140
- * @param ctx -
141
- */
142
- export const catr = (ctx) => {
143
- const stack = ctx[0];
144
- const n = stack.length - 2;
145
- $n(n, 0);
146
- stack[n] = stack.pop().concat(stack[n]);
147
- return ctx;
60
+ const catr = (ctx) => {
61
+ const stack = ctx[0];
62
+ const n = stack.length - 2;
63
+ $n(n, 0);
64
+ stack[n] = stack.pop().concat(stack[n]);
65
+ return ctx;
148
66
  };
149
- /**
150
- * Generic array transformer.
151
- *
152
- * ( arr q -- ? )
153
- *
154
- * Pops both args from d-stack, then executes quotation for each array
155
- * item (each pushed on d-stack prior to calling quotation). Can produce
156
- * any number of results and therefore also be used as filter, mapcat,
157
- * reduce...
158
- *
159
- * ```
160
- * // each item times 10
161
- * run([[1, 2, 3, 4], [10, mul], mapl])
162
- * // [ [ 10, 20, 30, 40 ], [], {} ]
163
- * ```
164
- *
165
- * Use for filtering:
166
- *
167
- * ```
168
- * // drop even numbers, duplicate odd ones
169
- * run([[1, 2, 3, 4], [dup, even, cond(drop, dup)], mapl])
170
- * // [ [ 1, 1, 3, 3 ], [], {} ]
171
- * ```
172
- *
173
- * Reduction:
174
- *
175
- * ```
176
- * // the `0` is the initial reduction result
177
- * runU([0, [1, 2, 3, 4], [add], mapl])
178
- * // 10
179
- * ```
180
- *
181
- * **Important**: {@link mapl} does not produce a result array. However,
182
- * there're several options to collect results as array, e.g.
183
- *
184
- * Use {@link mapll} to transform:
185
- *
186
- * @example
187
- * ```ts
188
- * runU([[1, 2, 3, 4], [10, mul], mapll])
189
- * // [ 10, 20, 30, 40]
190
- * ```
191
- *
192
- * Collecting results as array is a form of reduction, so we can use
193
- * {@link list} to produce an initial new array and {@link pushr} to push each new
194
- * interim value into the result:
195
- *
196
- * @example
197
- * ```ts
198
- * runU([list, [1, 2, 3, 4], [10, mul, pushr], mapl])
199
- * // [ 10, 20, 30, 40 ]
200
- * ```
201
- *
202
- * If the array size is known & not changed by transformation:
203
- *
204
- * @example
205
- * ```ts
206
- * runU([[1, 2, 3, 4], [10, mul], mapl, 4, collect])
207
- * // [ 10, 20, 30, 40 ]
208
- * ```
209
- *
210
- * @param ctx -
211
- */
212
- export const mapl = (ctx) => {
213
- $(ctx[0], 2);
214
- const stack = ctx[0];
215
- const w = $stackFn(stack.pop());
216
- const list = stack.pop();
217
- const n = list.length;
218
- for (let i = 0; i < n; i++) {
219
- ctx[0].push(list[i]);
220
- ctx = w(ctx);
221
- }
222
- return ctx;
67
+ const mapl = (ctx) => {
68
+ $(ctx[0], 2);
69
+ const stack = ctx[0];
70
+ const w = $stackFn(stack.pop());
71
+ const list2 = stack.pop();
72
+ const n = list2.length;
73
+ for (let i = 0; i < n; i++) {
74
+ ctx[0].push(list2[i]);
75
+ ctx = w(ctx);
76
+ }
77
+ return ctx;
223
78
  };
224
- /**
225
- * Similar to {@link mapl}, but produces new array of transformed values.
226
- *
227
- * ( arr q -- arr )
228
- *
229
- * @example
230
- * ```ts
231
- * runU([[1, 2, 3, 4], [10, mul], mapll])
232
- * // [ 10, 20, 30, 40]
233
- * ```
234
- *
235
- * Filter / mapcat:
236
- *
237
- * ```
238
- * // drop even numbers, duplicate odd ones
239
- * run([[1, 2, 3, 4], [dup, even, cond(drop, dup)], mapll])
240
- * // [ [ [ 1, 1, 3, 3 ] ], [], {} ]
241
- * ```
242
- *
243
- * @param ctx -
244
- */
245
- export const mapll = (ctx) => {
246
- $(ctx[0], 2);
247
- let stack = ctx[0];
248
- const w = $stackFn(stack.pop());
249
- const list = stack.pop();
250
- const n = list.length;
251
- let r = 0;
252
- for (let i = 0; i < n; i++) {
253
- let m = stack.length;
254
- stack.push(list[i]);
255
- ctx = w(ctx);
256
- stack = ctx[0];
257
- r += stack.length - m;
258
- }
259
- stack.push(stack.splice(stack.length - r, r));
260
- return ctx;
79
+ const mapll = (ctx) => {
80
+ $(ctx[0], 2);
81
+ let stack = ctx[0];
82
+ const w = $stackFn(stack.pop());
83
+ const list2 = stack.pop();
84
+ const n = list2.length;
85
+ let r = 0;
86
+ for (let i = 0; i < n; i++) {
87
+ let m = stack.length;
88
+ stack.push(list2[i]);
89
+ ctx = w(ctx);
90
+ stack = ctx[0];
91
+ r += stack.length - m;
92
+ }
93
+ stack.push(stack.splice(stack.length - r, r));
94
+ return ctx;
261
95
  };
262
- /**
263
- * Convenience wrapper for {@link mapl} to provide an alternative stack layout
264
- * for reduction purposes:
265
- *
266
- * ( arr q init -- reduction )
267
- */
268
- export const foldl = defWord([invrot, mapl]);
269
- /**
270
- * Pops TOS (a number) and then forms a tuple of the top `n` remaining
271
- * values and pushes it as new TOS. The original collected stack values
272
- * are removed from d-stack.
273
- *
274
- * ( ... n --- ... [...] )
275
- *
276
- * @param ctx -
277
- */
278
- export const collect = (ctx) => {
279
- const stack = ctx[0];
280
- let n = stack.length - 1, m;
281
- $n(n, 0);
282
- $n((n -= m = stack.pop()), 0);
283
- stack.push(stack.splice(n, m));
284
- return ctx;
96
+ const foldl = defWord([invrot, mapl]);
97
+ const collect = (ctx) => {
98
+ const stack = ctx[0];
99
+ let n = stack.length - 1, m;
100
+ $n(n, 0);
101
+ $n(n -= m = stack.pop(), 0);
102
+ stack.push(stack.splice(n, m));
103
+ return ctx;
285
104
  };
286
- /**
287
- * Higher order helper word to {@link collect} tuples of pre-defined size
288
- * `n`. The size can be given as number or a stack function producing a
289
- * number.
290
- *
291
- * ( ... -- [...])
292
- *
293
- * @param n -
294
- */
295
- export const defTuple = (n) => defWord([n, collect]);
296
- export const vec2 = defTuple(2);
297
- export const vec3 = defTuple(3);
298
- export const vec4 = defTuple(4);
299
- /**
300
- * Higher order helper word to convert a TOS tuple/array into a string
301
- * using `Array.join()` with given `sep`arator.
302
- *
303
- * @param sep -
304
- */
305
- export const defJoin = (sep = "") => defOp1((x) => x.join(sep));
306
- export const join = defOp2((sep, buf) => buf.join(sep));
307
- /**
308
- * Pushes length of TOS on d-stack.
309
- *
310
- * ( x -- x.length )
311
- *
312
- * @param ctx -
313
- */
314
- export const length = defOp1((x) => x.length);
315
- /**
316
- * Replaces TOS with its shallow copy. MUST be an array or plain object.
317
- *
318
- * ( x -- copy )
319
- */
320
- export const copy = defOp1((x) => isArray(x)
321
- ? x.slice()
322
- : isPlainObject(x)
323
- ? { ...x }
324
- : illegalArgs(`can't copy type ${typeof x}`));
325
- /**
326
- * Reads key/index from object/array.
327
- *
328
- * ( obj k -- obj[k] )
329
- *
330
- * @param ctx -
331
- */
332
- export const at = defOp2((b, a) => a[b]);
333
- /**
334
- * Writes `val` at key/index in object/array.
335
- *
336
- * ( val obj k -- obj )
337
- *
338
- * @param ctx -
339
- */
340
- export const setat = (ctx) => {
341
- const stack = ctx[0];
342
- const n = stack.length - 3;
343
- $n(n, 0);
344
- stack[n + 1][stack[n + 2]] = stack[n];
345
- stack[n] = stack[n + 1];
346
- stack.length -= 2;
347
- return ctx;
105
+ const defTuple = (n) => defWord([n, collect]);
106
+ const vec2 = defTuple(2);
107
+ const vec3 = defTuple(3);
108
+ const vec4 = defTuple(4);
109
+ const defJoin = (sep = "") => defOp1((x) => x.join(sep));
110
+ const join = defOp2((sep, buf) => buf.join(sep));
111
+ const length = defOp1((x) => x.length);
112
+ const copy = defOp1(
113
+ (x) => isArray(x) ? x.slice() : isPlainObject(x) ? { ...x } : illegalArgs(`can't copy type ${typeof x}`)
114
+ );
115
+ const at = defOp2((b, a) => a[b]);
116
+ const setat = (ctx) => {
117
+ const stack = ctx[0];
118
+ const n = stack.length - 3;
119
+ $n(n, 0);
120
+ stack[n + 1][stack[n + 2]] = stack[n];
121
+ stack[n] = stack[n + 1];
122
+ stack.length -= 2;
123
+ return ctx;
348
124
  };
349
- //////////////////// Objects ////////////////////
350
- /**
351
- * Takes an array of keys and target object, then pops & binds deeper
352
- * stack values to respective keys in object. Pushes result object back
353
- * on stack at the end. Throws error if there're less stack values than
354
- * keys in given array.
355
- *
356
- * @example
357
- * ```ts
358
- * runU([1,2,3, ["a","b","c"], {}, bindkeys])
359
- * // { c: 3, b: 2, a: 1 }
360
- * ```
361
- *
362
- * (v1 v2 .. [k1 k2 ..] obj -- obj )
363
- *
364
- * @param ctx -
365
- */
366
- export const bindkeys = (ctx) => {
367
- const stack = ctx[0];
368
- $(stack, 2);
369
- const obj = stack.pop();
370
- const keys = stack.pop();
371
- $(stack, keys.length);
372
- for (let i = keys.length - 1; i >= 0; i--) {
373
- obj[keys[i]] = stack.pop();
374
- }
375
- stack.push(obj);
376
- return ctx;
125
+ const bindkeys = (ctx) => {
126
+ const stack = ctx[0];
127
+ $(stack, 2);
128
+ const obj2 = stack.pop();
129
+ const keys = stack.pop();
130
+ $(stack, keys.length);
131
+ for (let i = keys.length - 1; i >= 0; i--) {
132
+ obj2[keys[i]] = stack.pop();
133
+ }
134
+ stack.push(obj2);
135
+ return ctx;
136
+ };
137
+ export {
138
+ at,
139
+ bindkeys,
140
+ cat,
141
+ catr,
142
+ collect,
143
+ copy,
144
+ defJoin,
145
+ defTuple,
146
+ foldl,
147
+ join,
148
+ length,
149
+ list,
150
+ mapl,
151
+ mapll,
152
+ obj,
153
+ popr,
154
+ pull,
155
+ pull2,
156
+ pull3,
157
+ pull4,
158
+ pushl,
159
+ pushr,
160
+ setat,
161
+ split,
162
+ vadd,
163
+ vdiv,
164
+ vec2,
165
+ vec3,
166
+ vec4,
167
+ vmul,
168
+ vsub
377
169
  };
package/binary.js CHANGED
@@ -1,44 +1,17 @@
1
1
  import { defOp1, defOp2 } from "./ops.js";
2
- //////////////////// Binary ops ////////////////////
3
- /**
4
- * ( x y -- x&y )
5
- *
6
- * @param ctx -
7
- */
8
- export const bitand = defOp2((b, a) => a & b);
9
- /**
10
- * ( x y -- x|y )
11
- *
12
- * @param ctx -
13
- */
14
- export const bitor = defOp2((b, a) => a | b);
15
- /**
16
- * ( x y -- x^y )
17
- *
18
- * @param ctx -
19
- */
20
- export const bitxor = defOp2((b, a) => a ^ b);
21
- /**
22
- * ( x -- ~x )
23
- *
24
- * @param ctx -
25
- */
26
- export const bitnot = defOp1((x) => ~x);
27
- /**
28
- * ( x y -- x<<y )
29
- *
30
- * @param ctx -
31
- */
32
- export const lsl = defOp2((b, a) => a << b);
33
- /**
34
- * ( x y -- x>>y )
35
- *
36
- * @param ctx -
37
- */
38
- export const lsr = defOp2((b, a) => a >> b);
39
- /**
40
- * ( x y -- x>>>y )
41
- *
42
- * @param ctx -
43
- */
44
- export const lsru = defOp2((b, a) => a >>> b);
2
+ const bitand = defOp2((b, a) => a & b);
3
+ const bitor = defOp2((b, a) => a | b);
4
+ const bitxor = defOp2((b, a) => a ^ b);
5
+ const bitnot = defOp1((x) => ~x);
6
+ const lsl = defOp2((b, a) => a << b);
7
+ const lsr = defOp2((b, a) => a >> b);
8
+ const lsru = defOp2((b, a) => a >>> b);
9
+ export {
10
+ bitand,
11
+ bitnot,
12
+ bitor,
13
+ bitxor,
14
+ lsl,
15
+ lsr,
16
+ lsru
17
+ };