Skip to content

Commit 8d88014

Browse files
author
Dierk Koenig
committed
finishing sequence cheat sheet and lazy sort and adding the examples.html page
1 parent 5ea2146 commit 8d88014

File tree

3 files changed

+268
-151
lines changed

3 files changed

+268
-151
lines changed

docs/examples.html

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,19 @@ <h2>Navigation</h2>
153153
</section>
154154

155155
<section>
156-
<h2>Sequences</h2>
157-
<dl>
156+
<h2>Sequences</h2>
157+
<dl>
158+
<dt><a href="../src/examples/sequence/CheatSheet.html">Cheat Sheet</a>
159+
</dt>
160+
<dd>A general overview of the Sequence features - from very basic to moderately advanced combinations.
161+
Code snippets that can be easily copied.
162+
</dd>
158163
<dt><a href="../src/examples/sequence/Stairs.html">Stairs</a>
159164
</dt>
160165
<dd>Kolibri sequences are lazy, immutable, persistent data structures with a rich API and a purely
161166
functional, monadic nature. They can still be used with even animated graphics as the
162-
<a href="../src/examples/sequence/Stairs.html">Stairs</a> example shows.</dd>
167+
<a href="../src/examples/sequence/Stairs.html">Stairs</a> example shows.
168+
</dd>
163169
<dt><a href="../src/examples/sequence/BeautifulMath.html">Beautiful Math</a>
164170
</dt>
165171
<dd>Who would have thought that a simple multiplication table can lead to such
@@ -181,28 +187,36 @@ <h2>Sequences</h2>
181187
</dd>
182188
<dt><a href="../src/examples/sequence/fibonacci/Fibonacci.html">Fibonacci</a></dt>
183189
<dd>While the fibonacci sequence is of course everybody's favorite,
184-
it is also lends itself to a nice graphical <a href="../src/examples/sequence/fibonacci/Fibonacci.html">
185-
Fibonacci</a> construction. Explore for yourself and let the golden ratio emerge!</dd>
190+
it is also lends itself to a nice graphical <a
191+
href="../src/examples/sequence/fibonacci/Fibonacci.html">
192+
Fibonacci</a> construction. Explore for yourself and let the golden ratio emerge!
193+
</dd>
186194
<dt>Fizzbuzz</dt>
187195
<dd>Prepare for the next job interview by solving the fizzbuzz challenge as a
188196
<a href="../src/examples/sequence/fizzbuzz/SimpleFizzBuzz.html">
189-
Simple Functional Fizzbuzz</a> solution or even in an interactive
197+
Simple Functional Fizzbuzz</a> solution or even in an interactive
190198
<a href="../src/examples/sequence/fizzbuzz/FizzBuzz.html">
191-
Generalized Functional Fizzbuzz</a> solution - all made from Kolibri sequences.
199+
Generalized Functional Fizzbuzz</a> solution - all made from Kolibri sequences.
192200
</dd>
193201
<dt><a href="../src/examples/sequence/focusring/demo/SlotMachine.html">Focusring</a></dt>
194202
<dd>The focusring is a usage or sequences where a sequence builds an endless ring
195-
while one element in the ring is considered the focus. For example, the
203+
while one element in the ring is considered the focus. For example, the
196204
<a href="../src/examples/sequence/focusring/demo/SlotMachine.html">Slot Machine</a>
197205
is made from three focus rings.
198206
</dd>
199207
<dt><a href="../src/examples/sequence/tictactoe/TicTacToe.html">Tic Tac Toe</a></dt>
200208
<dd>Playing <a href="../src/examples/sequence/tictactoe/TicTacToe.html">Tic Tac Toe</a>
201-
against the computer gives you some winning chances since the computer only looks
202-
three half-moves ahead. However, this is an example of the functional minimax
203-
algorithm (see John Hughes "Why FP matters") based on Kolibri sequences and the
204-
monadic JINQ (read "jinx") API.</dd>
205-
</dl>
209+
against the computer gives you some winning chances since the computer only looks
210+
three half-moves ahead. However, this is an example of the functional minimax
211+
algorithm (see John Hughes "Why FP matters") based on Kolibri sequences and the
212+
monadic JINQ (read "jinx") API.
213+
</dd>
214+
<dt><a href="../src/examples/sequence/LazySort.html">Lazy Sort</a>
215+
</dt>
216+
<dd>A somewhat silly attempt at sorting by returning the next minimum of the
217+
remaining rest of the sequence.
218+
</dd>
219+
</dl>
206220
</section>
207221

208222
<section>

src/examples/sequence/CheatSheet.html

