Skip to content

Commit b5fa01d

Browse files
🚧 progress: Import existing sources, tests, and code samples.
1 parent 1a5d390 commit b5fa01d

File tree

7 files changed

+10266
-10
lines changed

7 files changed

+10266
-10
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
Set closure for JavaScript.
55
See [docs](https://set-theory.github.io/closure/index.html).
66

7-
> :building_construction: Caveat emptor! This is work in progress. Code may be
8-
> working. Documentation may be present. Coherence may be. Maybe.
9-
107
> :warning: Depending on your environment, the code may require
118
> `regeneratorRuntime` to be defined, for instance by importing
129
> [regenerator-runtime/runtime](https://www.npmjs.com/package/regenerator-runtime).
1310
11+
12+
```js
13+
import {closure} from '@set-theory/closure';
14+
closure( x => x + 1 , 0 ) ; // 0 1 2 3 ...
15+
```
16+
1417
[![License](https://img.shields.io/github/license/set-theory/closure.svg)](https://raw.githubusercontent.com/set-theory/closure/main/LICENSE)
1518
[![Version](https://img.shields.io/npm/v/@set-theory/closure.svg)](https://www.npmjs.org/package/@set-theory/closure)
1619
[![Tests](https://img.shields.io/github/workflow/status/set-theory/closure/ci:test?event=push&label=tests)](https://github.com/set-theory/closure/actions/workflows/ci:test.yml?query=branch:main)

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@
6565
"@babel/preset-env": "7.14.0",
6666
"@babel/register": "7.13.16",
6767
"@commitlint/cli": "12.1.1",
68+
"@iterable-iterator/list": "^0.0.2",
69+
"@iterable-iterator/slice": "^0.0.1",
70+
"@iterable-iterator/zip": "^0.0.2",
6871
"@js-library/commitlint-config": "0.0.4",
6972
"ava": "3.15.0",
7073
"babel-plugin-transform-remove-console": "6.9.4",

src/closure.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Computes the closure of a unary operator, starting from a single element.
3+
*
4+
* @experimental Should handle d-ary operators in the future. Not sure the name
5+
* is well chosen. An actual closure function would keep track of encountered
6+
* elements to stop when all elements have been found.
7+
*
8+
* @example
9+
* closure( x => x + 1 , 0 ) ; // 0 1 2 3 ...
10+
*
11+
* @example
12+
* closure( x => x * 2 , 1 ) ; // 1 2 4 8 ...
13+
*
14+
* @param {Function} operator The operator.
15+
* @param {Object} start The starting element.
16+
* @returns {Iterator} Iterator over the closure.
17+
*/
18+
export default function* closure(operator, start) {
19+
yield start;
20+
21+
let element = start;
22+
23+
while (true) {
24+
element = operator(element);
25+
26+
yield element;
27+
}
28+
}

src/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
const answer = 42;
2-
export default answer;
1+
export {default as closure} from './closure.js';

test/src/api.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/src/closure.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import test from 'ava';
2+
3+
import {list} from '@iterable-iterator/list';
4+
import {enumerate} from '@iterable-iterator/zip';
5+
import {takewhile} from '@iterable-iterator/slice';
6+
7+
import {closure} from '../../src/index.js';
8+
9+
// https://oeis.org/A006577
10+
const Collatz = (x) => (x % 2 === 1 ? 3 * x + 1 : Math.floor(x / 2));
11+
12+
const A006577 = [
13+
0,
14+
1,
15+
7,
16+
2,
17+
5,
18+
8,
19+
16,
20+
3,
21+
19,
22+
6,
23+
14,
24+
9,
25+
9,
26+
17,
27+
17,
28+
4,
29+
12,
30+
20,
31+
20,
32+
7,
33+
7,
34+
15,
35+
15,
36+
10,
37+
23,
38+
10,
39+
111,
40+
18,
41+
18,
42+
18,
43+
106,
44+
5,
45+
26,
46+
13,
47+
13,
48+
21,
49+
21,
50+
21,
51+
34,
52+
8,
53+
109,
54+
8,
55+
29,
56+
16,
57+
16,
58+
16,
59+
104,
60+
11,
61+
24,
62+
24,
63+
24,
64+
11,
65+
11,
66+
112,
67+
112,
68+
19,
69+
32,
70+
19,
71+
32,
72+
19,
73+
19,
74+
107,
75+
107,
76+
6,
77+
27,
78+
27,
79+
27,
80+
14,
81+
14,
82+
14,
83+
102,
84+
22,
85+
];
86+
87+
function macro(t, n, a) {
88+
const sequence = list(takewhile((x) => x !== 1, closure(Collatz, n)));
89+
90+
t.is(sequence.length, a);
91+
}
92+
93+
macro.title = (_, n, a) => `closure [A006577] > a(${n}) = ${a}`;
94+
95+
for (const [n, a] of enumerate(A006577, 1)) {
96+
test(macro, n, a);
97+
}

0 commit comments

Comments
 (0)