Up and Compose
The following examples use the Emmy computer algebra system. The source of this post can be found here, you can copy-paste the html-code to a local file.
Arrays and Vectors in JavaScript
Some abbreviations
var cos = Math.cos;
var sin = Math.sin; null;
JavaScript arrays are a nice way to combine numbers and calculate.
[1, 0].map(sin);
In the same manner, the function up
of the algebra package Emmy is a way to combine numbers to a vector.
requireEmmy("up");
up(1, 0);
Do not be confused by the fact that the result itself includes the function name "up". You only see the string representation of the data as it was chosen by the library designers. Indeed, when accessing the zeroth element of our up vector, we get a number.
requireEmmy("get");
var data = up(1,0);
get(data,0);
One can even convert an up
vector into a JS array, but that is ugly and not used further.
requireEmmy("clj__GT_js");
clj__GT_js(up(1, 0)).map(sin);
Sure, one can call functions inside of other functions,
cos(sin(0));
and up
is no exception.
up(cos(0), sin(0));
In JS arrays, not only can one combine numbers, but also functions.
[cos, sin];
Also up
vectors can contain funtions in the same manner.
up(cos, sin);
Now the cool thing is that if an up
vector only contains functions, one can call the vector. In this way, a vector behaves itself like a function.
up(cos, sin).call(null,0);
Composition
We had functions within functions before
cos(sin(0));
The same result is achieved with function composition.
requireEmmy("compose");
compose(cos, sin).call(null, 0);
And function composition is indeed necessary when working with vectors.
up(cos, compose(cos, sin)).call(null,0);
Scheme syntax
As a follow up to the expositions in blog post Sicmutils as JavaScript library (3), we include a simple Scheme syntax transpiler.
var insertCommas = (txt) =>
txt.replace(/(\w+)/g,'"$1",')
.replace(/\,\s+\]/g," ]");
var makeBrackets = (txt) =>
txt.trim()
.replace(/\(/g,"[ ")
.replace(/\)/g," ],")
.replace(/,$/,"");
var textToJson = (txt) =>
insertCommas(makeBrackets(txt));
The above JavaScript program already defines the Scheme syntax. This syntax is shown below. Scheme code is converted into a nested JavaScript array (the so called AST).
(up (cos 0) (sin 0))
The magic to convert this AST into JavaScript is just in the following half dozen lines of code
var jsonToJs = (j) =>
j.constructor == Array
? jsonToJs(j[0]) + ".call(null," + j.slice(1).map(jsonToJs) + ")"
: j;
var expressionToJs = (expr) =>
jsonToJs(JSON.parse(textToJson(expr))) + ";";
Scheme syntax transpiled to Javascript
;((up cos sin) 0)
Scheme syntax executed
((up cos sin) 0)
((up cos (compose cos sin)) 0)