Skip to content

Commit 476403f

Browse files
authored
Merge pull request #65 from JohanWiltink/main
redesign for configure()
2 parents bd80979 + f56621d commit 476403f

File tree

12 files changed

+400
-463
lines changed

12 files changed

+400
-463
lines changed

example/test.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@ chaiConfig.truncateThreshold = 0;
44
import * as LC from "@codewars/lambda-calculus";
55
import { solution } from "./files.js"; // /workspace/files.js
66

7-
LC.config.purity = "Let";
8-
LC.config.numEncoding = "Church";
9-
const toInt = LC.toIntWith(LC.config);
7+
LC.configure({ purity: "Let", numEncoding: "Church" });
108
const { counter } = LC.compile(solution());
119

1210
const T = t => _ => t;
1311
const F = _ => f => f;
1412

1513
describe("counter", () => {
1614
it("fixed tests", () => {
17-
assert.strictEqual(toInt(counter(T)(T)(T)(F)), 3);
18-
assert.strictEqual(toInt(counter(T)(F)), 1);
19-
assert.strictEqual(toInt(counter(T)(T)(T)(T)(T)(T)(T)(F)), 7);
15+
assert.equal( counter(T)(T)(T)(F), 3);
16+
assert.equal( counter(T)(F), 1);
17+
assert.equal( counter(T)(T)(T)(T)(T)(T)(T)(F), 7);
2018
});
2119
});

src/lambda-calculus.js

Lines changed: 200 additions & 219 deletions
Large diffs are not rendered by default.

tests/basics-binary-scott/test.js

Lines changed: 73 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ import {readFileSync} from "fs";
22
import {assert} from "chai";
33

44
import * as LC from "../../src/lambda-calculus.js";
5-
LC.config.purity = "LetRec";
6-
LC.config.numEncoding = "BinaryScott";
5+
LC.configure({ purity: "LetRec", numEncoding: "BinaryScott" });
76

87
const solutionText = readFileSync(new URL("./solution.txt", import.meta.url), {encoding: "utf8"});
98
const solution = LC.compile(solutionText);
10-
const fromInt = LC.fromIntWith(LC.config);
11-
const toInt = LC.toIntWith(LC.config);
9+
const {fromInt,toInt} = LC;
1210

