Javascript
I think it should be obvious by now that the next paradigm is Distributed Eventual Programming. This is not a new idea. It goes back at least to the discovery of the Actor Model (1973). We have made some steps forward since that, but we have also made mistakes with things like remote procedure calls that try to do the distributed thing while holding onto the sequential programming model. I think the reason that JavaScript is interesting is that it was specifically created to do Distributed Eventual Programming. — How JavaScript works
Destructuring
The let statement also allows destructuring. This is a tricky bit of syntax that defines and initializes multiple variables with the contents of an object or array.
let {huey, dewey, louie} = my_little_object;
is shorthand for
let huey = my_little_object.huey;
let dewey = my_little_object.dewey;
let louie = my_little_object.louie;
Similarly
let [zeroth, wunth, twoth] = my_little_array;
is shorthand for
let zeroth = my_little_array[0];
let wunth = my_little_array[1];
let twoth = my_little_array[2];
Mutability/Purity
“Pure” functions don’t change their inputs, whereas “impure” functions get objects (including arrays) as arguments and mutate these.
Enumerations
JavaScript getter syntax offers an alternative to using switch to dispatch or route functions with zero parameters:
const TrafficLight = {
get red() {
return "red";
},
get yellow() {
return "yellow";
},
"green: "green"
};
Then TrafficLight["red"] returns "red". In this simple example, it’s just a more convoluted way of getting a string keyword to return itself, which can be turn in a more conventional ways as in the “green” example, but illustrates an ellegant way to use methods in object literals.
text-oriented-programing
The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information. — Alan J. Perlis
Reading Douglas Crockford’s How JavaScript Works reinforced my existing bias of “text over pointers” when it comes to data. I’m prejudiced against the conventional jargon term string for text since it’s a missuse of the word used to describe a path of lables giving a route through a state machine, which at its lowest level is text.
arrays
Douglas Crockford in How JavaScript Works divided array methods into “pure” (ie ones that don’t mutate the original array), and “impure” which often trip me up by often not returning anything while changing the original array.
Pure methods:
- concat
- every
- filter
- find
- findIndex
- forEach
- indexOf
- join
- lastIndexOf
- map
- reduce
- reduceRight
- slice
- some
Impure methods:
- fill
- pop
- push
- shift
- splice
- unshift
Impure methods that should have been pure:
- reverse
- sort
Objects->Arrays, Arrays->Objects
Objects can be represented as an array of [key, value] arrays using Object.entries(obj)
modules
Declaration
The modern way is to load a main.js file in the head of an HTML document with the attribute type="module":
<head>
...
<script type="module" src="/js/main.js"></script>
</head>
This replaces the old way of loading the file before the closing </body> to ensure the DOM objects used by the JavaScript code were known to it. Something that tripped me up is the type="module" attribute means main.js is a module client, aka importer, not an exporter, ie what’s generally thought of as a module.
jsdoc
To install, as root:
npm install -g jsdoc
Google JavaScript Style Guide
jsdoc -d doc -r js -R js/README.md
Style guides
- Forked from the KimonoLabs JS Doc Style Guide
- JSDoc: Return object structure
- How to describe “object” arguments in jsdoc?
jasmine
Installing
Download the latest zip file from Github.
unzip jasmine-standalone-6.2.0.zip
Archive: jasmine-standalone-6.2.0.zip
inflating: LICENSE
inflating: SpecRunner.html
inflating: lib/jasmine-6.2.0/jasmine_favicon.png
inflating: lib/jasmine-6.2.0/jasmine.js
inflating: lib/jasmine-6.2.0/jasmine-html.js
inflating: lib/jasmine-6.2.0/jasmine.css
inflating: lib/jasmine-6.2.0/boot0.js
inflating: lib/jasmine-6.2.0/boot1.js
inflating: src/Song.js
inflating: src/Player.js
inflating: spec/SpecHelper.js
inflating: spec/PlayerSpec.js
Alternatively:
git clone https://github.com/jasmine/jasmine.git
The key files are in jasmine/lib/jasmine-core.
Home Page
The SpecRunner.html is a template for a file I copy to /project-home/test/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Jasmine Spec Runner v6.2.0</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-6.2.0/jasmine_favicon.png">
<link rel="stylesheet" href="lib/jasmine-6.2.0/jasmine.css">
<script src="lib/jasmine-6.2.0/jasmine.js"></script>
<script src="lib/jasmine-6.2.0/jasmine-html.js"></script>
<script src="lib/jasmine-6.2.0/boot0.js"></script>
<!-- optional: include a file here that configures the Jasmine env -->
<script src="lib/jasmine-6.2.0/boot1.js"></script>
<!-- include source files here... -->
<script src="src/Player.js"></script>
<script src="src/Song.js"></script>
<!-- include spec files here... -->
<script src="spec/SpecHelper.js"></script>
<script src="spec/PlayerSpec.js"></script>
</head>
<body>
</body>
</html>
Hacking modules
Initially I loaded my Jasmine spec files as modules and imported my JavasScript modules into that.
node
After gaining some experience at using Bash’s associative arrays to handle JSON, I decided a better approach would be to rather write Unix filters in JavaScript which read JSON from stdin and write the munged JSON to stdout while logging problems to stderr.
Courtesy of node, that can be done, though it required deciphering its jargon. For instance what I’d call a remote procedure call to, say, date, involves using Node’s child_process module.
As a first exercise, let’s rewrite the bash function below: