1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Lambda Screen - Fractals in Pure Lambda Calculus</title>
<link rel="stylesheet" href="style.css" type="text/css" media="all" />
</head>
<body>
<main>
<canvas height="800" width="800" id="canvas"></canvas>
<div>
<div class="inputWrap">
Load preset:
<select id="examples">
<option value="" selected>Empty</option>
<option
value="-- the final term gets applied with the empty screen
\0"
>
Identity
</option>
<option
value="-- define substitutions of top-left, top-right, bottom-left, bottom-right black pixels
tl = \\0
tr = \\0
bl = \\0
br = \\0
-- two abstractions to ignore the screen state and replace the entire screen
\\((((0 tl) tr) bl) br)"
>
Just black
</option>
<option
value="map = \\(0 \\\\\((((0 (6 4)) (6 3)) (6 2)) (6 1)))
invert = \\\((2 0) 1)
-- the first argument is the empty screen, therefore we can use point-free style
(map invert)"
>
Invert
</option>
<option
value="y = \(\(1 (0 0)) \(1 (0 0)))
\(y \\((((0 1) \\1) \\0) 1))"
>
Diagonal
</option>
<option
value="-- note how no white gets drawn since the highlighted parts would be infinitely detailed
y = \(\(1 (0 0)) \(1 (0 0)))
\(y \\((((0 1) \\0) 1) 1))"
>
Sierpiński triangle
</option>
<option
value="y = \(\(1 (0 0)) \(1 (0 0)))
vfix = (y \\((\(y \\((0 \\\\((0 (6 3)) (5 2))) 0)) \(0 (2 1))) 0))
mut = \((0 \\((((0 (1 \\1)) ((1 \\0) \\1)) (((1 \\0) \\0) \\1)) \\0)) \((0 \\((((0 (1 \\1)) ((1 \\0) \\1)) \\0) ((((1 \\0) \\0) \\0) \\1))) \((0 \\((((0 (1 \\1)) \\0) (((1 \\0) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))) \((0 \\((((0 \\0) ((1 \\0) \\1)) (((1 \\0) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))) \\0))))
build = \\((((0 (1 \\1)) ((1 \\0) \\1)) (((1 \\0) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))
\(build (vfix mut))"
>
T-square
</option>
<option
value="y = \(\(1 (0 0)) \(1 (0 0)))
vfix = (y \\((\(y \\((0 \\\\((0 (6 3)) (5 2))) 0)) \(0 (2 1))) 0))
mut = \((0 \\((((0 (1 \\1)) ((1 \\0) \\1)) (((1 \\0) \\0) \\1)) \((((0 \((((0 \\0) \\1) \\1) \\1)) \\1) \\1) \\0))) \((0 \\((((0 (1 \\1)) ((1 \\0) \\1)) \((((0 \\1) \((((0 \\1) \\0) \\1) \\1)) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))) \((0 \\((((0 (1 \\1)) \((((0 \\1) \\0) \((((0 \\1) \\1) \\0) \\1)) \\1)) (((1 \\0) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))) \((0 \\((((0 \((((0 \\0) \\1) \\1) \((((0 \\1) \\1) \\1) \\0))) ((1 \\0) \\1)) (((1 \\0) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))) \\0))))
build = \\((((0 (1 \\1)) ((1 \\0) \\1)) (((1 \\0) \\0) \\1)) ((((1 \\0) \\0) \\0) \\1))
\(build (vfix mut))"
>
Sierpiński carpet (variant)
</option>
<option
value="s=\\0
quad = \\((((0 1) 1) 1) 1)
y = \(\(1 (0 0)) \(1 (0 0)))
\(y \\((((0 (quad \((((0 2) s) s) s))) (quad \((((0 s) 2) s) s))) (quad \((((0 s) s) 2) s))) (quad \((((0 s) s) s) 2))))"
>
Cantor dust
</option>
<option value="">Vicsek saltire</option>
</select>
</div>
<span id="error"></span>
<textarea
type="text"
rows="6"
placeholder="e.g. \\(0...) or 00000110... (BLC) or [[0 ...]] (bruijn)"
name="term"
id="term"
></textarea>
</div>
<button id="render">Render!</button>
</main>
<script src="main.js"></script>
<script charset="utf-8">
const canvas = window.canvas;
const root = { x: [0, canvas.width], y: [0, canvas.height] };
const offscreen = canvas.transferControlToOffscreen();
const worker = new Worker("canvasWorker.js");
worker.postMessage({ canvas: offscreen }, [offscreen]);
window.examples.addEventListener("change", () => {
clearScreen(worker);
window.term.value = window.examples.value;
});
window.render.addEventListener("click", () => {
clearScreen(worker);
clearErrors();
console.time("reduceLoop");
reduceLoop(
worker,
root,
app(parse(window.term.value))(
parse("\\((((0 \\\\1) \\\\1) \\\\1) \\\\1)"),
),
);
console.timeEnd("reduceLoop");
});
</script>
</body>
</html>
|