1311
const {False,True,not,and,or,xor,implies} = solution;
1412
const {LT,EQ,GT,compare,lt,le,eq,ge,gt} = solution;
@@ -27,220 +25,196 @@ const refGCD = m => n => n ? refGCD(n)(m%n) : m ;
2725
describe("Binary Scott tests",function(){
2826
this.timeout(0);
2927
it("enumeration",()=>{
28+
LC.configure({ purity: "LetRec", numEncoding: "BinaryScott" });
3029
const one = succ(zero)
3130
const two = succ(one)
3231
const three = succ(two)
3332
const four = succ(three)
3433
const five = succ(four)
35-
assert.strictEqual( toString(zero), "$" );
36-
assert.strictEqual( toString(one), "1$" );
37-
assert.strictEqual( toString(two), "01$" );
38-
assert.strictEqual( toString(three), "11$" );
39-
assert.strictEqual( toString(four), "001$" );
40-
assert.strictEqual( toString(five), "101$" );
41-
assert.strictEqual( toString(five), "101$" );
42-
assert.strictEqual( toString(pred(five)), "001$" );
43-
assert.strictEqual( toString(unpad(pred(pred(five)))), "11$" );
44-
assert.strictEqual( toString(unpad(pred(pred(pred(five))))), "01$" );
45-
assert.strictEqual( toString(unpad(pred(pred(pred(pred(five)))))), "1$" );
46-
assert.strictEqual( toString(unpad(pred(pred(pred(pred(pred(five))))))), "$" );
34+
assert.equal( toString(zero), "$" );
35+
assert.equal( toString(one), "1$" );
36+
assert.equal( toString(two), "01$" );
37+
assert.equal( toString(three), "11$" );
38+
assert.equal( toString(four), "001$" );
39+
assert.equal( toString(five), "101$" );
40+
assert.equal( toString(five), "101$" );
41+
assert.equal( toString(pred(five)), "001$" );
42+
assert.equal( toString(unpad(pred(pred(five)))), "11$" );
43+
assert.equal( toString(unpad(pred(pred(pred(five))))), "01$" );
44+
assert.equal( toString(unpad(pred(pred(pred(pred(five)))))), "1$" );
45+
assert.equal( toString(unpad(pred(pred(pred(pred(pred(five))))))), "$" );
4746
});
4847
it("successor",()=>{
49-
let n = zero;
48+
let n = 0;
5049
for ( let i=1; i<=100; i++ ) {
5150
n = succ (n);
52-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ i } <- ${ toString(n) }`);
53-
assert.strictEqual( toInt(n), i );
51+
assert.equal( n, i );
5452
}
5553
});
5654
it("predecessor",()=>{
57-
let n = fromInt(100);
55+
let n = 100;
5856
for ( let i=100; i--; ) {
5957
n = pred (n);
60-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ i } <- ${ toString(n) }`);
61-
assert.strictEqual( toInt(n), i );
58+
assert.equal( n, i );
6259
}
6360
});
6461
it("predecessor robustness",()=>{
65-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`pred 01$ -> 1$`);
66-
assert.strictEqual( toString( pred ( fromInt(2) ) ), "1$" );
67-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`pred $ -> $`);
68-
assert.strictEqual( toString( pred ( end => even => odd => end ) ), "$" );
69-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`pred 0$ -> $`);
70-
assert.strictEqual( toString( pred ( end => even => odd => even (
71-
end => even => odd => end ) ) ), "$" );
72-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`pred 00$ -> $`);
73-
assert.strictEqual( toString( pred ( end => even => odd => even (
74-
end => even => odd => even (
75-
end => even => odd => end ) ) ) ), "$" );
62+
assert.equal( toString( pred ( 2 ) ), "1$" );
63+
assert.equal( toString( pred ( end => even => odd => end ) ), "$" );
64+
assert.equal( toString( pred ( end => even => odd => even (
65+
end => even => odd => end ) ) ), "$" );
66+
assert.equal( toString( pred ( end => even => odd => even (
67+
end => even => odd => even (
68+
end => even => odd => end ) ) ) ), "$" );
7669
});
7770
it("ordering",()=>{
7871
for ( let i=1; i<=100; i++ ) {
7972
const m = rnd(i*i), n = rnd(i*i);
80-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`compare ${ m } ${ n }`);
81-
assert.strictEqual( compare (fromInt(m)) (fromInt(n)) ("-1") ("0") ("1"), String(Number(m>n) - Number(m<n)) );
73+
assert.equal( compare (fromInt(m)) (fromInt(n)) ("-1") ("0") ("1"), String(Number(m>n) - Number(m<n)) );
8274
}
8375
});
8476
it("comparison",()=>{
8577
for ( let i=1; i<=100; i++ ) {
8678
const m = rnd(i*i), n = rnd(i*i);
87-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`compare ${ m } ${ n }`);
88-
assert.strictEqual( lt (fromInt(m)) (fromInt(n)) (false)(true), m < n );
89-
assert.strictEqual( le (fromInt(m)) (fromInt(n)) (false)(true), m <= n );
90-
assert.strictEqual( eq (fromInt(m)) (fromInt(n)) (false)(true), m == n );
91-
assert.strictEqual( ge (fromInt(m)) (fromInt(n)) (false)(true), m >= n );
92-
assert.strictEqual( gt (fromInt(m)) (fromInt(n)) (false)(true), m > n );
93-
assert.strictEqual( eq (fromInt(m)) (fromInt(m)) (false)(true), true );
79+
assert.equal( lt (fromInt(m)) (fromInt(n)) (false)(true), m < n );
80+
assert.equal( le (fromInt(m)) (fromInt(n)) (false)(true), m <= n );
81+
assert.equal( eq (fromInt(m)) (fromInt(n)) (false)(true), m == n );
82+
assert.equal( ge (fromInt(m)) (fromInt(n)) (false)(true), m >= n );
83+
assert.equal( gt (fromInt(m)) (fromInt(n)) (false)(true), m > n );
84+
assert.equal( eq (fromInt(m)) (fromInt(m)) (false)(true), true );
9485
}
9586
});
9687
it("addition",()=>{
9788
for ( let i=1; i<=100; i++ ) {
9889
const m = rnd(i*i), n = rnd(i*i);
99-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ m } + ${ n } = ${ m+n }`);
100-
assert.strictEqual( toInt( plus (fromInt(m)) (fromInt(n)) ), m + n );
90+
assert.equal( plus (m) (n), m + n );
10191
}
10292
});
10393
it("multiplication",()=>{
10494
for ( let i=1; i<=100; i++ ) {
10595
const m = rnd(i*i), n = rnd(i*i);
106-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ m } * ${ n } = ${ m*n }`);
107-
assert.strictEqual( toInt( times (fromInt(m)) (fromInt(n)) ), m * n );
96+
assert.equal( times (m) (n), m * n );
10897
}
10998
});
11099
it("subtraction",()=>{
111100
for ( let i=1; i<=100; i++ ) {
112101
const m = rnd(i*i), n = rnd(i*i);
113-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`subtract ${ m } ${ n }`);
114-
assert.strictEqual( toInt( minus (fromInt(m)) (fromInt(n)) ), Math.max( 0, m - n ) );
115-
assert.strictEqual( toInt( minus (fromInt(n)) (fromInt(m)) ), Math.max( 0, n - m ) );
102+
assert.equal( minus (m) (n), Math.max( 0, m - n ) );
103+
assert.equal( minus (n) (m), Math.max( 0, n - m ) );
116104
}
117105
});
118106
it("division",()=>{
119107
for ( let i=1; i<=100; i++ ) {
120108
const m = rnd(i*i), n = rnd(i*i);
121-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`division ${ m } ${ n }`);
122-
assert.deepEqual( toPair( divMod (fromInt(m)) (fromInt(n||1)) ).map(toInt), [ m/(n||1)|0, m%(n||1) ] );
123-
assert.deepEqual( toPair( divMod (fromInt(n)) (fromInt(m||1)) ).map(toInt), [ n/(m||1)|0, n%(m||1) ] );
109+
assert.deepEqual( toPair( divMod (m) (n||1) ).map(toInt), [ m/(n||1)|0, m%(n||1) ] );
110+
assert.deepEqual( toPair( divMod (n) (m||1) ).map(toInt), [ n/(m||1)|0, n%(m||1) ] );
124111
}
125112
});
126113
it("exponentiation",()=>{
127114
for ( let i=1; i<=100; i++ ) {
128115
const m = rnd(i), n = rnd(i%10);
129-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ m } ** ${ n } = ${ m**n }`);
130-
assert.strictEqual( toInt( pow (fromInt(m)) (fromInt(n)) ), m ** n );
116+
assert.equal( pow (m) (n), m ** n );
131117
}
132118
});
133119
it("greatest common divisor",()=>{
134120
for ( let i=1; i<=100; i++ ) {
135121
const m = rnd(i), n = rnd(i);
136-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`gcd ${ m } ${ n } = ${ refGCD(m)(n) }`);
137-
assert.strictEqual( toInt( gcd (fromInt(m)) (fromInt(n)) ), refGCD(m)(n) );
122+
assert.equal( gcd (m) (n), refGCD(m)(n) );
138123
}
139124
});
140125
it("least common multiple",()=>{
141126
for ( let i=1; i<=100; i++ ) {
142127
const m = rnd(i), n = rnd(i);
143-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`lcm ${ m } ${ n } = ${ m/(refGCD(m)(n)||1)*n }`);
144-
assert.strictEqual( toInt( lcm (fromInt(m)) (fromInt(n)) ), m / (refGCD(m)(n)||1) * n );
128+
assert.equal( lcm (m) (n), m / (refGCD(m)(n)||1) * n );
145129
}
146130
});
147131
it("minimum",()=>{
148132
for ( let i=1; i<=100; i++ ) {
149133
const m = rnd(i*i), n = rnd(i*i);
150-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`min ${ m } ${ n } = ${ Math.min(m,n) }`);
151-
assert.strictEqual( toInt( min (fromInt(m)) (fromInt(n)) ), Math.min(m,n) );
134+
assert.equal( min (m) (n), Math.min(m,n) );
152135
}
153136
});
154137
it("maximum",()=>{
155138
for ( let i=1; i<=100; i++ ) {
156139
const m = rnd(i*i), n = rnd(i*i);
157-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`max ${ m } + ${ n } = ${ Math.max(m,n) }`);
158-
assert.strictEqual( toInt( max (fromInt(m)) (fromInt(n)) ), Math.max(m,n) );
140+
assert.equal( max (m) (n), Math.max(m,n) );
159141
}
160142
});
161143
it("shifting bits",()=>{
162144
for ( let i=1; i<=100; i++ ) {
163145
const n = rnd(i*i);
164-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`shift ${ n }`);
165-
assert.strictEqual( toInt( shiftL (fromInt(n)) ), n >> 1 );
166-
assert.strictEqual( toInt( shiftR0 (fromInt(n)) ), n << 1 );
167-
assert.strictEqual( toInt( shiftR1 (fromInt(n)) ), n << 1 | 1 );
146+
assert.equal( shiftL (n), n >> 1 );
147+
assert.equal( shiftR0 (n), n << 1 );
148+
assert.equal( shiftR1 (n), n << 1 | 1 );
168149
}
169150
});
170151
it("zero padding",()=>{
171152
for ( let i=1; i<=100; i++ ) {
172153
const n = rnd(i*i);
173-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`isPadded ${ n }`);
174-
assert.strictEqual( isPadded (fromInt(n)) (false)(true), false );
175-
assert.strictEqual( isPadded (pad(fromInt(n))) (false)(true), true );
176-
assert.strictEqual( isPadded (pad(pad(fromInt(n)))) (false)(true), true );
177-
assert.strictEqual( isPadded (pad(pad(pad(fromInt(n))))) (false)(true), true );
154+
assert.equal( isPadded (n) (false)(true), false );
155+
assert.equal( isPadded (pad(n)) (false)(true), true );
156+
assert.equal( isPadded (pad(pad(n))) (false)(true), true );
157+
assert.equal( isPadded (pad(pad(pad(n)))) (false)(true), true );
178158
}
179159
});
180160
it("bitwise and",()=>{
181161
for ( let i=1; i<=100; i++ ) {
182162
const m = rnd(i*i), n = rnd(i*i);
183-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ m } & ${ n } = ${ m&n }`);
184-
assert.strictEqual( toInt( bitAnd (fromInt(m)) (fromInt(n)) ), m & n );
163+
assert.equal( bitAnd (m) (n), m & n );
185164
}
186165
});
187166
it("bitwise or",()=>{
188167
for ( let i=1; i<=100; i++ ) {
189168
const m = rnd(i*i), n = rnd(i*i);
190-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ m } | ${ n } = ${ m|n }`);
191-
assert.strictEqual( toInt( bitOr (fromInt(m)) (fromInt(n)) ), m | n );
169+
assert.equal( bitOr (m) (n), m | n );
192170
}
193171
});
194172
it("bitwise exclusive or",()=>{
195173
for ( let i=1; i<=100; i++ ) {
196174
const m = rnd(i*i), n = rnd(i*i);
197-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`${ m } ^ ${ n } = ${ m^n }`);
198-
assert.strictEqual( toInt( bitXor (fromInt(m)) (fromInt(n)) ), m ^ n );
175+
assert.equal( bitXor (m) (n), m ^ n );
199176
}
200177
});
201178
it("testing bits",()=>{
202179
for ( let i=1; i<=100; i++ ) {
203180
const j = rnd(i%32), n = rnd(i*i);
204-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`testBit ${ j } ${ n } = ${ Boolean( n & 1<<j ) }`);
205-
assert.strictEqual( testBit (fromInt(j)) (fromInt(n)) (false)(true), Boolean( n & 1<<j ) ); // JS restricted to 32-bit
181+
assert.equal( testBit (j) (n) (false)(true), Boolean( n & 1<<j ) ); // JS restricted to 32-bit
206182
}
207183
});
208184
it("setting bits",()=>{
209185
for ( let i=1; i<=100; i++ ) {
210186
const j = rnd(i%32);
211-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`bit ${ j } = ${ 1<<j }`);
212-
assert.strictEqual( toInt( bit (fromInt(j)) ), 1<<j ); // JS restricted to 32-bit
187+
assert.equal( bit (j), 1<<j ); // JS restricted to 32-bit
213188
}
214189
});
215190
it("population count",()=>{
216191
const refPopCount = n => n && 1 + refPopCount(n & n-1) ;
217192
for ( let i=1; i<=100; i++ ) {
218193
const n = rnd(i*i);
219-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`popCount ${ n } = ${ refPopCount(n) }`);
220-
assert.strictEqual( toInt( popCount (fromInt(n)) ), refPopCount(n) ); // JS restricted to 32-bit
194+
assert.equal( popCount (n), refPopCount(n) ); // JS restricted to 32-bit
221195
}
222196
});
223197
it("logical not",()=>{
224-
assert.strictEqual( not(False) (false)(true), true );
225-
assert.strictEqual( not(True) (false)(true), false );
198+
assert.equal( not(False) (false)(true), true );
199+
assert.equal( not(True) (false)(true), false );
226200
});
227201
it("logical and",()=>{
228-
assert.strictEqual( and(False)(False) (false)(true), false );
229-
assert.strictEqual( and(False)(True) (false)(true), false );
230-
assert.strictEqual( and(True) (False) (false)(true), false );
231-
assert.strictEqual( and(True) (True) (false)(true), true );
202+
assert.equal( and(False)(False) (false)(true), false );
203+
assert.equal( and(False)(True) (false)(true), false );
204+
assert.equal( and(True) (False) (false)(true), false );
205+
assert.equal( and(True) (True) (false)(true), true );
232206
});
233207
it("logical or",()=>{
234-
assert.strictEqual( or(False)(False) (false)(true), false );
235-
assert.strictEqual( or(False)(True) (false)(true), true );
236-
assert.strictEqual( or(True) (False) (false)(true), true );
237-
assert.strictEqual( or(True) (True) (false)(true), true );
208+
assert.equal( or(False)(False) (false)(true), false );
209+
assert.equal( or(False)(True) (false)(true), true );
210+
assert.equal( or(True) (False) (false)(true), true );
211+
assert.equal( or(True) (True) (false)(true), true );
238212
});
239213
it("logical exclusive or",()=>{
240-
assert.strictEqual( xor(False)(False) (false)(true), false );
241-
assert.strictEqual( xor(False)(True) (false)(true), true );
242-
assert.strictEqual( xor(True) (False) (false)(true), true );
243-
assert.strictEqual( xor(True) (True) (false)(true), false );
214+
assert.equal( xor(False)(False) (false)(true), false );
215+
assert.equal( xor(False)(True) (false)(true), true );
216+
assert.equal( xor(True) (False) (false)(true), true );
217+
assert.equal( xor(True) (True) (false)(true), false );
244218
});
245219
it("logical implies",()=>{
246220
assert.strictEqual( implies(False)(False) (false)(true), true );
@@ -251,9 +225,8 @@ describe("Binary Scott tests",function(){
251225
it("parity",()=>{
252226
for ( let i=1; i<=100; i++ ) {
253227
const n = rnd(i*i*i);
254-
if ( LC.config.verbosity >= "Loquacious" ) console.log(`parity ${ n }`);
255-
assert.strictEqual( odd (fromInt(n)) (false)(true), Boolean(n&1) );
256-
assert.strictEqual( even (fromInt(n)) (false)(true), ! (n&1) );
228+
assert.equal( odd (fromInt(n)) (false)(true), Boolean(n&1) );
229+
assert.equal( even (fromInt(n)) (false)(true), ! (n&1) );
257230
}
258231
});
259232
});

tests/basics-church/test.js

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,39 @@ import {readFileSync} from "fs";
22
import {assert} from "chai";
33

44
import * as LC from "../../src/lambda-calculus.js";
5-
LC.config.purity = "LetRec";
6-
LC.config.numEncoding = "Church";
5+
LC.configure({ purity: "LetRec", numEncoding: "Church" });
76

87
const solutionText = readFileSync(new URL("./solution.txt", import.meta.url), {encoding: "utf8"});
98
const solution = LC.compile(solutionText);
10-
const fromInt = LC.fromIntWith(LC.config);
11-
const toInt = LC.toIntWith(LC.config);
9+
const { fromInt, toInt } = LC;
1210

1311
const {B,C,I,KI,M,S,T,V,W,Y,Z} = solution;
1412
const {True,False,not,and,or,xor,implies} = solution;
1513
const {lt,le,eq,ge,gt} = solution;
1614
const {zero,succ,pred,isZero} = solution;
1715
const {plus,times,pow,minus} = solution;
1816

19-
const toPair = xy => [ fst(xy), snd(xy) ] ;
20-
2117
const rnd = (m,n=0) => Math.random() * (n-m) + m | 0 ;
2218

2319
describe("Church tests",function(){
2420
this.timeout(0);
2521
it("fixed tests",()=>{
22+
LC.configure({ purity: "LetRec", numEncoding: "Church" });
2623
const one = succ(zero);
2724
const two = succ(one);
2825
const three = succ(two);
2926
const four = succ(three);
3027
const five = succ(four);
31-
assert.strictEqual( toInt(zero), 0 );
32-
assert.strictEqual( toInt(one), 1 );
33-
assert.strictEqual( toInt(two), 2 );
34-
assert.strictEqual( toInt(three), 3 );
35-
assert.strictEqual( toInt(four), 4 );
36-
assert.strictEqual( toInt(five), 5 );
28+
assert.equal( zero, 0 );
29+
assert.equal( one, 1 );
30+
assert.equal( two, 2 );
31+
assert.equal( three, 3 );
32+
assert.equal( four, 4 );
33+
assert.equal( five, 5 );
3734
const n = 1e3;
38-
assert.strictEqual( toInt(I(fromInt(n))), n );
39-
assert.strictEqual( toInt(times(fromInt(1e2))(fromInt(1e1))), 1e3 );
40-
assert.strictEqual( toInt(pow(fromInt(10))(fromInt(3))), 1e3 );
41-
assert.strictEqual( toInt(pred(pow(fromInt(10))(fromInt(3)))), 1e3-1 );
35+
assert.equal( I(fromInt(n)), n );
36+
assert.equal( times(1e2)(1e1), 1e3 );
37+
assert.equal( pow(10)(3), 1e3 );
38+
assert.equal( pred(pow(10)(3)), 1e3-1 );
4239
});
4340
});

0 commit comments

Comments
 (0)