functionalscript 0.3.11 → 0.3.13

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/fsm/module.f.js CHANGED
@@ -17,7 +17,7 @@ export const toUnion = s => {
17
17
  const codePoints = stringToList(s);
18
18
  return fold(toUnionOp)(empty)(codePoints);
19
19
  };
20
- const mergeOp = { union: sortedSetUnion(unsafeCmp), equal: equal(strictEqual) };
20
+ const mergeOp = { union: sortedSetUnion(unsafeCmp), equal: equal(strictEqual), def: [] };
21
21
  const hasState = s => set => !isEmpty(intersect(unsafeCmp)([s])(set));
22
22
  const foldOp = set => ([ruleIn, bs, ruleOut]) => rm => {
23
23
  if (hasState(ruleIn)(set)) {
@@ -0,0 +1 @@
1
+ type TerminalRange = readonly [number, number];
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ // JSON: https://www.json.org/json-en.html
3
+ {
4
+ // null, [0x09, 0x0A], 0x0D, 0x20
5
+ const ws = () => ({ or: [
6
+ [],
7
+ ['\t', ws], // 0x09
8
+ ['\n', ws], // 0x0A
9
+ ['\r', ws], // 0x0D
10
+ [' ', ws], // 0x20
11
+ ] });
12
+ // null, 0x2B, 0x2D
13
+ const sign = { or: [
14
+ [],
15
+ '+', // 0x2B
16
+ '-', // 0x2D
17
+ ] };
18
+ // null, [0x30, 0x39]
19
+ const digits1 = () => ({ or: [
20
+ [],
21
+ digits // [0x30, 0x39]
22
+ ] });
23
+ // [0x30, 0x39]
24
+ const digits = () => [digit, digits1];
25
+ // null, 0x45, 0x65
26
+ const exponent = { or: [
27
+ [],
28
+ ['E', sign, digits], // 0x45
29
+ ['e', sign, digits], // 0x65
30
+ ] };
31
+ // null, 0x2E
32
+ const fraction = { or: [
33
+ [],
34
+ ['.', digits] // 0x2E
35
+ ] };
36
+ // [0x31, 0x39]
37
+ const onenine = [0x31, 0x39];
38
+ // [0x30, 0x39]
39
+ const digit = { or: [
40
+ '0', // 0x30
41
+ onenine, // [0x31, 0x39]
42
+ ] };
43
+ // null, 0x2C
44
+ const members2 = () => ({ or: [
45
+ [],
46
+ [',', ws, members1], // 0x2C
47
+ ] });
48
+ // 0x22
49
+ const members1 = () => [member1, members2];
50
+ // 0x22, 0x7D
51
+ const object1 = { or: [
52
+ [members1, '}'], // 0x22
53
+ '}', // 0x7D
54
+ ] };
55
+ // 0x7B
56
+ const object = ['{', ws, object1];
57
+ // 0x22, 0x2D, [0x30, 0x39], 0x5B, 0x5D, 0x66, 0x6E, 0x74, 0x7B
58
+ const array1 = () => ({ or: [
59
+ [element1, ']'], // 0x22, 0x2D, [0x30, 0x39], 0x5B, 0x66, 0x6E, 0x74, 0x7B
60
+ ']', // 0x5D
61
+ ] });
62
+ // 0x5B
63
+ const array = ['[', ws, array1];
64
+ // [0x30, 0x39], [0x41, 0x46], [0x61, 0x66]
65
+ const hex = { or: [
66
+ digit, // [0x30, 0x39]
67
+ [0x41, 0x46], // A..F
68
+ [0x61, 0x66], // a..f
69
+ ] };
70
+ // 0x22, 0x2F, 0x5C, 0x62, 0x66, 0x6E, 0x72, [0x74, 0x75]
71
+ const escape = { or: [
72
+ '"', // 0x22
73
+ '/', // 0x2F
74
+ '\\', // 0x5C
75
+ 'b', // 0x62
76
+ 'f', // 0x66
77
+ 'n', // 0x6E
78
+ 'r', // 0x72
79
+ 't', // 0x74
80
+ ['u', hex, hex, hex, hex] // 0x75
81
+ ] };
82
+ // [0x20, 0x21], [0x23, 0x10FFFF]
83
+ const character = { or: [
84
+ [0x20, 0x21], // exclude '"' 0x22
85
+ [0x23, 0x5B], // exclude '\' 0x5C
86
+ [0x5D, 0x10FFFF], //
87
+ ['\\', escape], // 0x5C
88
+ ] };
89
+ // null, [0x20, 0x21], [0x23, 0x10FFFF]
90
+ const characters = () => ({ or: [
91
+ [],
92
+ [character, characters]
93
+ ] });
94
+ // 0x22
95
+ const string = ['"', characters, '"'];
96
+ // [0x30, 0x39]
97
+ const integer1 = { or: [
98
+ '0',
99
+ [onenine, digits1],
100
+ ] };
101
+ // 0x2D, [0x30, 0x39]
102
+ const integer = { or: [
103
+ ['-', integer1], // 0x2D
104
+ '0', // 0x30
105
+ [onenine, digits1], // [0x31, 0x39]
106
+ ] };
107
+ // 0x2D, [0x30, 0x39]
108
+ const number = [integer, fraction, exponent];
109
+ // 0x22, 0x2D, [0x30, 0x39], 0x5B, 0x66, 0x6E, 0x74, 0x7B
110
+ const value = { or: [
111
+ string, // 0x22
112
+ number, // 0x2D, [0x30, 0x39]
113
+ array, // 0x5B
114
+ 'false', // 0x66
115
+ 'null', // 0x6E
116
+ 'true', // 0x74
117
+ object, // 0x7B
118
+ ] };
119
+ // 0x22, 0x2D, [0x30, 0x39], 0x5B, 0x66, 0x6E, 0x74, 0x7B
120
+ const element1 = [value, ws];
121
+ // [0x09, 0x0A], 0x0D, 0x20, 0x22, 0x2D, [0x30, 0x39], 0x5B, 0x66, 0x6E, 0x74, 0x7B
122
+ const element = [ws, element1];
123
+ // 0x22
124
+ const member1 = [string, ws, ':', element];
125
+ const json = element;
126
+ }
127
+ // serializable
128
+ {
129
+ //
130
+ const element = { id: 'element' };
131
+ const ws = { id: 'ws' };
132
+ const value = { id: 'value' };
133
+ const object = { id: 'object' };
134
+ const array = { id: 'array' };
135
+ const string = { id: 'string' };
136
+ const number = { id: 'number' };
137
+ const members = { id: 'members' };
138
+ const characters = { id: 'characters' };
139
+ const integer = { id: 'integer' };
140
+ const fraction = { id: 'fraction' };
141
+ const exponent = { id: 'exponent' };
142
+ const member = { id: 'member' };
143
+ const character = { id: 'character' };
144
+ const digit = { id: 'digit' };
145
+ const onenine = { id: 'onenine' };
146
+ const digits = { id: 'digits' };
147
+ const sign = { id: 'sign' };
148
+ const escape = { id: 'escape' };
149
+ const hex = { id: 'hex' };
150
+ const map = {
151
+ json: element,
152
+ element: [ws, value, ws],
153
+ ws: { or: [
154
+ [],
155
+ [' ', ws],
156
+ ['\t', ws],
157
+ ['\n', ws],
158
+ ['\r', ws],
159
+ ] },
160
+ value: { or: [
161
+ object,
162
+ array,
163
+ string,
164
+ number,
165
+ 'true',
166
+ 'false',
167
+ 'null'
168
+ ] },
169
+ object: { or: [
170
+ ['{', ws, '}'],
171
+ ['{', members, '}'],
172
+ ] },
173
+ array: { or: [
174
+ ['[', ws, ']'],
175
+ ['[', element, ']'],
176
+ ] },
177
+ string: ['"', characters, '"'],
178
+ number: [integer, fraction, exponent],
179
+ members: { or: [
180
+ member,
181
+ [member, ',', members],
182
+ ] },
183
+ characters: { or: [
184
+ [],
185
+ [character, characters]
186
+ ] },
187
+ integer: { or: [
188
+ digit,
189
+ [onenine, digits],
190
+ ['-', digit],
191
+ ['-', onenine, digits],
192
+ ] },
193
+ fraction: { or: [
194
+ [],
195
+ ['.', digits]
196
+ ] },
197
+ exponent: { or: [
198
+ [],
199
+ ['E', sign, digits],
200
+ ['e', sign, digits],
201
+ ] },
202
+ member: [ws, string, ws, ':', element],
203
+ character: { or: [
204
+ [0x20, 0x21], // exclude '"' 0x22
205
+ [0x23, 0x5B], // exclude '\' 0x5C
206
+ [0x5D, 0x10FFFF],
207
+ ['\\', escape],
208
+ ] },
209
+ digit: { or: [
210
+ '0',
211
+ onenine,
212
+ ] },
213
+ onenine: [0x31, 0x39],
214
+ digits: { or: [
215
+ digit,
216
+ [digit, digits]
217
+ ] },
218
+ sign: { or: [
219
+ [],
220
+ '+',
221
+ '-',
222
+ ] },
223
+ escape: { or: [
224
+ '"',
225
+ '\\',
226
+ '/',
227
+ 'b',
228
+ 'f',
229
+ 'n',
230
+ 'r',
231
+ 't',
232
+ ['u', hex, hex, hex, hex]
233
+ ] },
234
+ hex: { or: [
235
+ digit,
236
+ [0x41, 0x46], // A..F
237
+ [0x61, 0x66], // a..f
238
+ ] },
239
+ };
240
+ const _map = map;
241
+ }
@@ -107,6 +107,7 @@ const union = def => a => b => {
107
107
  const rangeMapMerge = def => merge({
108
108
  union: union(def),
109
109
  equal: operator.strictEqual,
110
+ def,
110
111
  });
111
112
  const rangeFunc = r => f => def => fromRange(def)(r)(f);
112
113
  const scanRangeOp = def => f => [f(def), scanRangeOp(def)];
@@ -126,7 +127,11 @@ const create = (def) => (a) => {
126
127
  };
127
128
  const digitToBigInt = d => BigInt(d - digit0);
128
129
  const startNumber = digit => ({ s: 1n, m: digitToBigInt(digit), f: 0, es: 1, e: 0 });
129
- const startNegativeNumber = { s: -1n, m: 0n, f: 0, es: 1, e: 0 };
130
+ /*
131
+ const startNegativeNumber
132
+ : ParseNumberBuffer
133
+ = { s: -1n, m: 0n, f: 0, es: 1, e: 0 }
134
+ */
130
135
  const addIntDigit = digit => b => ({ ...b, m: b.m * 10n + digitToBigInt(digit) });
131
136
  const addFracDigit = digit => b => ({ ...b, m: b.m * 10n + digitToBigInt(digit), f: b.f - 1 });
132
137
  const addExpDigit = digit => b => ({ ...b, e: b.e * 10 + digit - digit0 });
@@ -41,6 +41,42 @@ declare const _default: {
41
41
  positive: () => void;
42
42
  nan: () => void;
43
43
  };
44
+ bigint: {
45
+ throw: () => number;
46
+ };
47
+ array: {
48
+ empty: () => void;
49
+ single_number: () => void;
50
+ single_string: () => void;
51
+ multiple: () => void;
52
+ };
53
+ object: {
54
+ empty: () => void;
55
+ };
56
+ function: () => void;
57
+ };
58
+ unary_minus: () => {
59
+ null: () => void;
60
+ undefined: () => void;
61
+ boolean: {
62
+ false: () => void;
63
+ true: () => void;
64
+ };
65
+ number: {
66
+ zero: () => void;
67
+ positive: () => void;
68
+ negative: () => void;
69
+ };
70
+ string: {
71
+ empty: () => void;
72
+ zero: () => void;
73
+ positive: () => void;
74
+ nan: () => void;
75
+ };
76
+ bigint: {
77
+ positive: () => void;
78
+ negative: () => void;
79
+ };
44
80
  array: {
45
81
  empty: () => void;
46
82
  single_number: () => void;
@@ -50,6 +86,7 @@ declare const _default: {
50
86
  object: {
51
87
  empty: () => void;
52
88
  };
89
+ function: () => void;
53
90
  };
54
91
  };
55
92
  export default _default;
@@ -10,6 +10,12 @@ const n = a => b => {
10
10
  throw [a, '!==', b];
11
11
  }
12
12
  };
13
+ const nan_res = op => n => {
14
+ let result = op(n);
15
+ if (!Number.isNaN(result)) {
16
+ throw result;
17
+ }
18
+ };
13
19
  export default {
14
20
  eq: {
15
21
  nullish: () => {
@@ -84,12 +90,7 @@ export default {
84
90
  },
85
91
  unary_plus: () => {
86
92
  const op = (n) => +n;
87
- const nan = (n) => {
88
- let result = op(n);
89
- if (!Number.isNaN(result)) {
90
- throw result;
91
- }
92
- };
93
+ const nan = nan_res(op);
93
94
  return {
94
95
  null: () => e(op(null))(0),
95
96
  undefined: () => nan(undefined),
@@ -108,11 +109,9 @@ export default {
108
109
  positive: () => e(op("2.3"))(2.3),
109
110
  nan: () => nan("a")
110
111
  },
111
- // TODO: bigint - handle TypeError exception for bigint. The test below (that follows
112
- // current Rust implementation) is incorrect.
113
- // bigint: {
114
- // nan: () => u_p_nan(0n)
115
- // }
112
+ bigint: {
113
+ throw: () => op(0n),
114
+ },
116
115
  array: {
117
116
  empty: () => e(op([]))(0),
118
117
  single_number: () => e(op([2.3]))(2.3),
@@ -122,8 +121,46 @@ export default {
122
121
  object: {
123
122
  empty: () => nan({})
124
123
  // TODO: test objects with valueOf, toString functions - when Rust logic is implemented
125
- }
126
- // TODO: test Function - when Rust logic is implemented
124
+ },
125
+ function: () => nan(op(() => { }))
126
+ };
127
+ },
128
+ unary_minus: () => {
129
+ const op = (n) => -n;
130
+ const nan = nan_res(op);
131
+ return {
132
+ null: () => e(op(null))(0),
133
+ undefined: () => nan(undefined),
134
+ boolean: {
135
+ false: () => e(op(false))(0),
136
+ true: () => e(op(true))(-1)
137
+ },
138
+ number: {
139
+ zero: () => e(op(0))(0),
140
+ positive: () => e(op(2.3))(-2.3),
141
+ negative: () => e(op(-2.3))(2.3)
142
+ },
143
+ string: {
144
+ empty: () => e(op(""))(0),
145
+ zero: () => e(op("0"))(0),
146
+ positive: () => e(op("2.3"))(-2.3),
147
+ nan: () => nan("a")
148
+ },
149
+ bigint: {
150
+ positive: () => e(op(1n))(-1n),
151
+ negative: () => e(op(-1n))(1n),
152
+ },
153
+ array: {
154
+ empty: () => e(op([]))(0),
155
+ single_number: () => e(op([2.3]))(-2.3),
156
+ single_string: () => e(op(["-2.3"]))(2.3),
157
+ multiple: () => nan([null, null])
158
+ },
159
+ object: {
160
+ empty: () => nan({})
161
+ // TODO: test objects with valueOf, toString functions - when Rust logic is implemented
162
+ },
163
+ function: () => nan(op(() => { }))
127
164
  };
128
165
  }
129
166
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.f.d.ts",
@@ -11,11 +11,13 @@
11
11
  "tsc-emit": "tsc --NoEmit false",
12
12
  "prepack": "npm run tsc-emit",
13
13
  "test20": "npm run prepack && node --trace-uncaught ./dev/test.js",
14
- "test": "tsc && node --experimental-strip-types --trace-uncaught ./dev/test.ts",
15
- "comtest": "node --experimental-strip-types ./com/test/build.ts",
16
- "index": "node --experimental-strip-types ./dev/index.ts",
17
- "version": "node --experimental-strip-types ./nodejs/version/main.ts",
18
- "fsc": "node --experimental-strip-types ./main.ts"
14
+ "test22": "tsc && node --experimental-strip-types --trace-uncaught ./dev/test.ts",
15
+ "test": "tsc && node --trace-uncaught ./dev/test.ts",
16
+ "comtest": "node ./com/test/build.ts",
17
+ "index": "node ./dev/index.ts",
18
+ "version": "node ./nodejs/version/main.ts",
19
+ "fsc": "node ./main.ts",
20
+ "update": "npm run version && npm run index && npm install"
19
21
  },
20
22
  "repository": {
21
23
  "type": "git",
@@ -37,7 +39,7 @@
37
39
  },
38
40
  "homepage": "https://github.com/functionalscript/functionalscript#readme",
39
41
  "devDependencies": {
40
- "@types/node": "^22.10.2",
42
+ "@types/node": "^22.10.5",
41
43
  "typescript": "^5.7.2"
42
44
  }
43
45
  }
package/text/module.f.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { msb, u8List, u8ListToVec } from "../types/bit_vec/module.f.js";
2
2
  import { flatMap } from "../types/list/module.f.js";
3
3
  import * as utf8 from "./utf8/module.f.js";
4
- import * as utf16 from "./utf16/module.f.js";
4
+ import { stringToCodePointList, codePointListToString } from "./utf16/module.f.js";
5
5
  export const flat = (indent) => {
6
6
  const f = (prefix) => {
7
7
  const g = (item) => typeof (item) === 'string' ? [`${prefix}${item}`] : f(`${prefix}${indent}`)(item);
@@ -16,11 +16,11 @@ export const curly = (type) => (name) => (body) => [`${type} ${name}`, '{', body
16
16
  * @param s The input string to be converted.
17
17
  * @returns The resulting UTF-8 bit vector, MSB first.
18
18
  */
19
- export const msbUtf8 = (s) => u8ListToVec(msb)(utf8.fromCodePointList(utf16.toCodePointList(utf16.stringToList(s))));
19
+ export const msbUtf8 = (s) => u8ListToVec(msb)(utf8.fromCodePointList(stringToCodePointList(s)));
20
20
  /**
21
21
  * Converts a UTF-8 bit vector with MSB first encoding to a string.
22
22
  *
23
23
  * @param msbV - The UTF-8 bit vector with MSB first encoding.
24
24
  * @returns The resulting string.
25
25
  */
26
- export const msbUtf8ToString = (msbV) => utf16.listToString(utf16.fromCodePointList(utf8.toCodePointList(u8List(msb)(msbV))));
26
+ export const msbUtf8ToString = (msbV) => codePointListToString(utf8.toCodePointList(u8List(msb)(msbV)));
@@ -1,8 +1,14 @@
1
1
  import { type List, type Thunk } from '../../types/list/module.f.ts';
2
- type U16 = number;
3
- type I32 = number;
4
- export declare const fromCodePointList: (input: List<number>) => Thunk<number>;
5
- export declare const toCodePointList: (input: List<U16>) => List<I32>;
2
+ export type U16 = number;
3
+ /**
4
+ * [0, 0x10_FFFF]: 16+5 = 21 bits
5
+ *
6
+ * 121_0000_0000: 16+16+9 = 41 bits
7
+ */
8
+ export type CodePoint = number;
9
+ export declare const fromCodePointList: (input: List<CodePoint>) => Thunk<U16>;
10
+ export declare const toCodePointList: (input: List<U16>) => List<CodePoint>;
6
11
  export declare const stringToList: (s: string) => List<U16>;
12
+ export declare const stringToCodePointList: (input: string) => List<CodePoint>;
7
13
  export declare const listToString: (input: List<U16>) => string;
8
- export {};
14
+ export declare const codePointListToString: (input: List<CodePoint>) => string;
@@ -60,6 +60,8 @@ export const stringToList = (s) => {
60
60
  };
61
61
  return at(0);
62
62
  };
63
+ export const stringToCodePointList = (input) => toCodePointList(stringToList(input));
63
64
  export const listToString = fn(map(String.fromCharCode))
64
65
  .then(reduce(concat)(''))
65
66
  .result;
67
+ export const codePointListToString = (input) => listToString(fromCodePointList(input));
@@ -1,4 +1,4 @@
1
- import { toCodePointList, fromCodePointList, stringToList, listToString } from "./module.f.js";
1
+ import { toCodePointList, fromCodePointList, stringToList, listToString, stringToCodePointList, codePointListToString } from "./module.f.js";
2
2
  import * as json from "../../json/module.f.js";
3
3
  import { sort } from "../../types/object/module.f.js";
4
4
  import { toArray } from "../../types/list/module.f.js";
@@ -130,6 +130,13 @@ export default {
130
130
  throw result;
131
131
  }
132
132
  },
133
+ () => {
134
+ const cpList = stringToCodePointList("Hello world!😂🚜🚲");
135
+ const result = codePointListToString(cpList);
136
+ if (result !== "Hello world!😂🚜🚲") {
137
+ throw result;
138
+ }
139
+ },
133
140
  () => {
134
141
  const a = stringToList("Hello world!😂🚜🚲");
135
142
  const b = toCodePointList(a);
@@ -1,3 +1,8 @@
1
+ /**
2
+ * JavaScript immutable arrays.
3
+ *
4
+ * @module
5
+ */
1
6
  export type Array1<T> = readonly [T];
2
7
  export type Index1 = 0;
3
8
  export type Array2<T> = readonly [T, T];
@@ -5,16 +10,17 @@ export type Tuple2<T0, T1> = readonly [T0, T1];
5
10
  export type Index2 = 0 | 1;
6
11
  export type Array3<T> = readonly [T, T, T];
7
12
  export type Tuple3<T0, T1, T2> = readonly [T0, T1, T2];
8
- export type Index3 = 0 | 1 | 2;
13
+ export type Index3 = Index2 | 2;
9
14
  export type Array4<T> = readonly [T, T, T, T];
10
- export type Index4 = 0 | 1 | 2 | 3;
15
+ export type Index4 = Index3 | 3;
11
16
  export type Array5<T> = readonly [T, T, T, T, T];
17
+ export type Index5 = Index4 | 4;
12
18
  export type Array8<T> = readonly [T, T, T, T, T, T, T, T];
19
+ export type Index8 = Index5 | 5 | 6 | 7;
13
20
  export type Array16<T> = readonly [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
14
- export type Index16 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
21
+ export type Index16 = Index8 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
15
22
  export type Array1_5<T> = Array1<T> | Array2<T> | Array3<T> | Array4<T> | Array5<T>;
16
- export type Index5 = 0 | 1 | 2 | 3 | 4;
17
- export type KeyOf<T> = T extends Array1<infer _> ? Index1 : T extends Array2<infer _> ? Index2 : T extends Array3<infer _> ? Index3 : T extends Array4<infer _> ? Index4 : T extends Array5<infer _> ? Index5 : T extends readonly (infer _)[] ? number : never;
23
+ export type KeyOf<T> = T extends Array1<infer _> ? Index1 : T extends Array2<infer _> ? Index2 : T extends Array3<infer _> ? Index3 : T extends Array4<infer _> ? Index4 : T extends Array5<infer _> ? Index5 : T extends Array8<infer _> ? Index8 : T extends Array16<infer _> ? Index16 : T extends readonly (infer _)[] ? number : never;
18
24
  export declare const at: (i: number) => <T>(a: readonly T[]) => T | null;
19
25
  export declare const first: <T>(_: readonly T[]) => T | null;
20
26
  export declare const last: <T>(a: readonly T[]) => T | null;
@@ -22,3 +28,11 @@ export declare const tail: <T>(a: readonly T[]) => readonly T[] | null;
22
28
  export declare const splitFirst: <T>(a: readonly T[]) => readonly [T, readonly T[]] | null;
23
29
  export declare const head: <T>(a: readonly T[]) => readonly T[] | null;
24
30
  export declare const splitLast: <T>(a: readonly T[]) => readonly [readonly T[], T] | null;
31
+ /**
32
+ * An empty immutable array.
33
+ *
34
+ * Two JavaScript empty arrays are different and has to have two different values.
35
+ * Usually, it requires memory allocation. If we use the same an empty array everywhere,
36
+ * we may minimize memory a number of memory allocations.
37
+ */
38
+ export declare const empty: readonly [];
@@ -1,3 +1,8 @@
1
+ /**
2
+ * JavaScript immutable arrays.
3
+ *
4
+ * @module
5
+ */
1
6
  import { map } from "../nullable/module.f.js";
2
7
  const uncheckTail = (a) => a.slice(1);
3
8
  const uncheckHead = (a) => a.slice(0, -1);
@@ -20,3 +25,11 @@ export const splitLast = (a) => {
20
25
  }
21
26
  return [uncheckHead(a), lastA];
22
27
  };
28
+ /**
29
+ * An empty immutable array.
30
+ *
31
+ * Two JavaScript empty arrays are different and has to have two different values.
32
+ * Usually, it requires memory allocation. If we use the same an empty array everywhere,
33
+ * we may minimize memory a number of memory allocations.
34
+ */
35
+ export const empty = [];
@@ -7,5 +7,6 @@ declare const _default: {
7
7
  tail: (() => void)[];
8
8
  splitFirst: (() => void)[];
9
9
  splitLast: (() => void)[];
10
+ empty: () => void;
10
11
  };
11
12
  export default _default;
@@ -1,4 +1,4 @@
1
- import { at, first, last, head, tail, splitFirst, splitLast } from "./module.f.js";
1
+ import { at, first, last, head, tail, splitFirst, splitLast, empty } from "./module.f.js";
2
2
  import * as json from "../../json/module.f.js";
3
3
  import { sort } from "../object/module.f.js";
4
4
  const stringify = json.stringify(sort);
@@ -113,5 +113,14 @@ export default {
113
113
  throw result;
114
114
  }
115
115
  }
116
- ]
116
+ ],
117
+ empty: () => {
118
+ const x = empty;
119
+ const a = x;
120
+ const b = x;
121
+ const c = [...a, ...b, ...x];
122
+ if (c.length !== 0) {
123
+ throw c;
124
+ }
125
+ }
117
126
  };