Skip to content

Commit 906a6c5

Browse files
committed
Completed first draft
Signed-off-by: David Laing <david@davidlaing.com>
1 parent ec5d273 commit 906a6c5

File tree

1 file changed

+178
-15
lines changed

1 file changed

+178
-15
lines changed

index.html

Lines changed: 178 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ <h3 class="">Javascript function programming koans</h3>
3636

3737
<div id="area">
3838
<pre id="pre" class="javascript" style="height: 425px; ">
39-
<a href="#1">1) Our Goal</a>
40-
39+
/* TOC goes here */
4140
</pre>
4241
<form id="form">
4342
<div class="buttons" style="display: none; ">
@@ -92,8 +91,8 @@ <h3 class="">Javascript function programming koans</h3>
9291
*/
9392
</pre></dd>
9493

95-
<!-- Slide 3 -->
96-
<dt>How koans work (2)</dt>
94+
<!-- Slide 4 -->
95+
<dt>More on how koans work...</dt>
9796
<dd><pre>
9897
//Sometimes we just want to see what's going on
9998
var theAnswer = 6 * 7;
@@ -107,7 +106,7 @@ <h3 class="">Javascript function programming koans</h3>
107106
}
108107
</pre></dd>
109108

110-
<!-- Slide 1 -->
109+
<!-- Slide 5 -->
111110
<dt>First class functions</dt>
112111
<dd></dd>
113112

@@ -128,7 +127,7 @@ <h3 class="">Javascript function programming koans</h3>
128127
*/
129128
</pre></dd>
130129