Lines changed: 153 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,95 @@
44
<meta charset="UTF-8">
55
<title>Kolibri Sequence Cheat Sheet</title>
66
<link rel="shortcut icon" type="image/png" href="../../../img/logo/logo-60x54.png"/>
7+
<link rel="stylesheet" href="../../../css/kolibri-base.css">
78
</head>
89
<style>
910
body {
10-
margin: 1em;
11+
margin-inline: 3rem;
1112
}
12-
main {
13-
display: grid;
14-
grid-template-columns: max-content max-content auto;
15-
gap: .5lh 1em;
13+
14+
header {
15+
margin-bottom: 2lh;
1616
}
17-
main div {
18-
display: grid;
19-
grid-template-columns: subgrid;
20-
grid-column: 1 / -1;
21-
align-items: baseline;
17+
18+
.intro {
19+
padding: 1em;
20+
column-count: auto;
21+
column-width: 40ch;
22+
border-radius: .5em;
23+
color: black;
24+
box-shadow: var(--kolibri-box-shadow);
25+
26+
& li {
27+
margin-bottom: .3lh;
28+
}
29+
30+
& p:nth-child(1) {
31+
margin-top: 0;
32+
}
2233
}
23-
.src, .out {
24-
font-family: monospace;
34+
35+
36+
main div {
37+
display: flex;
38+
flex-direction: column;
39+
gap: .5lh;
40+
padding: .8em;
41+
font-family: monospace;
42+
border-radius: 1em;
43+
&:nth-child(odd) {
44+
background-color: rgb( from var(--kolibri-color-shadow) r g b / .03);
45+
}
2546
}
47+
2648
.src {
27-
white-space: pre-line;
49+
white-space: pre;
2850
}
51+
2952
.out {
30-
color: #0006;
53+
color: var(--kolibri-color-output);
54+
opacity: 60%;
55+
word-wrap: break-word;
3156
}
3257

3358
</style>
3459
<body>
3560
<header>
36-
<h1>Kolibri Sequence Cheat Sheet</h1>
61+
<h1>Kolibri Sequence Cheat Sheet</h1>
62+
<div class="intro">
63+
<p>
64+
The Kolibri Sequence facility is an extension of the standard
65+
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Iteration
66+
protocols</a> that are in the JavaScript stdlib since 2016
67+
and have been upgraded considerably with Baseline 2025 that introduced
68+
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator">new
69+
Iterator functions</a> like map, filter, reduce, forEach, flatMap, and more.
70+
</p>
71+
<p>
72+
This cheat sheet shows how to use Kolibri Sequences and how they play nicely together
73+
with the stdlib iteration features. For full coverage, see the Kolibri sequence test cases and
74+
additional demos and examples.
75+
</p>
76+
<p>
77+
A few things to keep in mind that make all Kolibri Sequences and their operators special:
78+
</p>
79+
<ul>
80+
<li>all constructors and operators are thoroughly typed, documented, and tested</li>
81+
<li>Sequences are immutable, lazy, compositional, and pure (as long as the callback functions are pure)</li>
82+
<li>Sequences can be infinite</li>
83+
<li>names of operators that should only be called on finite sequences end with a $ character (e.g.
84+
reduce$)
85+
</li>
86+
<li>non-terminal operators can be chained (they are monoidal where possible)</li>
87+
<li>Sequences provide "fusion optimization" by design</li>
88+
<li>all operators are available as instance methods as well as utility functions in curried
89+
style for eta reduction, pipelining, and custom operators
90+
</li>
91+
<li>Sequences - along with Pair, Tuple, MayBe, and JSON - are monadic and can therefore be used
92+
with JINQ like in from(...).where(...).select(...).result()
93+
</li>
94+
</ul>
95+
</div>
3796
</header>
3897

3998
<main>
@@ -62,86 +121,85 @@ <h1>Kolibri Sequence Cheat Sheet</h1>
62121
</div>
63122
`);
64123
const codeLines = [
65-
"Walk().show()",
66-
"Walk().show(10)",
67-
"Walk(5).show()",
68-
"Walk(5,10).show()",
69-
"Walk(0,20,5).show()",
70-
"Walk(100,0,-7).show()",
71-
"Walk(1,ALL,2).take(4).show()",
72-
"Walk(1,5,2) ['=='] (Walk(5,1,2))",
73-
"Walk(1,5,-2).eq$(Walk(5,1,-2))",
74-
"Seq().show()",
75-
"Seq(1,2,3).show()",
76-
"Seq(3,4,5,6) ['=='] (Walk(3,6))",
77-
"Seq(42,'***',true).show()",
78-
"Seq(...[1,2,3]).eq$(Walk(1,3))",
79-
"Seq(1).cycle().show()",
80-
"Seq(1).cycle().show()",
81-
"Seq('_','🌹').cycle().show()",
82-
"Sequence('a', x => x.length < 100, x => x+x).show()",
83-
"Sequence(1, forever, x => x/2).show()",
84-
"Walk().map (n => n*n).show()",
85-
"Walk().fmap(n => n*n).show()",
86-
"Walk().take(5).show()",
87-
"Walk().takeWhile(n => n < 9).show()",
88-
"Walk().takeWhere(n => n % 3 === 0).show()",
89-
"Walk().drop(5).show()",
90-
"Walk().dropWhile(n => n < 9).show()",
91-
"Walk().dropWhere(n => n % 3 === 0).show()",
92-
"Walk(1,5).count$()",
93-
"Walk(1,5).reduce$( (acc,cur) => acc + cur, 0)",
94-
"Walk(1,5).reduce$(plusOp, 0)",
95-
"Walk(1,5).map(String).foldl$(plusOp, '')",
96-
"Walk(1,5).map(String).scan(plusOp, '').show()",
97-
"Seq(1,2,3).append(Walk()).show()",
98-
"Seq(1,2,3) ['++'] (Walk()).show()",
99-
"Seq(1,2,3).cons(0).show()",
100-
"Seq(1,2,3).snoc(4).show()",
101-
"Walk(1,4).and( n => Walk(1,n)).show()",
102-
"Walk().and( n => n < 10 ? Seq() : Seq(n,n)).show()",
103-
"Seq(Just(1), Nothing, Just(2)).catMaybes().show()",
104-
`const getAt = idx => Seq(drop(idx-1), take(1));
105-
Walk().pipe(...getAt(10)).show()`,
106-
"Seq(...Pair(1)(2)).show()",
107-
`const [Triple] = Tuple(3);
108-
TupleSequence(Triple ('_')(42)(true) ).show()`,
109-
"Seq(1,2,3).reverse$().show()",
110-
"Seq(1,2,3).min$()",
111-
"Seq('**','***','*').max$((a,b) => a.length < b.length)",
112-
`const seen = [];
113-
Walk()
114-
.tap(n=>seen.push(n))
115-
.take(5)
116-
.forEach$(id);
117-
seen;`,
118-
`const seen = [];
119-
for(const x of Walk().take(5)) { seen.push(x) }
120-
seen;`,
121-
"[...Walk().take(5)]",
122-
"[...Iterator.from(Walk()).take(5)] // Seq -> JS Iterator",
123-
`const every = f => reduce$((acc,cur) => acc && f(cur),true);
124-
Walk(10).pipe(every(n=> n < 11));`,
125-
`const some = f => seq => ! seq.takeWhere(f).isEmpty();
126-
Walk().pipe(some(n=> n > 10));`,
127-
`const last = reduce$((_acc,cur) => Just(cur), Nothing);
128-
Walk(10).pipe(last)(_=>"no last value")(id);`,
129-
`const last = reduce$((_acc,cur) => Just(cur), Nothing);
130-
Seq().pipe(last)(_=>"no last value")(id);`,
131-
`Seq('*','**','***').zip(Walk()).map(([n,i]) => i+":"+n).show()`,
132-
`Seq('*','**','***').zipWith((n,i) => i+":"+n)(Walk()).show()`,
133-
`// make sequence from iterable without consuming
134-
toSeq("abc").show();`,
135-
`toSeq("hello kolibri".split(/ /)).show();`,
136-
`toSeq("0+1-2+3-44".match(/-\\d*/g)).show();`,
137-
`toSeq(document.querySelectorAll('.src')).count$();`,
138-
`toSeq(document.body.children).count$();`,
139-
`from( Walk(2,ALL))
140-
.combine( z => Walk(2,z,1))
141-
.combine( ([z,y]) => Walk(2,Math.sqrt(z),1))
142-
.where ( ([[z,y], x]) => x * y === z )
143-
.select ( ([[z,y], x]) => z+"="+y+"*"+x)
144-
.result().show();`,
124+
"Walk().show()",
125+
"Walk().show(10)",
126+
"Walk(5).show()",
127+
"Walk(5,10).show()",
128+
"Walk(0,20,5).show()",
129+
"Walk(100,0,-7).show()",
130+
"Walk(1,ALL,2).take(4).show()",
131+
"Walk(1,5,2) ['=='] (Walk(5,1,2))",
132+
"Walk(1,5,-2).eq$(Walk(5,1,-2))",
133+
"Seq().show()",
134+
"Seq(1,2,3).show()",
135+
"Seq(3,4,5,6) ['=='] (Walk(3,6))",
136+
"Seq(42,'***',true).show()",
137+
"Seq(...[1,2,3]).eq$(Walk(1,3))",
138+
"Seq(1).cycle().show()",
139+
"Seq('_','🌹').cycle().show()",
140+
"Sequence('a', x => x.length < 100, x => x+x).show()",
141+
"Sequence(1, forever, x => x+x).show(17)",
142+
"Walk().map (n => n*n).show()",
143+
"Walk().fmap(n => n*n).show()",
144+
"Walk().take(5).show()",
145+
"Walk().takeWhile(n => n < 9).show()",
146+
"Walk().takeWhere(n => n % 3 === 0).show()",
147+
"Walk().drop(5).show()",
148+
"Walk().dropWhile(n => n < 9).show()",
149+
"Walk().dropWhere(n => n % 3 === 0).show()",
150+
"Walk(1,5).count$()",
151+
"Walk(1,5).reduce$( (acc,cur) => acc + cur, 0)",
152+
"Walk(1,5).reduce$(plusOp, 0)",
153+
"Walk(1,5).map(String).foldl$(plusOp, '')",
154+
"Walk(1,5).map(String).scan(plusOp, '').show()",
155+
"Seq(1,2,3).append(Walk()).show()",
156+
"Seq(1,2,3) ['++'] (Walk()).show()",
157+
"Seq(1,2,3).cons(0).show()",
158+
"Seq(1,2,3).snoc(4).show()",
159+
"Walk(1,4).and( n => Walk(1,n)).show()",
160+
"Walk().and( n => n < 10 ? Seq() : Seq(n,n)).show()",
161+
"Seq(Just(1), Nothing, Just(2)).catMaybes().show()",
162+
`const getAt = idx => Seq(drop(idx-1), take(1));
163+
Walk().pipe(...getAt(10)).show()`,
164+
"Seq(...Pair(1)(2)).show()",
165+
`const [Triple] = Tuple(3);
166+
TupleSequence(Triple ('_')(42)(true) ).show()`,
167+
"Seq(1,2,3).reverse$().show()",
168+
"Seq(1,2,3).min$()",
169+
"Seq('**','***','*').max$((a,b) => a.length < b.length)",
170+
`const seen = [];
171+
Walk()
172+
.tap(n=>seen.push(n)) // keep side effects in "tap"
173+
.take(5)
174+
.forEach$(id);
175+
seen;`,
176+
`const seen = [];
177+
for(const x of Walk().take(5)) { seen.push(x) }
178+
seen;`,
179+
"[...Walk().take(5)]",
180+
"Iterator.from(Walk()).take(5).toArray() // Seq -> JS Iterator",
181+
`const every = f => reduce$((acc,cur) => acc && f(cur),true);
182+
Walk(10).pipe(every(n=> n < 11));`,
183+
`const some = f => seq => ! seq.takeWhere(f).isEmpty();
184+
Walk().pipe(some(n=> n > 10));`,
185+
`const last = reduce$((_acc,cur) => Just(cur), Nothing);
186+
Walk(10).pipe(last)(_=>"no last value")(id);`,
187+
`const last = reduce$((_acc,cur) => Just(cur), Nothing);
188+
Seq().pipe(last)(_=>"no last value")(id);`,
189+
`Seq('*','**','***').zip(Walk()).map(([n,i]) => i+":"+n).show()`,
190+
`Seq('*','**','***').zipWith((n,i) => i+":"+n)(Walk()).show()`,
191+
`// make sequence from iterable without consuming
192+
toSeq("abc").show();`,
193+
`toSeq("hello kolibri".split(/ /)).show();`,
194+
`toSeq("0+1-2+3-44".match(/-\\d*/g)).show();`,
195+
`toSeq(document.querySelectorAll('.src')).count$();`,
196+
`toSeq(document.body.children).count$();`,
197+
`from( Walk(2,ALL))
198+
.combine( z => Walk(2,z,1))
199+
.combine( ([z,y]) => Walk(2,Math.sqrt(z),1))
200+
.where ( ([[z,y], x]) => z === y * x )
201+
.select ( ([[z,y], x]) => z + "=" + y + "*" + x)
202+
.result().show();`,
145203
];
146204
codeLines.forEach( line => main.append(...makeRow(line, eval(line))) );
147205

0 commit comments

Comments
 (0)