first commit
This commit is contained in:
94
javascript/examples/0_1_magic.js
Normal file
94
javascript/examples/0_1_magic.js
Normal file
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
|
||||
// Magic helper functions
|
||||
function example(s, description) {
|
||||
const result = (() => {
|
||||
try {
|
||||
return eval(s);
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
})();
|
||||
|
||||
if (description) {
|
||||
println(description + ":", s, "->", result);
|
||||
} else {
|
||||
println(s, "->", result);
|
||||
}
|
||||
}
|
||||
|
||||
function examples(collection, template) {
|
||||
collection.forEach(function(name) {
|
||||
return example(template.replace('#', name).replace('#', name));
|
||||
});
|
||||
}
|
||||
|
||||
function subsection(name) {
|
||||
println();
|
||||
println("---", name);
|
||||
}
|
||||
|
||||
function section(name) {
|
||||
println();
|
||||
println();
|
||||
println("===", name, "===");
|
||||
}
|
||||
|
||||
function chapter(name) {
|
||||
println();
|
||||
println();
|
||||
println();
|
||||
println("##########", name, "##########");
|
||||
}
|
||||
|
||||
function lecture(name) {
|
||||
println();
|
||||
println("#".repeat(name.length + 16));
|
||||
println("### Lecture " + name + " ###");
|
||||
println("#".repeat(name.length + 16));
|
||||
}
|
||||
|
||||
// Helper function
|
||||
function dumpProperty(o, property) {
|
||||
if (typeof(o[property]) === "function") {
|
||||
if (o[property].length === 0) {
|
||||
println(" " + property.toString() + "() -> " + o[property]());
|
||||
} else {
|
||||
println(" " + property.toString() + "(...)");
|
||||
}
|
||||
} else {
|
||||
println(" " + property.toString() + " = " + o[property]);
|
||||
}
|
||||
}
|
||||
|
||||
function dumpObject(name, o) {
|
||||
println(name + ": " + o.constructor.name);
|
||||
for (const property in o) {
|
||||
dumpProperty(o, property);
|
||||
}
|
||||
let symbols = Object.getOwnPropertySymbols(o);
|
||||
if (symbols.length > 0) {
|
||||
for (const property of symbols) {
|
||||
dumpProperty(o, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dumpArray(a) {
|
||||
const other = (Object.keys(a)
|
||||
.filter(i => i != "" + parseInt(i) || !(0 <= i && i < a.length))
|
||||
.map(name => name + " = " + a[name])
|
||||
.join(", ")
|
||||
);
|
||||
println(" length: " + a.length + ", elements: [" + a + "]" + (other ? ", other: {" + other + "}" : ""));
|
||||
}
|
||||
|
||||
if (!String.prototype.repeat) {
|
||||
String.prototype.repeat = function(count) {
|
||||
let result = "";
|
||||
for (let i = 0; i < count; i++) {
|
||||
result += this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
51
javascript/examples/1_1_types.js
Normal file
51
javascript/examples/1_1_types.js
Normal file
@@ -0,0 +1,51 @@
|
||||
"use strict";
|
||||
|
||||
chapter("Types");
|
||||
section("Variables are typeless");
|
||||
|
||||
let v = 1;
|
||||
example("v");
|
||||
example(" typeof(v)");
|
||||
|
||||
v = "Hello";
|
||||
example("v");
|
||||
example(" typeof(v)");
|
||||
|
||||
section("Values are typed");
|
||||
let as = ["'Hello'", 1, 1.1, true, false, [1, 2, 3], new Array(1, 2, 3), null, undefined];
|
||||
for (let i = 0; i < as.length; i++) {
|
||||
println("v =", as[i]);
|
||||
println(" typeof(v) ->", typeof(as[i]));
|
||||
}
|
||||
|
||||
section("Ordinary comparison");
|
||||
example("'1' == '1'");
|
||||
example("'1' == 1");
|
||||
example("'1.0' == 1");
|
||||
example("undefined == undefined");
|
||||
example("undefined == null");
|
||||
example("null == null");
|
||||
example("0 == []");
|
||||
example("'10' == [10]");
|
||||
|
||||
section("Strict comparison");
|
||||
example("'1' === '1'");
|
||||
example("'1' === 1");
|
||||
example("undefined === undefined");
|
||||
example("undefined === null");
|
||||
example("null === null");
|
||||
example("0 === []");
|
||||
example("'10' === [10]");
|
||||
|
||||
section("Calculations");
|
||||
subsection("Addition");
|
||||
example("2 + 3");
|
||||
example("2.1 + 3.1");
|
||||
example("'2.1' + '3.1'");
|
||||
example("'Hello, ' + 'world!'");
|
||||
|
||||
subsection("Subtraction");
|
||||
example("2 - 3");
|
||||
example("2.1 - 3.1");
|
||||
example("'2.1' - '3.1'");
|
||||
example("'Hello, ' - 'world!'");
|
||||
68
javascript/examples/1_2_arrays.js
Normal file
68
javascript/examples/1_2_arrays.js
Normal file
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
|
||||
chapter("Arrays");
|
||||
|
||||
section("Like in Java?");
|
||||
example("as = [10, 20, 30]");
|
||||
println("as -> [" + as +"]");
|
||||
example("as.length");
|
||||
example("as[2]");
|
||||
example("as[3]");
|
||||
|
||||
subsection("Mostly");
|
||||
example("as['2']");
|
||||
example("as[2.0]");
|
||||
example("as['2.0']");
|
||||
example("as.constructor.name");
|
||||
|
||||
section("Variable length");
|
||||
subsection("push/pop");
|
||||
example("as = new Array(10, 20, 30)");
|
||||
example("as.push(40, 50)");
|
||||
dumpArray(as);
|
||||
example("as.pop()");
|
||||
dumpArray(as);
|
||||
example("as.pop()");
|
||||
dumpArray(as);
|
||||
|
||||
subsection("unshift/shift");
|
||||
example("as.unshift(60, 70)");
|
||||
dumpArray(as);
|
||||
example("as.shift()");
|
||||
dumpArray(as);
|
||||
example("as.shift()");
|
||||
dumpArray(as);
|
||||
|
||||
|
||||
section("Weird indices");
|
||||
example("as[3] = 80");
|
||||
dumpArray(as);
|
||||
example("as[10] = 90");
|
||||
dumpArray(as);
|
||||
example(" typeof(as[5])");
|
||||
|
||||
example("as[-1] = 100");
|
||||
dumpArray(as);
|
||||
example(" as[-1]");
|
||||
|
||||
example("as['2.0'] = 110");
|
||||
dumpArray(as);
|
||||
example(" as['2.0']");
|
||||
|
||||
example("as['hello'] = 120");
|
||||
dumpArray(as);
|
||||
example(" as['hello']");
|
||||
|
||||
|
||||
section("Enumeration")
|
||||
|
||||
print("Indexed for")
|
||||
for (var i = 0; i < as.length; i++) {
|
||||
example(" as[i]");
|
||||
}
|
||||
|
||||
|
||||
print("for of")
|
||||
for (var a of as) {
|
||||
example(" a");
|
||||
}
|
||||
128
javascript/examples/1_3_functions.js
Normal file
128
javascript/examples/1_3_functions.js
Normal file
@@ -0,0 +1,128 @@
|
||||
"use strict";
|
||||
|
||||
chapter("Functions");
|
||||
section("Arguments");
|
||||
|
||||
subsection("Indices");
|
||||
let dumpArgs = function() {
|
||||
println(arguments.constructor.name);
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
println(" ", i, arguments[i]);
|
||||
}
|
||||
};
|
||||
println("let dumpArgs =", dumpArgs);
|
||||
example("dumpArgs(1, 2, 'hello', null, undefined)");
|
||||
|
||||
|
||||
subsection("Values");
|
||||
let dumpArgs2 = function() {
|
||||
println(arguments.constructor.name);
|
||||
for (const arg of arguments) {
|
||||
println(" ", arg);
|
||||
}
|
||||
};
|
||||
println("let dumpArgs2 =", dumpArgs2);
|
||||
example("dumpArgs2(1, 2, 'hello', null, undefined)");
|
||||
|
||||
|
||||
subsection("sum");
|
||||
|
||||
let sum = function() {
|
||||
let result = 0;
|
||||
for (const arg of arguments) {
|
||||
result += arg;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
println("let sum =", sum);
|
||||
example("sum(1, 2, 3)");
|
||||
|
||||
|
||||
subsection("minimum");
|
||||
|
||||
let minimum = function() {
|
||||
let result = Infinity;
|
||||
for (const arg of arguments) {
|
||||
if (result > arg) {
|
||||
result = arg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
println("let minimum =", minimum);
|
||||
example("minimum(1, -2, 3)");
|
||||
|
||||
|
||||
section("Named functions and arguments");
|
||||
|
||||
function min(a, b) {
|
||||
//println(" ", typeof(a), typeof(b));
|
||||
return a < b ? a : b;
|
||||
}
|
||||
println(min);
|
||||
example("min(1, -1)");
|
||||
example("min(1, -1)");
|
||||
example("min(1)");
|
||||
example("min()");
|
||||
|
||||
subsection("Still values");
|
||||
let m = min;
|
||||
example("m");
|
||||
example("m.name");
|
||||
example("m.length");
|
||||
example("m(10, 20)");
|
||||
|
||||
|
||||
section("Default arguments");
|
||||
|
||||
function def(a = -10, b = -20) {
|
||||
return [a, b];
|
||||
}
|
||||
println(def);
|
||||
example("def(1, 2)");
|
||||
example("def(1)");
|
||||
example("def()");
|
||||
|
||||
|
||||
section("Rest argument and spread calls");
|
||||
|
||||
function minRest(first, ...rest) {
|
||||
let result = first;
|
||||
for (const a of rest) {
|
||||
result = min(result, a);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
println(minRest);
|
||||
example("minRest(1)");
|
||||
example("minRest(1, -1)");
|
||||
example("minRest(1, -1, 2, -2)");
|
||||
example("minRest(...[1, -1, 2, -2])");
|
||||
example("minRest(1, -1, ...[2, -2])");
|
||||
|
||||
|
||||
section("Arrow functions");
|
||||
|
||||
const minArr = (a, b) => a < b ? a : b;
|
||||
example("minArr");
|
||||
example("minArr(1, -2)");
|
||||
|
||||
const minArrow = (first, ...rest) => {
|
||||
let result = first;
|
||||
for (const a of rest) {
|
||||
result = Math.min(result, a);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
example("minArrow");
|
||||
example("minArrow(1)");
|
||||
example("minArrow(1, -1)");
|
||||
example("minArrow(1, -1, 2, -2)");
|
||||
|
||||
const stupidArrow = (v) => {
|
||||
println(v);
|
||||
// No "arguments" for arrow functions
|
||||
// println(arguments);
|
||||
};
|
||||
example("stupidArrow");
|
||||
example("stupidArrow(3)");
|
||||
169
javascript/examples/1_4_functions-hi.js
Normal file
169
javascript/examples/1_4_functions-hi.js
Normal file
@@ -0,0 +1,169 @@
|
||||
"use strict"; 4
|
||||
|
||||
chapter("Hi-order functions");
|
||||
section("Minimum by absolute value");
|
||||
|
||||
let minimumByAbs = function(...args) {
|
||||
let result = Infinity;
|
||||
for (const arg of args) {
|
||||
if (Math.abs(result) > Math.abs(arg)) {
|
||||
result = arg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
println("minimumByAbs =", minimumByAbs);
|
||||
example("minimumByAbs(1, -2, 3)");
|
||||
|
||||
|
||||
section("Unify minimum and minimumByAbs");
|
||||
|
||||
subsection("High-order functions");
|
||||
function minimumBy(comparator, init = Infinity) {
|
||||
return (...args) => {
|
||||
let result = init;
|
||||
for (const arg of args) {
|
||||
if (comparator(result, arg) > 0) {
|
||||
result = arg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
println(minimumBy);
|
||||
|
||||
function comparing(f) {
|
||||
return (a, b) => f(a) - f(b);
|
||||
}
|
||||
println(comparing);
|
||||
|
||||
const identity = a => a;
|
||||
println("const identity =", identity);
|
||||
|
||||
function maximumBy(comparator, init = -Infinity) {
|
||||
return minimumBy((a, b) => -comparator(a, b), init);
|
||||
}
|
||||
println(maximumBy);
|
||||
|
||||
|
||||
subsection("Definitions");
|
||||
|
||||
let minimumByV = minimumBy(comparing(identity));
|
||||
minimumByAbs = minimumBy(comparing(Math.abs));
|
||||
let maximumByLength = maximumBy(comparing(s => s.length), "");
|
||||
|
||||
example("minimumByV");
|
||||
example("minimumByAbs");
|
||||
example("maximumByLength");
|
||||
example("minimumByV(1, -2, 3)");
|
||||
example("minimumByAbs(1, -2, 3)");
|
||||
example("maximumByLength('aa', 'bbb', 'c')");
|
||||
|
||||
|
||||
section("Unify minimumBy and sum");
|
||||
|
||||
subsection("High-order functions");
|
||||
function foldLeft(f, zero) {
|
||||
return (...args) => {
|
||||
let result = zero;
|
||||
for (const arg of args) {
|
||||
result = f(result, arg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
println(foldLeft);
|
||||
|
||||
function minBy(f) {
|
||||
return (a, b) => f(a) < f(b) ? a : b;
|
||||
}
|
||||
println(minBy);
|
||||
|
||||
subsection("Definitions");
|
||||
const sum2 = foldLeft((a, b) => a + b, 0);
|
||||
const product = foldLeft((a, b) => a * b, 1);
|
||||
minimumByAbs = foldLeft(minBy(comparing(Math.abs)), Infinity);
|
||||
example("sum2(1, -2, 3)");
|
||||
example("product(1, -2, 3)");
|
||||
example("minimumByAbs(1, -2, 3)");
|
||||
|
||||
|
||||
section("sumSquares and sumAbs");
|
||||
|
||||
let square = x => x * x;
|
||||
let sumSquares = foldLeft((a, b) => a + square(b), 0);
|
||||
let sumAbs = foldLeft((a, b) => a + Math.abs(b), 0);
|
||||
example("sumSquares(1, -2, 3)");
|
||||
example("sumAbs(1, -2, 3)");
|
||||
|
||||
|
||||
subsection("High-order functions");
|
||||
function map(f) {
|
||||
return (...args) => {
|
||||
const result = [];
|
||||
for (const arg of args) {
|
||||
result.push(f(arg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
println(map);
|
||||
|
||||
function compose(f, g) {
|
||||
return (...args) => f(g(...args));
|
||||
}
|
||||
println(compose);
|
||||
|
||||
function unspread(f) {
|
||||
return args => f(...args);
|
||||
}
|
||||
println(unspread);
|
||||
|
||||
subsection("Definitions");
|
||||
sumSquares = compose(unspread(sum2), map(square));
|
||||
sumAbs = compose(unspread(sum2), map(Math.abs));
|
||||
example("sumSquares(1, -2, 3)");
|
||||
example("sumAbs(1, -2, 3)");
|
||||
|
||||
|
||||
section("diff");
|
||||
|
||||
let diff = dx => f => x => (f(x + dx) - f(x - dx)) / 2 / dx;
|
||||
|
||||
let dsin = diff(1e-7)(Math.sin);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
println(i + " " + Math.cos(i) + " " + dsin(i) + " " + Math.abs(Math.cos(i) - dsin(i)));
|
||||
}
|
||||
|
||||
|
||||
section("Currying");
|
||||
subsection("curry");
|
||||
|
||||
const curry = f => a => b => f(a, b);
|
||||
|
||||
const addC = curry((a, b) => a + b);
|
||||
const add10 = addC(10);
|
||||
example("addC(10)(20)");
|
||||
example("add10(20)");
|
||||
|
||||
|
||||
subsection("uncurry");
|
||||
|
||||
const uncurry = f => (a, b) => f(a)(b);
|
||||
const addU = uncurry(a => b => a + b);
|
||||
example("addU(10, 20)");
|
||||
|
||||
|
||||
subsection("mCurry");
|
||||
|
||||
println("bind");
|
||||
let bind = (f, ...as) => (...args) => f(...[...as, ...args]);
|
||||
let add100 = bind((a, b) => a + b, 100);
|
||||
example(" add100(200)");
|
||||
|
||||
println("mCurry");
|
||||
let mCurry = curry(bind);
|
||||
let sub = mCurry((a, b, c) => a - b - c);
|
||||
let sub10 = sub(10);
|
||||
example(" sub(10)(20, 30)");
|
||||
example(" sub10(20, 30)");
|
||||
52
javascript/examples/1_5_vectors.js
Normal file
52
javascript/examples/1_5_vectors.js
Normal file
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
chapter("Vector and matrix operations");
|
||||
|
||||
section("Scalar operations");
|
||||
const addS = (a, b) => a + b;
|
||||
const subtractS = (a, b) => a - b;
|
||||
const multiplyS = (a, b) => a * b;
|
||||
example("addS(2, 3)");
|
||||
example("subtractS(2, 3)");
|
||||
example("multiplyS(2, 3)");
|
||||
|
||||
section("Vector operations");
|
||||
function transpose(matrix) {
|
||||
const result = [];
|
||||
for (let i = 0; i < matrix[0].length; i++) {
|
||||
const row = [];
|
||||
for (let j = 0; j < matrix.length; j++) {
|
||||
row.push(matrix[j][i]);
|
||||
}
|
||||
result.push(row);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const apply = f => args => f(...args);
|
||||
const zipWith = f => (...args) => apply(map(apply(f)))(transpose(args));
|
||||
const sumV = v => sum(...v);
|
||||
|
||||
const addV = zipWith(addS);
|
||||
const subtractV = zipWith(subtractS);
|
||||
const multiplyV = zipWith(multiplyS);
|
||||
const scalar = compose(sumV, multiplyV);
|
||||
example("addV([1, 2, 3], [4, 5, 6])");
|
||||
example("subtractV([1, 2, 3], [4, 5, 6])");
|
||||
example("multiplyV([1, 2, 3], [4, 5, 6])");
|
||||
example("scalar([1, 2, 3], [4, 5, 6])");
|
||||
|
||||
section("Matrix operations");
|
||||
function multiplyM(a, b) {
|
||||
return apply(map(ar => apply(map(curry(scalar)(ar)))(transpose(b))))(a);
|
||||
}
|
||||
const addM = zipWith(addV);
|
||||
const subtractM = zipWith(subtractV);
|
||||
example("addM([[1, 2], [3, 4]], [[5, 6], [7, 8]])[0]");
|
||||
example("addM([[1, 2], [3, 4]], [[5, 6], [7, 8]])[1]");
|
||||
example("subtractM([[1, 2], [3, 4]], [[5, 6], [7, 8]])[0]");
|
||||
example("subtractM([[1, 2], [3, 4]], [[5, 6], [7, 8]])[1]");
|
||||
example("transpose([[1, 2], [3, 4]])[0]");
|
||||
example("transpose([[1, 2], [3, 4]])[1]");
|
||||
example("multiplyM([[1, 2], [3, 4]], [[5, 6], [7, 8]])[0]");
|
||||
example("multiplyM([[1, 2], [3, 4]], [[5, 6], [7, 8]])[1]");
|
||||
Reference in New Issue
Block a user