131-
<!-- Slide 5 -->
130+
<!-- Slide 6 -->
132131
<dt>Giving functions names</dt>
133132
<dd><pre>
134133
var add = function(x, y) {
@@ -143,7 +142,7 @@ <h3 class="">Javascript function programming koans</h3>
143142
assert(alsoAdd(1, 6) === FILL_ME_IN, "Named functions behave just like other variables");
144143
</pre></dd>
145144

146-
<!-- Slide 6 -->
145+
<!-- Slide 7 -->
147146
<dt>Storing functions in data structures</dt>
148147
<dd><pre>
149148
var result = 0;
@@ -166,7 +165,7 @@ <h3 class="">Javascript function programming koans</h3>
166165
assert(result === FILL_ME_IN, "what is the final result?");
167166
</pre></dd>
168167

169-
<!-- Slide 7 -->
168+
<!-- Slide 8 -->
170169
<dt>Passing a function as an argument to another function call</dt>
171170
<dd><pre>
172171
var afterMeditation = function(knowledge) {
@@ -181,7 +180,7 @@ <h3 class="">Javascript function programming koans</h3>
181180
thinkLongAndHard('wind', 'rain', afterMeditation);
182181
</pre></dd>
183182

184-
<!-- Slide 8 -->
183+
<!-- Slide 9 -->
185184
<dt>You can return a function from another function</dt>
186185
<dd><pre>
187186
var powerFactory = function(power) {
@@ -200,11 +199,11 @@ <h3 class="">Javascript function programming koans</h3>
200199
assert(squared(2) + cubed(3) === FILL_ME_IN, "functions can create new functions");
201200
</pre></dd>
202201

203-
<!-- Slide 1 -->
202+
<!-- Slide 10 -->
204203
<dt>Higher order functions</dt>
205204
<dd></dd>
206205

207-
<!-- Slide 9 -->
206+
<!-- Slide 11 -->
208207
<dt>First class functions make common operations with collections easy</dt>
209208
<dd><pre>
210209
/*
@@ -219,15 +218,18 @@ <h3 class="">Javascript function programming koans</h3>
219218
* (7) range
220219
* (8) flatten
221220
*
222-
* because the apply a function to a list in a common way.
221+
* because they apply a function to a list in a common way.
222+
* (We use the underscore.js library to ensure these are
223+
* applied consistently across all browsers)
223224
*
224225
*/
225226
</pre></dd>
226227

227-
<!-- Slide 10 -->
228+
<!-- Slide 12 -->
228229
<dt>Each</dt>
229230
<dd><pre>
230231
/* Iterates over a list of elements, yielding each in turn to an iterator function. */
232+
231233
var numbers = [1,2,3];
232234
var msg = "";
233235
var isEven = function(item) {
@@ -240,11 +242,172 @@ <h3 class="">Javascript function programming koans</h3>
240242
assert(numbers === FILL_ME_IN, "but the original list wasn't touched");
241243
</pre></dd>
242244

245+
<!-- Slide 13 -->
246+
<dt>Map</dt>
247+
<dd><pre>
248+
/* Produces a new array of values by mapping each value in list through a transformation function (iterator). */
243249

244-
<!-- Slide 9 -->
250+
var numbers = [1, 2, 3];
251+
var numbersPlus1 = _.map(numbers, function(x) { return x + 1 });
252+
253+
assert(numbersPlus1 === FILL_ME_IN, "each element is the result of the function applied to the original list");
254+
assert(numbers === FILL_ME_IN, "but the original list wasn't touched");
255+
</pre></dd>
256+
257+
<!-- Slide 14 -->
258+
<dt>Filter</dt>
259+
<dd><pre>
260+
/* Looks through each value in the list, returning an array of all the values that pass a truth test (iterator) */
261+
262+
var numbers = [1,2,3];
263+
var odd = _(numbers).filter(function (x) { return x % 2 !== 0 });
264+
265+
assert(odd === FILL_ME_IN, "should only contain odd");
266+
assert(numbers === FILL_ME_IN, "but the original list isn't touched");
267+
</pre></dd>
268+
269+
<!-- Slide 15 -->
270+
<dt>Reduce</dt>
271+
<dd><pre>
272+
/* Reduce boils down a list of values into a single value. */
273+
274+
var numbers = [1, 2, 3];
275+
var reduction = _(numbers).reduce(
276+
function(/* result from last call */ memo, /* current */ x) { return memo + x }, /* initial */ 0);
277+
278+
assert(reduction === FILL_ME_IN, "should be the cumulative sum");
279+
assert(numbers === FILL_ME_IN, "but the original list isn't touched");
280+
</pre></dd>
281+
282+
<!-- Slide 16 -->
283+
<dt>All</dt>
284+
<dd><pre>
285+
/* Returns true if all of the values in the list pass the iterator truth test */
286+
287+
var onlyEven = [2,4,6];
288+
var mixedBag = [2,4,5,6];
289+
290+
var isEven = function(x) { return x % 2 === 0 };
291+
292+
assert(_(onlyEven).all(isEven) === FILL_ME_IN, "are _all_ of the list items even?");
293+
assert(_(mixedBag).all(isEven) === FILL_ME_IN, "leave the original list alone!");
294+
</pre></dd>
295+
296+
<!-- Slide 17 -->
297+
<dt>Any</dt>
298+
<dd><pre>
299+
/* Returns true if any of the values in the list pass the iterator truth test.
300+
* Short-circuits and stops traversing the list if a true element is found.
301+
*/
302+
303+
var onlyEven = [2,4,6];
304+
var mixedBag = [2,4,5,6];
305+
306+
var isEven = function(x) { return x % 2 === 0 };
307+
308+
assert(_(onlyEven).any(isEven) === FILL_ME_IN, "are any of the list items even?");
309+
assert(_(mixedBag).any(isEven) === FILL_ME_IN, "leave the original list alone!");
310+
</pre></dd>
311+
312+
<!-- Slide 18 -->
313+
<dt>Range</dt>
314+
<dd><pre>
315+
/* A function to create flexibly-numbered lists of integers, handy for each and map loops. */
316+
317+
assert(_.range(3) === FILL_ME_IN, "should have 3 elements");
318+
assert(_.range(1, 4) === FILL_ME_IN, "should start at 1 and end at 4 (exclusive)" );
319+
assert(_.range(0, -4, -1) === FILL_ME_IN, "should increment in steps of -1");
320+
</pre></dd>
321+
322+
<!-- Slide 19 -->
323+
<dt>Flatten</dt>
324+
<dd><pre>
325+
/* A function to create flexibly-numbered lists of integers, handy for each and map loops. */
326+
expect(_([ [1, 2], [3, 4] ]).flatten() === FILL_ME_IN);
327+
</pre></dd>
328+
329+
<!-- Slide 20 -->
330+
<dt>Chain</dt>
331+
<dd><pre>
332+
/* Returns a wrapped object.
333+
* Calling methods on this object will continue to return wrapped objects until value is used.
334+
*/
335+
336+
var result = _([ [0, 1], 2 ]).chain()
337+
.flatten()
338+
.map(function(x) { return x+1 } )
339+
.reduce(function (sum, x) { return sum + x })
340+
.value();
341+
342+
assert(result === FILL_ME_IN);
343+
</pre></dd>
344+
345+
346+
<!-- Slide 21 -->
245347
<dt>Continuations</dt>
348+
<dd></dd>
349+
350+
<!-- Slide 22 -->
351+
<dt>Continuations enable async programming</dt>
352+
<dd><pre>
353+
/*TODO: Sample involving waiting on lots of network calls -
354+
perhaps fetching a set of RSS feeds & doing some aggregation? */
355+
</pre></dd>
356+
357+
<!-- Slide 23 -->
358+
<dt>Applying our enlightenment</dt>
359+
<dd></dd>
360+
361+
<!-- Slide 24 -->
362+
<dt>Applying our enlightenment</dt>
363+
<dd><pre>
364+
var products = [
365+
{ name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
366+
{ name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
367+
{ name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
368+
{ name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
369+
{ name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
370+
];
371+
372+
/* Given I'm allergic to nuts and hate mushrooms, find a pizza I can eat (imperative) */
373+
374+
var i,j,hasMushrooms, productsICanEat = [];
375+
376+
for (i = 0; i < products.length; i+=1) {
377+
if (products[i].containsNuts === false) {
378+
hasMushrooms = false;
379+
for (j = 0; j < products[i].ingredients.length; j+=1) {
380+
if (products[i].ingredients[j] === "mushrooms") {
381+
hasMushrooms = true;
382+
}
383+
}
384+
if (!hasMushrooms) productsICanEat.push(products[i]);
385+
}
386+
}
387+
388+
assert(productsICanEat.length == FILL_ME_IN);
389+
390+
/* now solve in a functional style */
391+
392+
productsICanEat = [];
393+
394+
/* try using filter() & all() / any() */
395+
396+
assert(productsICanEat.length === FILL_ME_IN);
397+
398+
</pre></dd>
399+
400+
<!-- Slide 25 -->
401+
<dt>Go forth</dt>
246402
<dd><pre>
247-
/*TODO*/
403+
/* Congratulations grasshopper, you have reached the first level of
404+
* functional enlightenment!
405+
*
406+
* Remember to take this new awareness with you when solving
407+
* everyday problems - you will find that many of your
408+
* existing tools contain functional elements, and that these
409+
* can greatly simplify a certain class of problems
410+
*/
248411
</pre></dd>
249412

250413
</dl>

0 commit comments

Comments
 (0)