<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>The Mandelbear&apos;s Musings</title>
  <link>https://mdlbear.dreamwidth.org/</link>
  <description>The Mandelbear&apos;s Musings - Dreamwidth Studios</description>
  <lastBuildDate>Tue, 23 Oct 2018 00:11:06 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>mdlbear</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/15740388/505737</url>
    <title>The Mandelbear&apos;s Musings</title>
    <link>https://mdlbear.dreamwidth.org/</link>
    <width>96</width>
    <height>96</height>
  </image>

<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1639781.html</guid>
  <pubDate>Tue, 23 Oct 2018 00:11:06 GMT</pubDate>
  <title>Further Adventures in Hyperspace</title>
  <link>https://mdlbear.dreamwidth.org/1639781.html</link>
  <description>&lt;p&gt;You may remember from &lt;a href=&quot;2018-10-08-adventures-in-hyperspace.md&quot;&gt;my previous post about
Hyperviewer&lt;/a&gt; that I’d been plagued by
a mysterious bug.  The &lt;em&gt;second&lt;/em&gt; time the program tried to make a simplex (the
N-dimensional version of a triangle (N=2) or tetrahedron (N=3), a whole batch
of “ghost edges” appeared and the program (quite understandably) blew up.  I
didn’t realize it until somewhat later, but there were ghost &lt;em&gt;vertices&lt;/em&gt; as
well, and that was somewhat more fundamental.  Basically, &lt;code&gt;nVertices&lt;/code&gt;, the
field that holds the number of vertices in the polytope, was wildly wrong.&lt;/p&gt;

&lt;h2&gt;Chasing ghosts&lt;/h2&gt;

&lt;p&gt;Eventually I narrowed things down to someplace around here, which is where
things stood at the end of the previous post.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-coderay&quot;&gt;&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n1&quot; name=&quot;n1&quot;&gt;1&lt;/a&gt;&lt;/span&gt;        let vertices = [];
&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n2&quot; name=&quot;n2&quot;&gt;2&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#777&quot;&gt;/* something goes massively wrong, right here. */&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n3&quot; name=&quot;n3&quot;&gt;3&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;for&lt;/span&gt; (let i = &lt;span style=&quot;color:#00D&quot;&gt;0&lt;/span&gt;; i &amp;lt; dim; ++i) {
&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n4&quot; name=&quot;n4&quot;&gt;4&lt;/a&gt;&lt;/span&gt;            vertices.push(&lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;new&lt;/span&gt; vector(dim).fill((j) =&amp;gt; i === j? &lt;span style=&quot;color:#60E&quot;&gt;1.0&lt;/span&gt; : &lt;span style=&quot;color:#00D&quot;&gt;0&lt;/span&gt;));
&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n5&quot; name=&quot;n5&quot;&gt;5&lt;/a&gt;&lt;/span&gt;        }
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I found this by throwing an error, with a big data dump, right in the middle
if &lt;code&gt;nVertices&lt;/code&gt; was wrong (it’s supposed to be &lt;code&gt;dim+&lt;/code&gt;), or if the length of the
list of vertices was different from &lt;code&gt;nVertices&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-coderay&quot;&gt;&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n1&quot; name=&quot;n1&quot;&gt;1&lt;/a&gt;&lt;/span&gt;        let vertices = [];
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n2&quot; name=&quot;n2&quot;&gt;2&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#777&quot;&gt;/* something goes massively wrong, right here. */&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n3&quot; name=&quot;n3&quot;&gt;3&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nVertices !== (dim + &lt;span style=&quot;color:#00D&quot;&gt;1&lt;/span&gt;) || &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nEdges !== ((dim + &lt;span style=&quot;color:#00D&quot;&gt;1&lt;/span&gt;) * dim / &lt;span style=&quot;color:#00D&quot;&gt;2&lt;/span&gt;) ||
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n4&quot; name=&quot;n4&quot;&gt;4&lt;/a&gt;&lt;/span&gt;            &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.vertices.length !== &lt;span style=&quot;color:#00D&quot;&gt;0&lt;/span&gt; || &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.edges.length !== &lt;span style=&quot;color:#00D&quot;&gt;0&lt;/span&gt; ) {
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n5&quot; name=&quot;n5&quot;&gt;5&lt;/a&gt;&lt;/span&gt;            &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;new&lt;/span&gt; Error(&lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;nEdges = &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nEdges + &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; want &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +  ((dim + &lt;span style=&quot;color:#00D&quot;&gt;1&lt;/span&gt;) * dim / &lt;span style=&quot;color:#00D&quot;&gt;2&lt;/span&gt;) +
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n6&quot; name=&quot;n6&quot;&gt;6&lt;/a&gt;&lt;/span&gt;                            &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;; nVertices = &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nVertices + &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; want &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + dim +
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n7&quot; name=&quot;n7&quot;&gt;7&lt;/a&gt;&lt;/span&gt;                            &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;; vertices.length = &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.vertices.length +
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n8&quot; name=&quot;n8&quot;&gt;8&lt;/a&gt;&lt;/span&gt;                            &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; at this point in the initialization, where dim = &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt; + dim +
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n9&quot; name=&quot;n9&quot;&gt;9&lt;/a&gt;&lt;/span&gt;                            &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; in &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.dimensions + &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;-D &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.name 
&lt;span class=&quot;line-numbers&quot;&gt;&lt;strong&gt;&lt;a href=&quot;#n10&quot; name=&quot;n10&quot;&gt;10&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;                           );
&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n11&quot; name=&quot;n11&quot;&gt;11&lt;/a&gt;&lt;/span&gt;        } 
&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n12&quot; name=&quot;n12&quot;&gt;12&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;for&lt;/span&gt; (let i = &lt;span style=&quot;color:#00D&quot;&gt;0&lt;/span&gt;; i &amp;lt; dim; ++i) {
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It appeared that &lt;code&gt;nVertices&lt;/code&gt; was wildly wrong at that point.  If I’d looked
carefully and thought about what &lt;code&gt;nVertices&lt;/code&gt; actually &lt;em&gt;was&lt;/em&gt;, I would probably
have found the bug at that point.  Or even earlier.  Instead, what clinched it
was this:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-coderay&quot;&gt;&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n1&quot; name=&quot;n1&quot;&gt;1&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.vertices = vertices;
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n2&quot; name=&quot;n2&quot;&gt;2&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nVertices = vertices.length;  &lt;span style=&quot;color:#777&quot;&gt;// setting this to dim+1 FAILS:&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n3&quot; name=&quot;n3&quot;&gt;3&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#777&quot;&gt;// in other words, this.nVertices is getting changed between these two statements!&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n4&quot; name=&quot;n4&quot;&gt;4&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.vertices.length !== &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nVertices || &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.edges.length !== &lt;span style=&quot;color:#00D&quot;&gt;0&lt;/span&gt;) {
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n5&quot; name=&quot;n5&quot;&gt;5&lt;/a&gt;&lt;/span&gt;            &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color:#080;font-weight:bold&quot;&gt;new&lt;/span&gt; Error(&lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;expect &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nVertices + &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; verts, have &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.vertices.length +
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n6&quot; name=&quot;n6&quot;&gt;6&lt;/a&gt;&lt;/span&gt;                            &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; in &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.dimensions + &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;-D &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&apos;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.name +
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n7&quot; name=&quot;n7&quot;&gt;7&lt;/a&gt;&lt;/span&gt;                            &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt;; want &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nEdges + &lt;span style=&quot;background-color:hsla(0,100%,50%,0.05)&quot;&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#D20&quot;&gt; edges into &lt;/span&gt;&lt;span style=&quot;color:#710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.edges.length
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n8&quot; name=&quot;n8&quot;&gt;8&lt;/a&gt;&lt;/span&gt;                           );
&lt;span class=&quot;line-numbers&quot;&gt; &lt;a href=&quot;#n9&quot; name=&quot;n9&quot;&gt;9&lt;/a&gt;&lt;/span&gt;        }
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The code that creates the list of vertices produces the right number of
vertices.  If I set &lt;code&gt;nVertices&lt;/code&gt; equal to the length of that list, everything
was fine.&lt;/p&gt;

&lt;p&gt;If instead I set&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-coderay&quot;&gt;&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;&lt;a href=&quot;#n1&quot; name=&quot;n1&quot;&gt;1&lt;/a&gt;&lt;/span&gt;        &lt;span style=&quot;color:#950&quot;&gt;this&lt;/span&gt;.nVertices = dim+&lt;span style=&quot;color:#00D&quot;&gt;1&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;it was wrong.  Huh?  For example, in four dimensions, the number of vertices
is supposed to be five, and that was the length of the list.  When is &lt;code&gt;4+1&lt;/code&gt;
not equal to &lt;code&gt;5&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;At this point a light bulb went off, because it was clear that &lt;code&gt;dim+1&lt;/code&gt; was
coming out equal to 41.  In three dimensions it was 31.  When is &lt;code&gt;4+1&lt;/code&gt; not
equal to 5?  When it’s actually &lt;code&gt;&quot;4&quot;+1&lt;/code&gt;.  In other words, &lt;code&gt;dim&lt;/code&gt; was a string.
JavaScript “helpfully” converts a string to a number when you do anything
arithmetical to it, like multiply it by something or raise it to a power.  But
&lt;code&gt;+&lt;/code&gt; isn’t always an arithmetic operation!  In JavaScript (and many other
languages) it’s also used for &lt;em&gt;string concatenation&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;What went wrong, and a rant&lt;/h2&gt;

&lt;p&gt;The problem was that, the &lt;em&gt;second&lt;/em&gt; time I tried to create a simplex, the
number of dimensions was coming from the user interface.  From an &lt;code&gt;&amp;lt;input&lt;/code&gt;
element in a web form.  And every value that you get from a web form is a
string.  HTML knows nothing about numbers, and it has no way to know what
you’re going to do with the input you get.&lt;/p&gt;

&lt;p&gt;So the fix was simple (and you can see it &lt;a href=&quot;https://github.com/ssavitzky/hyperviewer/commit/8bef087648d403a9ba432058fc4641e582b27250&quot;&gt;here on
GitHub&lt;/a&gt;:
convert the value from a string to a number right off before trying to use it
as a number of dimensions.  But… But…  But cubes and octohedrons were
&lt;em&gt;right!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s because the number of vertices in a N-cube is &lt;code&gt;2**N&lt;/code&gt;, and in an
N-orthoplex (octohedron in three dimensions) it’s &lt;code&gt;N*2&lt;/code&gt; (and multiplication is
always an arithmetic operator in JavaScript).  And it worked when I
was creating the simplex’s vertices because it was being compared against in a
&lt;code&gt;for&lt;/code&gt; loop.  And so on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If I’d been using a strongly-typed language, the compiler would have found
this two weeks ago.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are two main ways of dealing with data in a programming language, called
“strong typing” and “dynamic typing”.  In a strongly-typed language, both
values and variables (the boxes you put values into) have types (like “string”
or “integer”), and the types have to match.  You can’t put a string into a
variable with a type of integer.  Java is like that (mostly).&lt;/p&gt;

&lt;p&gt;Some people find this burdensome, and they prefer dynamically-typed languages
like JavaScript.  In JavaScript, &lt;em&gt;values&lt;/em&gt; have types, but variables don’t.
It’s called “dynamic” typing because a variable can hold anything, and its
type is that of the last thing that was put into it.&lt;/p&gt;

&lt;p&gt;You can write code very quickly in a language where you don’t have to declare
your variables and make sure they’re the right type for the kind of values you
want to put into them.  You can also shoot yourself in the foot much more
easily.&lt;/p&gt;

&lt;p&gt;There are a couple of strongly-typed variants on JavaScript, for example
CoffeeScript and TypeScript, and a type-checker called “Flow”.  I’m going to
try one of those next.&lt;/p&gt;

&lt;h2&gt;There was one more problem with simplexes&lt;/h2&gt;

&lt;p&gt;(simplices?) … but that was purely geometrical, and just because I was
trying to do all the geometry in my head instead of on paper, and wasn’t
thinking things through.&lt;/p&gt;

&lt;p&gt;If you’re in N dimensions, you can create an N-1 dimensional simplex by simply
connecting the points with coordinates like &lt;code&gt;[1,0,0]&lt;/code&gt;, &lt;code&gt;[0,1,0]&lt;/code&gt;, and
&lt;code&gt;[0,0,1]&lt;/code&gt; (in three dimensions – it’s pretty easy to see that that gives you
an equilateral triangle).  Moreover, all the vertices are on the unit sphere,
which is where we want them.  The last vertex is a bit of a problem.&lt;/p&gt;

&lt;p&gt;A fair amount of googling around (or DuckDuckGoing around, in my case) will
eventually turn up &lt;a href=&quot;mathoverflow.net/questions/38724/coordinates-of-vertices-of-regular-simplex&quot;&gt;this answer on
mathoverflow.net&lt;/a&gt;,
which says that in N dimensions, the last vertex has to be at &lt;code&gt;[x,...,x]&lt;/code&gt;
where &lt;code&gt;x=-1/(1+sqrt(1+N))&lt;/code&gt;.  Cool!  And it works.  Except that it’s not
centered – that last vertex is a lot closer to the origin than the others.
It took me longer than it should have to get this right, but the center of the
simplex is its “center of mass”, which is simply the average of all the
vertices.  So that’s at &lt;code&gt;y=(1+x)/(N+1)&lt;/code&gt; because there are N+1 vertices.  Now
we just have to subtract y from all the coordinates to shift it over until the
center is at the origin.&lt;/p&gt;

&lt;p&gt;Then of course we have to scale it so that all the vertices are back on the
unit sphere.  You can find the code &lt;a href=&quot;https://github.com/ssavitzky/hyperviewer/blob/794f406d8de7af4dd55ded5f21d46237bf76a5bd/src/polytopes.js#L128-L140&quot;&gt;here, on
GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Another fine post from &lt;a href=&quot;https://computer-curmudgeon.com&quot;&gt;The Computer Curmudgeon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1639781&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1639781.html</comments>
  <category>curmudgeon</category>
  <category>strong-typing</category>
  <category>hyperviewer</category>
  <category>programming</category>
  <category>4-d</category>
  <category>javascript</category>
  <category>math</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1638548.html</guid>
  <pubDate>Tue, 09 Oct 2018 04:01:55 GMT</pubDate>
  <title>Adventures in Hyperspace (and Javascript)</title>
  <link>https://mdlbear.dreamwidth.org/1638548.html</link>
  <description>&lt;p&gt; (This will be something of an experiment.  The original was written in
    markdown and posted on &lt;a href=&quot;https://computer-curmudgeon.com/2018/10/08/adventures-in-hyperspace.html&quot;&gt;Computer-Curmudgeon.com&lt;/a&gt;.  We&apos;ll see whether the process made a hash
    of it.  I may have to do some cleaning up.

&lt;p&gt;This post is about &lt;a href=&quot;http://github.com/ssavitzky/hyperviewer&quot;&gt;Hyperviewer&lt;/a&gt;, an update of a &lt;a href=&quot;https://github.com/ssavitzky/ncube/&quot;&gt;very old demo program of mine&lt;/a&gt; from 1988 that displays wireframe objects rotating in hyperspace. (Actually, anywhere between four and six dimensions.) Since this is 2018, I naturally decided to write it in JavaScript, using &lt;a href=&quot;https://infernojs.org/&quot;&gt;Inferno&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG&quot;&gt;SVG&lt;/a&gt;, and put it on the web. It was a learning experience, in more ways than one.&lt;/p&gt;

&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;I had been doing a little work with &lt;a href=&quot;https://reactjs.org/&quot;&gt;React&lt;/a&gt;, which is pretty good an very popular, and had recently read about &lt;a href=&quot;https://infernojs.org/&quot;&gt;Inferno&lt;/a&gt;, which is a lighter-weight, faster framework that&apos;s almost completely interchangeable with React. Sounded good, especially since I wanted high performance for something that&apos;s going to be doing thousands of floating-point matrix multiplies per second. (A hypercube in N dimensions has 2^N vertices, and a rotation matrix has N^2 entries -- do the math). (It turns out I really didn&apos;t have to worry -- Moore&apos;s Law over three decades gives a speedup by a factor of a million, give or take a few orders of magnitude, so even using an partially-interpreted language speed isn&apos;t a problem. Perhaps I&apos;m showing my age.)&lt;/p&gt;
&lt;p&gt;To keep things simple -- and make it possible to eventually save pictures -- I decided to use SVG: the web standard for &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG&quot;&gt;Scalable Vector Graphics&lt;/a&gt;, rather than trying to draw them out using an HTML5 &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API&quot;&gt;Canvas&lt;/a&gt; tag. It&apos;s a perfect match for something that&apos;s nothing but a bunch of vectors. SVG is XML-based, and you can simply drop it into the middle of an HTML page. SVG is also &lt;em&gt;really&lt;/em&gt; easy to generate using the new JSX format, which is basically XML tags embedded in a JavaScript file.&lt;/p&gt;
&lt;p&gt;Modern JavaScript uses a program called a &amp;quot;transpiler&amp;quot; -- the most common one is &lt;a href=&quot;https://babeljs.io/&quot;&gt;Babel&lt;/a&gt; -- that compiles shiny new JavaScript constructs (and even some new languages like TypeScript and CoffeeScript, which I want to learn soon) into the kind of plain old JavaScript that almost any browser can understand. (There are still some people using Microsoft Exploiter from the turn of the &lt;del&gt;century&lt;/del&gt; &lt;em&gt;millennium&lt;/em&gt;; if you&apos;re reading this blog it&apos;s safe for me to assume that you aren&apos;t one of them.)&lt;/p&gt;
&lt;p&gt;Anyway, let&apos;s get started:&lt;/p&gt;
&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://mdlbear.dreamwidth.org/1638548.html#cutid1&quot;&gt;cut tag added to protect your sanity&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;
&lt;p&gt; (Not too bad of a formatting job, though of course the color didn&apos;t come through.  Cut tag added because it&apos;s over 2000 words.)




&lt;p&gt; &lt;em&gt;Another fine post from
    &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer Curmudgeon&lt;/a&gt;.
&lt;br /&gt; Cross-posted on &lt;a href=&quot;https://computer-curmudgeon.com/2018/10/08/adventures-in-hyperspace.html&quot;&gt;computer-curmudgeon.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1638548&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1638548.html</comments>
  <category>development</category>
  <category>programming</category>
  <category>hyperviewer</category>
  <category>math</category>
  <category>javascript</category>
  <category>4-d</category>
  <category>curmudgeon</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1631872.html</guid>
  <pubDate>Fri, 27 Jul 2018 00:46:22 GMT</pubDate>
  <title>Scripting Languages</title>
  <link>https://mdlbear.dreamwidth.org/1631872.html</link>
  <description>&lt;p&gt; Today in my continuing series on programming languages I&apos;m going to talk
    about &quot;scripting languages&quot;.  &quot;Scripting&quot; is a rather fuzzy category,
    because unlike the kinds of languages we&apos;ve discussed before, scripting
    languages are really distinguished by how they are &lt;em&gt;used&lt;/em&gt;, and
    they&apos;re used in two very different ways.  It&apos;s also confusing because most
    scripting languages are interpreted, and people tend to use &quot;scripting&quot;
    when they should be using &quot;interpreted&quot;.  In my opinion it&apos;s more correct
    to say that a language is &lt;em&gt;being used as&lt;/em&gt; a scripting language,
    rather than to say that it &lt;em&gt;is&lt;/em&gt; a scripting language.  As we&apos;ll
    see, this is particularly true when the language is being used to
    customize some application.

&lt;p&gt; But first, let&apos;s define &lt;cite&gt;scripts.&lt;/cite&gt; A script is basically a
    sequence of &lt;em&gt;commands&lt;/em&gt; that a user could type at a terminal[1] --
    often called &quot;the command line&quot; -- that have been put together in a file
    so that they can be run automatically.  The script then becomes a
    new command.  In Linux, and before that Unix, the program that interprets
    user commands is called a &quot;shell&quot;, possibly because it&apos;s the visible outer
    layer of the operating system.  The quintessential script is a &lt;cite&gt;shell
    script&lt;/cite&gt;.  We&apos;ll dive into the details later.

&lt;blockquote style=&quot;font-size:small&quot;&gt;
[1] okay, a terminal &lt;em&gt;emulator.&lt;/em&gt;  Hardly anyone uses physical terminals
anymore.  Or remembers that the &quot;tty&quot; in &lt;code&gt;/dev/tty&lt;/code&gt; stands for
&quot;teletype&quot;&apos;.
&lt;/blockquote&gt;

&lt;p&gt; The second kind of scripting language is used to implement commands inside
    some interactive program that &lt;em&gt;isn&apos;t&lt;/em&gt; a shell.  (These languages
    are also called &lt;cite&gt;extension&lt;/cite&gt; languages, because they&apos;re
    extending the capabilities of their host program, or sometimes
    &lt;cite&gt;configuration&lt;/cite&gt; languages.)  Extension languages generally look
    nothing at all like something you&apos;d type into a shell -- they&apos;re really
    just programming languages, and often are just the programming language
    the application was written in.  The commands of an interactive program
    like a text editor or graphics editor tend to be things like single
    keystrokes and mouse gestures, and in most cases you wouldn&apos;t want to --
    or even be able to -- write programs with them.  I&apos;ll use &quot;extension
    languages&quot; for languages used in this way.  There&apos;s some overlap in
    between, and I&apos;ll talk about that later.

&lt;h3&gt;Shell scripting languages&lt;/h3&gt;

&lt;p&gt; Before there was Unix, there were mainframes.  At first, you would punch
    out decks of Hollerith cards, hand them to the computer operator, and they
    would (eventually) put it in the reader and push the start button, and you
    would come back an hour or so later and pick up your deck with a pile of
    listings from the printer.

&lt;p&gt; Computers were &lt;em&gt;expensive&lt;/em&gt; in those days, so to save time the
    operator would pile a big batch of card decks on top of one another with
    a couple of &quot;job control&quot; cards in between to separate the jobs.  Job
    control languages were really the first scripting languages.  (And the old
    terminology lingers on, as such things do, in the &quot;.bat&quot; extension of
    MS/DOS (later Windows) &quot;batch files&quot;.  Which are shell scripts.)

&lt;p&gt; By far the most sophisticated job control language ran on the Burroughs
    5000 and 6000 series computers, which were designed to run Algol very
    efficiently.  (So efficiently that they used Algol as what amounted to
    their assembly language!  Programs in other languages, including Fortran
    and Cobol, were compiled by first translating them into Algol.)  The job
    control language was a somewhat extended version of Algol in which some
    variables had files as their values, and programs were simply
    subroutines.  Don&apos;t let anyone tell you that all scripting languages are
    interpreted.

&lt;p&gt; Side note:  the Burroughs machines&apos; operating system was called MCP, which
    stands for Master Control Program.  Movie fans may find that name familiar.

&lt;p&gt; Even DOS batch files had control-flow statements (conditionals and loops)
    and the ability to substitute variables into commands.  But these features
    were clumsy to use.  In contrast, the Unix shell written by Stephen Bourne
    at Bell Labs was &lt;em&gt;designed&lt;/em&gt; as a scripting language.  The syntax of
    the control structures was, in fact, derived from Algol 68, which
    introduced the &quot;if...fi&quot; and &quot;do...done&quot; syntax.

&lt;p&gt; Bourne&apos;s shell was called &lt;code&gt;sh&lt;/code&gt; in Unix&apos;s characteristically
    terse style.  The version of Unix developed at Berkeley, (BSD, for
    Berkeley System Distribution -- I&apos;ll talk about the history of operating
    systems some time) had a shell called the C shell, &lt;code&gt;csh&lt;/code&gt;, which
    had a syntax derived from the C programming language.  That immediately
    gave rise to the popular tongue-twister &quot;she sells cshs by the cshore&quot;.

&lt;p&gt; The GNU (GNU&apos;s Not Unix) project, started by Richard Stallman with the
    goal of producing a completely free replacement for Unix, naturally had
    its own rewrite of the Bourne Shell called &lt;code&gt;bash&lt;/code&gt; -- the Bourne
    Again Shell.  It&apos;s a considerable improvement over the original, pulling
    in features from &lt;code&gt;csh&lt;/code&gt; and some other shell variants.

&lt;p&gt; Let&apos;s look at shell scripting a little more closely.  The basic statement
    is a command -- the name of a program followed by its arguments, just as
    you would type it on the command line.  If the command isn&apos;t one of the
    few built-in ones, the shell then looks for a file that matches the name
    of the command, and runs it.  The program eventually produces some output,
    and exits with a result code that indicates either success or failure.

&lt;p&gt; There are a few really brilliant things going on here.
&lt;ul&gt;
  &lt;li&gt; Each program gets run in a separate process.  Unix was originally a
       &lt;cite&gt;time-sharing&lt;/cite&gt; operating system, meaning that many people
       could use the computer at the same time, each typing at their own
       terminal, and the OS would run all their commands at once, a little at
       a time.
  &lt;li&gt; That means that you can pipe the output of one command into the input
       of another.  That&apos;s called a &quot;pipeline&quot;; the commands are separated by
       vertical bars, like | this, so the &apos;|&apos; character is often called &quot;pipe&quot;
       in other contexts.  It&apos;s a lot shorter than saying &quot;vertical bar&quot;.
  &lt;li&gt; You can &quot;redirect&quot; the output of a command into a file.  There&apos;s even a
       &quot;pipe fitting&quot; command called &lt;code&gt;tee&lt;/code&gt; that does both:  copies
       its input into a file, and also passes it along to the next command in
       the pipeline.
  &lt;li&gt; The shell uses the command&apos;s result code for control -- there&apos;s a
       program called &lt;code&gt;true&lt;/code&gt; that does nothing but immediately
       returns success, and another called &lt;code&gt;false&lt;/code&gt; that immediately
       fails.  There&apos;s another one, &lt;code&gt;test&lt;/code&gt;, which can perform
       various tests, for example to see whether two strings are equal, or a
       file is writable.  There&apos;s an alias for it:  &lt;code&gt;[&lt;/code&gt;.  Unix
       allows all sorts of characters in filenames.  Anyway, you can say
       things like &lt;code&gt;if&amp;nbsp;[&amp;nbsp;-w&amp;nbsp;$f&amp;nbsp;];&amp;nbsp;then...&lt;/code&gt;
  &lt;li&gt; You can also use a command&apos;s output as part of another command line, or
       put it into a variable.  &lt;code&gt;today=`date`&lt;/code&gt; takes the result of
       running the &lt;code&gt;date&lt;/code&gt; program and puts it in a variable called
       &lt;code&gt;today&lt;/code&gt;.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt; This is basically functional programming, with programs as functions and
    files as variables.  (Of course, you can define variables and functions in
    the shell as well.)  In case you were wondering whether Bash is a &quot;real&quot;
    programming language, take a look at &lt;a href=&quot;https://github.com/mrstegeman/nanoblogger-mod&quot;&gt;nanoblogger&lt;/a&gt; and
    &lt;a href=&quot;https://abcde.einval.com/wiki/&quot;&gt;Abcde&lt;/a&gt; (A Better CD Encoder).

&lt;p&gt; Sometime later in this series I&apos;ll devote a whole post to an introduction
    to shell scripting.  For now, I&apos;ll just show you a couple of my favorite
    one-liners to give you a taste for it.  These are tiny but useful scripts
    that you might type off the top of your head.  Note that comments in shell
    -- almost all Unix scripting languages, as a matter of fact -- start with
    an octothorpe.  (I&apos;ll talk about octothorpe/sharp/hash/pound later, too.)

&lt;blockquote style=&quot;font-size:small&quot;&gt;&lt;pre&gt;# wait until nova (my household server) comes back up after a reboot
until ping -c1 nova; do sleep 10; done

# count my blog posts.  wc counts words, lines, and/or characters.
find $HOME/.ljarchive -type f -print | wc -l

# find all posts that were published in January.
# grep prints lines in its input that match a pattern.
find $HOME/.ljarchive -type f -print | grep /01/ | sort&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h3&gt;Other scripting languages&lt;/h3&gt;

&lt;p&gt; As you can see, shell scripts tend to be a bit cryptic.  That&apos;s partly
    because shells are also meant to have commands typed at them directly, so
    brevity is often favored over clarity.  It&apos;s also because all of the
    operations that work on files are &lt;em&gt;programs&lt;/em&gt; in their own right;
    they often have dozens of options and were written at different times by
    different people.  The &lt;code&gt;find&lt;/code&gt; program is often cited as a good
    (or bad) example of this -- it has a very different set of options from
    any other program, because you&apos;re trying to express a rather complicated
    combination of tests on its command line.

&lt;p&gt; Some things are just too complicated to express on a single line, at least
    with anything resembling readability,  so many other programs besides
    shells are designed to run scripts.  Some of the first of these in Unix
    were &lt;code&gt;sed&lt;/code&gt;, the &quot;stream editor&quot;, which applies text editing
    operations to its input, and &lt;code&gt;awk&lt;/code&gt;, which splits lines into
    &quot;fields&quot; and lets you do database-like operations on them.  (Simpler
    programs that also split lines into fields include &lt;code&gt;sort&lt;/code&gt;,
    &lt;code&gt;uniq&lt;/code&gt;, and &lt;code&gt;join&lt;/code&gt;.)

&lt;blockquote style=&quot;font-size:small&quot;&gt;
    DOS and Windows look at the last three characters of a program&apos;s name
    (e.g., &quot;exe&quot; for &quot;executable&quot; machine language and &quot;bat&quot; for &quot;batch&quot;
    scripts) to determine what it contains and how to run it.  Unix, on the
    other hand, looks at the first few characters of the file itself.  In
    particular, if these are &quot;&lt;code&gt;#!&lt;/code&gt;&quot; followed by the name of a
    program (I&apos;m simplifying a little), the file is passed to that program to
    be run as a script.  The &quot;&lt;code&gt;#!&lt;/code&gt;&quot; combination is usually
    pronounced &quot;&lt;a href=&quot;https://en.wikipedia.org/wiki/Shebang_(Unix)&quot;&gt;shebang&lt;/a&gt;&quot;.  This
    accounts for the popularity of &quot;&lt;code&gt;#&lt;/code&gt;&quot; to mark comments -- lines
    that are meant to be ignored -- in most scripting languages.
&lt;/blockquote&gt;

&lt;p&gt; The scripting programs we&apos;ve seen so far -- &lt;code&gt;sh&lt;/code&gt;,
    &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, and some others -- are all designed to
    do one kind of thing.  Shells mostly just run commands, assign variables,
    and substitute variables into commands, and rely on other programs like
    &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; to do most other things.  Wouldn&apos;t
    it be nice if one could combine all these functions into one program, and
    give it a better language to write programs in.  The first of these that
    really took off was Larry Wall&apos;s &lt;a href=&quot;https://en.wikipedia.org/wiki/Perl&quot;&gt;Perl&lt;/a&gt;.  Like the others it
    allows you to put simple commands on the command line -- with &lt;em&gt;exactly
    the same syntax as grep and awk&lt;/em&gt;.

&lt;p&gt; Perl&apos;s operations for searching and substituting text look just like the
    ones in &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt;.  It has associative arrays
    (basically lookup tables) just like the ones in &lt;code&gt;awk&lt;/code&gt;.  It can
    run programs and get their results exactly the way &lt;code&gt;sh&lt;/code&gt; does,
    by enclosing them in backtick characters (`...` -- originally meant to be
    used as left single quotes), and it can easily read lines out of files,
    mess with them, and write them out.  It has has objects, methods, and
    (more or less) first-class functions.  And just like &lt;code&gt;find&lt;/code&gt; and
    the Unix command line, it has a well-earned reputation for scripts that
    are obscure and hard to read.

&lt;p&gt; You&apos;ve probably heard &lt;a href=&quot;https://en.wikipedia.org/wiki/Python_(programming_language)&quot;&gt;Python&lt;/a&gt; mentioned.  It was designed by Guido van Rossum in an attempt
    to be a better scripting language Perl, with an emphasis on making
    programs more readable, easier to write, and easier to maintain.  He
    succeeded.  At this point Python has mostly replaced Perl as the most
    popular scripting language, in addition to being a good first language for
    learning programming.  (Which is the &lt;em&gt;best&lt;/em&gt; language for learning
    is a subject guaranteed to invoke strong opinions and heated discussions;
    I&apos;ll avoid it for now.)  I avoided Python for many years, but I&apos;m finally
    learning it and finding it much better than I expected.

&lt;h3&gt;Extension languages&lt;/h3&gt;

&lt;p&gt; The other major kind of scripting is done to extend a program that
    &lt;em&gt;isn&apos;t&lt;/em&gt; a shell.  In most cases this will be an interactive program
    like an editor, but it doesn&apos;t have to be.  Extensions of this sort may 
    also be called &quot;plugins&quot;.

&lt;p&gt; Extension languages are usually small, simple, and interpreted, because
    nobody wants their text editor (for example) to include something as large
    and complex as a compiler when its main purpose is defining keyboard
    shortcuts.  There&apos;s an exception to this -- sometimes when a program is
    written in a compiled language, the same language may be used for
    extensions.  In that case the extensions have to be compiled in, which is
    usually inconvenient, but they can be particularly powerful.  I&apos;ve already
    written about one such case -- the &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/xmonad&quot;&gt;Xmonad&lt;/a&gt; window
    manager, which is written and configured in Haskell. 

&lt;p&gt; Everyone these days has at least heard of &lt;a href=&quot;https://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt;, which is
    the scripting language used in web pages.  Like most scripting languages,
    JavaScript has escaped from its enclosure in the browser and run wild, to
    the point where text editors, whole web browsers, web &lt;em&gt;servers&lt;/em&gt;,
    and so on are built in it.

&lt;p&gt; Other popular extension languages include various kinds of Lisp, &lt;a href=&quot;https://en.wikipedia.org/wiki/Tcl&quot;&gt;Tcl&lt;/a&gt;, and
    &lt;a href=&quot;https://en.wikipedia.org/wiki/Lua_(programming_language)&quot;&gt;Lua&lt;/a&gt;.  Lua and Tcl were explicitly designed to be embedded in
    programs.  Lua is particularly popular in games, although it has recently
    turned up in other places, including the TeX typesetting system.

&lt;p&gt; Lisp is an interesting case -- probably its earliest use as an extension
    language was in the Emacs text editor, which is almost entirely written in
    it.  (To the point where many people say that it&apos;s a very good Lisp
    interpretor, but it needs a better text editor.  I&apos;m not one of them:  I&apos;m
    passionately fond of Emacs, and I&apos;ll write about it at greater length
    later on.)  Because of its radically simple structure, Lisp is
    particularly easy to write an interpretor for.  Emacs isn&apos;t the only
    example; there are Lisp variants in the Audacity audio workstation and the
    Autodesk CAD program.  I used the one in Audacity for the sound effects in
    my computer/horror crossover song &lt;a href=&quot;https://steve.savitzky.net/Songs/vampire/&quot;&gt;&quot;Vampire Megabyte&quot;&lt;/a&gt;.

&lt;p&gt; Emacs, Atom (a text editor written in JavaScript), and Xmonad are good
    examples of interactive programs where the same language is used for
    (most, if not all, of) the implementation as well as for the configuration
    files and the extensions.  The boundaries can get very fuzzy in cases like
    that; as a Mandelbear I find that particularly appealing.

&lt;p&gt; &lt;em&gt;Another fine post from
    &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer Curmudgeon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1631872&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1631872.html</comments>
  <category>languages</category>
  <category>programming</category>
  <category>computers</category>
  <category>scripting</category>
  <category>curmudgeon</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>9</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1631514.html</guid>
  <pubDate>Mon, 23 Jul 2018 04:25:15 GMT</pubDate>
  <title>Blog posting software planning</title>
  <link>https://mdlbear.dreamwidth.org/1631514.html</link>
  <description>&lt;p&gt; In &lt;a href=&quot;https://mdlbear.dreamwidth.org/1631371.html?thread=4766603#cmt4766603&quot;&gt;comments on &quot;Done Since 2018-07-15&quot;&lt;/a&gt; we started having a discussion of
    mirroring and cross-posting DW blog entries, and in particular what my
    plans are for implementing personal blog sites that mirror all or some of
    a -- &lt;em&gt;this&lt;/em&gt; -- Dreamwidth journal.

&lt;p&gt; Non-techie readers might conceivably want to skip this post.

&lt;h3&gt;Where I am now:&lt;/h3&gt;

&lt;p&gt; Right now, my blog posting process is, well, let&apos;s just say
    &lt;em&gt;idiosyncratic&lt;/em&gt;.  Up until sometime late last year, I was posting
    using an Emacs major mode called &lt;code&gt;lj-update-mode&lt;/code&gt;; it was
    pretty good.  It had only two significant problems:
&lt;ol&gt;
  &lt;li&gt; It could only create one post at a time, and there was no good way to
       save a draft and come back to it later.  I could live with that.
  &lt;li&gt; It stopped working when DW switched to all HTTPS.  It was using an
       obsolete http library, and noone was maintaining either of them.
&lt;/li&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt; My current system is much better.
&lt;ol&gt;
  &lt;li&gt; I run a command, either &lt;code&gt;make&amp;nbsp;draft&lt;/code&gt; or, if I&apos;m pretty
       sure I&apos;m going to post immediately, &lt;code&gt;make&amp;nbsp;entry&lt;/code&gt;.  I
       pass the filename, without the yyyy/mm/dd prefix, along with an
       optional title.  If I don&apos;t pass the title I can add it later.  The
       draft gets checked in with git; I can find out when I started by using
       &lt;code&gt;git&amp;nbsp;log&lt;/code&gt;. 
  &lt;li&gt; I edit the draft.  It can sit around for days or months; doesn&apos;t
       matter.  It&apos; an ordinary html file except that it has an email-like
       header with the metadata in it.
  &lt;li&gt; When I&apos;m done, I &lt;code&gt;make&amp;nbsp;post&lt;/code&gt;.  Done.  If I&apos;m posting a
       draft I have to pass the filename again to tell it &lt;em&gt;which&lt;/em&gt;
       draft; &lt;code&gt;make&amp;nbsp;entry&lt;/code&gt; makes a symlink to the entry, which
       is already in a file called
       &lt;code&gt;yyyy/mm/dd-&lt;em&gt;filename&lt;/em&gt;.html&lt;/code&gt;.  It gets posted,
       and committed in git with a suitable commit message.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt; You can see the code in &lt;a href=&quot;https://github.com/ssavitzky/MakeStuff/tree/master/blogging&quot;&gt;MakeStuff/blogging&lt;/a&gt; on GitHub.  It depends on a Python client called
    &lt;a href=&quot;https://github.com/ssavitzky/charm&quot;&gt;&lt;code&gt;charm&lt;/code&gt;&lt;/a&gt;,
    which I forked to add the Location: header and some sane defaults like not
    auto-formatting.  Charm is mostly useless -- it does almost everything
    using a terminal-based text editor.  Really?  But it does have a
    &quot;quick-post&quot; mode that takes metadata on the command line, and a &quot;sync&quot;
    mode that you can use to sync your journal with an archive.  Posts in the
    archive are almost, but not quite, in the same format as the MakeStuff
    archive; the main difference is that the filenames look like
    &lt;code&gt;yyyy/mm/dd_HHMM&lt;/code&gt;.  Close, but not quite there.

&lt;p&gt; There&apos;s another advantage that isn&apos;t apparent in the code: you can add
    custom make targets that set up your draft using a template.  For example,
    my &quot;Done since ...&quot; posts are started with &lt;code&gt;make&amp;nbsp;done&lt;/code&gt;,
    and my &quot;&lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;Computer
    Curmudgeon&lt;/a&gt;&quot; posts are started with &lt;code&gt;make&amp;nbsp;curmudgeon&lt;/code&gt;.
    There are other shortcuts for River and S4S posts.  I also have multiple
    directories for drafts, separated roughly by subject, but all posting into
    the same archive.

&lt;h3&gt;Where I want to go:&lt;/h3&gt;

&lt;p&gt; Here&apos;s what I want next:

&lt;ul&gt;
  &lt;li&gt; The ability to post in either HTML or markdown -- markdown has a great
       toolchain, including the ability to syntax-color your code blocks.
  &lt;li&gt; The ability to &lt;em&gt;edit&lt;/em&gt; posts by editing the archived post and
       uploading it.  Right now it&apos;s a real pain to keep them in sync.
  &lt;li&gt; A unified archive, with &lt;em&gt;actual URLs in the metadata&lt;/em&gt; rather
       than just the date and time in the filename.
  &lt;li&gt; The ability to put all or part of my blog on &lt;em&gt;different sites.&lt;/em&gt;
       I really want the computer-related posts to go on &lt;a href=&quot;https://stephen.savitzky.net/&quot;&gt;Stephen.Savitzky.net&lt;/a&gt; (usually
       shortened to S.S.net in my notes), and a complete mirror on &lt;a href=&quot;https://steve.savitzky.net/&quot;&gt;steve.savitzky.net&lt;/a&gt; (s.s.net).
  &lt;li&gt; Cross-links in both directions between my sites and DW.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;How to get there:&lt;/h3&gt;

&lt;p&gt; Here&apos;s a very brief sketch of what needs to be done.  It&apos;s only vaguely in
    sequence, and I&apos;ve undoubtedly left parts out.  But it&apos;s a start.

&lt;h4&gt;Posting, editing, and archiving&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt; Posting in HTML or markdown is a pretty easy one; I can do that just by
       modifying the makefiles and (probably) changing the final extension
       from &lt;code&gt;.html&lt;/code&gt; to &lt;code&gt;.posted&lt;/code&gt; so that make can apply
       its usual dependency-inference magic.
  &lt;li&gt; Editing and a unified archive will &lt;em&gt;both&lt;/em&gt; require a new
       command-line client.  There aren&apos;t any.  There &lt;em&gt;are&lt;/em&gt; libraries,
       in Ruby, Haskell, and Javascript, that I can wrap a program around.
       (The Python code in &lt;code&gt;charm&lt;/code&gt; doesn&apos;t look worth saving.)  I
       wanted to learn Ruby anyway.
  &lt;li&gt; The unified archive will also require a program that can go back in
       time and match up archived posts with the right URLs, reconcile the two
       file naming conventions, and remove the duplicates that are due to
       archiving posts both in &lt;code&gt;charm&lt;/code&gt; and &lt;code&gt;MakeStuff&lt;/code&gt;.
       Not too hard, and it only has to be done once.
  &lt;li&gt; It would be nice to be able to archive comments, too.  The old
       &lt;code&gt;ljbackup&lt;/code&gt; program can do it, so it&apos;s feasible.  It&apos;s in
       Perl, so it might be a good place to start.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;h4&gt;Mirror, mirror, on the server...&lt;/h4&gt;

&lt;p&gt; This is a separate section because it&apos;s mostly orthogonal to the posting,
    archiving, etc.  
&lt;ul&gt;
  &lt;li&gt; The only part of the posting section that really needs to be done first
       is the first one, changing the extension of archived posts to
       &lt;code&gt;.posted&lt;/code&gt;.  (That&apos;s because &lt;code&gt;make&lt;/code&gt; uses
       extensions to figure out what rules to apply to get from one to
       another.  Remind me to post about &lt;code&gt;make&lt;/code&gt; some time.)
  &lt;li&gt; The post archive may want to have its own git repository.
  &lt;li&gt; Templating and styling.  My websites are starting to show their age;
       there&apos;s nothing really wrong with a retro look, but they also aren&apos;t
       responsive (to different screen sizes -- that&apos;s important when most
       people are reading websites on their phones), or accessible
       (screen-reader friendly and navigable by keyboard; having different
       font sizes helps here, too).  Any respectable static site generator can
       do it -- you may remember &lt;a href=&quot;https://mdlbear.dreamwidth.org/1618191.html&quot;&gt;this post on The
       Joy of Static Sites&lt;/a&gt; -- but the way I&apos;m formatting my metadata will
       require some custom work.  Blosxom and nanoblogger are probably the
       closest, but they&apos;re ancient.  I probably ought to resist the
       temptation to roll my own.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt; Yeah.  Right.

&lt;p&gt; &lt;em&gt;Another fine post from
    &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer Curmudgeon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1631514&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1631514.html</comments>
  <category>projects</category>
  <category>curmudgeon</category>
  <category>blogging</category>
  <category>programming</category>
  <category>computers</category>
  <category>makestuff</category>
  <category>software</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1628698.html</guid>
  <pubDate>Fri, 06 Jul 2018 05:36:51 GMT</pubDate>
  <title>Languages: Imperative, Object-Oriented, and Functional</title>
  <link>https://mdlbear.dreamwidth.org/1628698.html</link>
  <description>&lt;blockquote style=&quot;white-space: pre-wrap;&quot;&gt;
Back when smalltalk was sports and the weather,
And an object was what you could see,
And we watched &quot;Captain Video&quot; in black-and-white,
Before there was color TV.
-- &lt;a href=&quot;https://steve.savitzky.net/Songs/lad/&quot;&gt;&quot;When I Was a Lad&quot;&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt; Even if you&apos;re not a programmer (and most of the people I expect to be
    reading this aren&apos;t) you&apos;ve probably heard one of your geek friends
    mentioning &quot;object-oriented&quot; programming.  You might even have heard them
    mention &quot;functional&quot; programming, and wondered how it differs from
    non-functional programming.  The computer curmudgeon can help you.

&lt;p&gt; If you &lt;em&gt;are&lt;/em&gt; a programmer, you probably know a lot of this.  You may
    find a few items of historical interest, and it might be useful explaining
    things to the non-programmers in your life.

&lt;h2&gt;Imperative languages&lt;/h2&gt;

&lt;p&gt; As you may recall from last month&apos;s post on &lt;a href=&quot;https://mdlbear.dreamwidth.org/1621179.html&quot;&gt;computer
    languages&lt;/a&gt;, the first programming languages were assembly languages --
    just sequences of things for the computer to do, one after another (with a
    few side-trips).  This kind of language is called &quot;imperative&quot;, because
    each statement is a command telling the computer what to do next:  &quot;load a
    into register 2!&quot; &quot;add register 2 to register 3!&quot; &quot;roll over!&quot;  &quot;sit!&quot;
    You get the idea.

&lt;p&gt; Most programmers use &quot;statement&quot; instead of &quot;command&quot; for these things
    even though the latter might be more correct from a grammatical point of
    view; a &quot;command&quot; is something one types at a terminal in order to run a
    program (which is &lt;em&gt;also&lt;/em&gt; called a &quot;command&quot;).

&lt;p&gt; Most of the earlier programming languages (with one notable exception that
    we&apos;ll get to later) were also imperative.  Fortran, Cobol, and Algol were
    the most prominent of these; most of today&apos;s languages descend
    more-or-less from Algol.  (By the way, the &lt;a href=&quot;http://www.softwarepreservation.org/projects/ALGOL/report/Algol60_report_CACM_1960_June.pdf&quot;&gt;Report on the Algorithmic Language Algol 60&lt;/a&gt; is something I always
    point to as an example of excellent technical writing.)

&lt;p&gt; Imperative languages make a distinction between statements, which
    &lt;em&gt;do&lt;/em&gt; things (like &quot;a := 2&quot;, which puts the number 2 into a variable
    called &quot;a&quot;), and &quot;expressions&quot;, which compute results.  Another way of
    saying that is that an expression has a &lt;em&gt;value&lt;/em&gt; (like 2+2, which
    has a value of 4), and a statement doesn&apos;t.  In earlier languages that
    value was always a number; later languages add things like lists of
    symbols and strings of characters enclosed in quotes.

&lt;p&gt; Algol and its descendents lend themselves to what&apos;s called &quot;Structured
    Programming&quot; -- control structures like conditionals (&quot;if this then {that}
    else {something-else}&quot;) and loops (for x in some-collection do
    {something}) let you build your program out of simple sections that nest
    together but always have a single entrance and exit.  Notice the braces
    around those sections.  Programming languages have different ways of
    grouping statements; braces and indentation are probably the most common,
    but some languages use &quot;if ... fi&quot; and &quot;do ... done&quot;.

&lt;p&gt; Languages also have ways of packaging up groups of statements so that they
    can be used in different places in the program.  These are called either
    &quot;subroutines&quot; or &quot;functions&quot;; if a language has both it means that a
    function returns a value (like &quot;sqrt(2)&quot;, which returns the square root of
    2) and a subroutine doesn&apos;t (like &quot;print(&apos;Hello world!&apos;)&quot;, which prints a
    familiar greeting.)  Subroutines are statements, and functions are
    expressions.  The expressions in parentheses are called either &quot;arguments&quot;
    or &quot;parameters&quot; -- I was bemused to find out recently that &lt;em&gt;verbs&lt;/em&gt;
    have arguments, too.  (A verb&apos;s arguments are the subject, and the direct
    and indirect objects.)

&lt;h2&gt;Object-oriented languages&lt;/h2&gt;

&lt;p&gt; As long as we&apos;re on the subject of objects, ...

&lt;p&gt; In the mid 1960s Ole-Johan Dahl and Kristen Nygaard, working at the
    University of Oslo, developed a language called &lt;a href=&quot;https://en.wikipedia.org/wiki/Simula&quot;&gt;Simula&lt;/a&gt;, designed for
    simulating objects and events in the real world.  Objects are things like
    cars, houses, people, and cats, and Simula introduced &lt;em&gt;software&lt;/em&gt;
    objects to represent them.  Objects have &quot;attributes&quot;:  my car is blue, my
    cats are both female, my wife has purple hair.  Some of these attributes
    are objects in their own right:  a car has wheels, a cat has four legs and
    a person has two legs and two arms.  Some of these are variables:
    sometimes my driveway has a car in it, sometimes it doesn&apos;t, and sometimes
    it has two or three.

&lt;p&gt; What this means is that objects have &lt;em&gt;state.&lt;/em&gt;  A car&apos;s speed and
    direction vary all the time, as does the position of a cat&apos;s tail.  An
    object is a natural way to bundle up a collection of state variables.

&lt;p&gt; An object also can &lt;em&gt;do things&lt;/em&gt;.  In a program, objects rarely do
    things on their own, some other object &lt;em&gt;tells&lt;/em&gt; them what to do.
    This is a lot like sending the object a message.  &quot;Hey, car -- turn left!&quot;
    &quot;Hey, cat!  What color are your eyes?&quot;  Software objects don&apos;t usually
    have any of their state on the outside where other parts of the program
    can see it; they have to be asked politely.  That means that the object
    might be &lt;em&gt;computing&lt;/em&gt; something that looks to the outside like a
    simple state variable -- a car computes its speed from the diameter of its
    tires and how fast its wheels are turning.  All these things are hidden
    from the rest of the program.

&lt;p&gt; An object has to have a &lt;em&gt;method&lt;/em&gt; for handling any message thrown at
    it, so the documentation of most languages refers to &quot;calling a method&quot;
    rather than &quot;sending a message&quot;.  It&apos;s the same thing in most cases.  As
    seen from the outside, calling a method is just like calling a function or
    subroutine, except that there&apos;s an extra argument that represents the
    object.  If you think of the message as a command -- an imperative
    sentence -- it has an implied subject, which is the object you&apos;re talking
    to.  &lt;em&gt;Inside&lt;/em&gt; the little program that handles the method, the
    object is represented by a name that is usually either &quot;self&quot; or &quot;this&quot;,
    depending on the language.

&lt;p&gt; One natural thing to do with objects is to classify them, so objects have
    &quot;classes&quot;, and classes tend to be arranged in hierarchies.  My cats are
    cats -- we say that Ticia and Desti are &lt;em&gt;instances&lt;/em&gt; of the class
    &quot;Cat&quot;.  All cats are animals, so Cat is a &lt;em&gt;subclass&lt;/em&gt; of Animal, as
    are Dog and Person.  (In programming languages, classes tend to have their
    names capitalized.  Variables (like &quot;x&quot; or &quot;cat&quot;) almost always start with
    a lowercase letter.  Constants (like &quot;Pi&quot;, &quot;True&quot;, and &quot;Ticia&quot;) can go
    either way.)

&lt;p&gt; An object&apos;s class contains everything the computer needs to determine the
    behavior of its instances:  a list of the state variables, a list of the
    methods it can handle, and so on.  Now we get to the fun part.

&lt;p&gt; Simula was just objects and methods tacked on to a &quot;traditional&quot;
    imperative language -- Algol in that case.  Most other &quot;object-oriented&quot;
    languages work the same way -- C++ is just objects tacked on to C; Python
    and Perl had objects from the beginning or close to it, but they still
    include a lot of things -- numbers, strings, arrays, and so on, that
    aren&apos;t objects or (like strings in Java) are pretending to be objects.  It
    doesn&apos;t have to be that complicated.

&lt;p&gt; Shortly after Simula was released, Alan Kay at Xerox PARC realized that
    you could design a programming language where &lt;em&gt;everything&lt;/em&gt; was an
    object.  The result was Smalltalk, and it&apos;s still the best example of a
    &lt;em&gt;pure&lt;/em&gt; object-oriented language.  (It inspired C++ and Java, and
    indeed almost all existing OO languages, but very few of them went all the
    way.  Ruby comes closest of the languages I&apos;m familiar with.)  Smalltalk
    is &lt;del&gt;turtles&lt;/del&gt; &lt;ins&gt;objects&lt;/ins&gt; all the way down.

&lt;p&gt; In Smalltalk numbers are objects -- you can add new methods to them, or
    redefine existing methods.  (Your program will eventually stop working if
    you redefine addition so that 2+2 is 5, but it will keep going for a
    surprisingly long time.)  So are booleans.  True and False are instances
    of different subclasses of Boolean, and they behave differently when given
    messages like &lt;code&gt;ifTrue:&lt;/code&gt; or &lt;code&gt;ifFalse:&lt;/code&gt;.  (I&apos;m not
    going to go into the details here; Smalltalk warrants an article all by
    itself).  Loops are methods, too.  The trickiest bit, though, is that
    &lt;em&gt;classes&lt;/em&gt; are objects.  A class is just an instance of Metaclass,
    and Metaclass is an instance of &lt;em&gt;itself.&lt;/em&gt;

&lt;p&gt; Someone trying to implement Smalltalk has to cheat in a couple of places
    -- the Metaclass weirdness is one of them -- but they have to hide their
    tracks and not get caught.

&lt;h2&gt;Functional languages&lt;/h2&gt;

&lt;p&gt; Smalltalk, for all its object orientation, is still an imperative language
    underneath.  A program is still a sequence of statements, even if they&apos;re
    all wrapped up in methods.  Objects have state -- lots of it; they&apos;re just
    a good way of organizing it.  Alan Kay once remarked that programming in
    Smalltalk was a lot like training a collection of animals to perform
    tricks together.  Sometimes it&apos;s more like herding cats.

&lt;p&gt; But it turns out that you don&apos;t need statements -- or even state -- at
    all!  All you need is functions.

&lt;p&gt; About the same time Alan Turing was inventing the &lt;a href=&quot;https://en.wikipedia.org/wiki/Turing_machine&quot;&gt;Turing Machine&lt;/a&gt;,
    which is basically a computer stripped-down and simplified to something
    that will just barely work, Alonzo Church was developing something he
    called the &lt;a href=&quot;https://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;Lambda
    Calculus&lt;/a&gt;, which did something similar to the mathematical concept of
    &lt;em&gt;functions&lt;/em&gt;.

&lt;p&gt; A mathematical function takes a set of inputs, and produces an output.
    The key thing about it is that a given set of inputs will always produce
    exactly the same output.  It&apos;s like a meat grinder -- put in beef, and you
    get ground beef.  Put in pork, and you get ground pork.  &lt;em&gt;A function
    has no state, and no side-effects.&lt;/em&gt;  State would be like a secret
    compartment in the meat grinder, so that you get a little chicken mixed in
    with your ground beef, and beef in your ground pork.  Ugh.  A side effect
    would be like a hole in the side that lets a little of the ground meat
    escape.

&lt;p&gt; Objects are all about state and side effects.  You can call a method like
    &quot;turn left&quot; on a car (in most languages that would look like
    &lt;code&gt;car.turn(left)&lt;/code&gt;) and as a side effect it will change the car&apos;s
    direction state to something 90 degrees counterclockwise from where it
    was.  That makes it hard to reason about what&apos;s going to happen when you
    call a particular method.  It&apos;s even harder with cats.

&lt;p&gt; Anyway, in lambda calculus, functions are things that you can pass around,
    pass to other functions, and return from functions.  They&apos;re &lt;em&gt;first
    class&lt;/em&gt; values, just like numbers, strings, and lists.  It turns out
    that you can use functions to compute anything that you can compute with a
    Turing machine.

&lt;p&gt; Lambda calculus gets its name from the way you represent functions:  To
    define a function that squares a number, for example, we say something
    like: 

&lt;blockquote&gt;&lt;pre&gt;square = &amp;lambda; x: x*x
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt; Now, this looks suspiciously like assigning a value to a variable, and
    that&apos;s exactly what it&apos;s doing.  If you like, you can even think of
    &amp;lambda; as a funny kind of function that takes a list of symbols and
    turns it into a function.  You find the value of an expression like
    &lt;code&gt;square(3)&lt;/code&gt; by plugging the value 3 into the function&apos;s
    definition in place of &lt;code&gt;x&lt;/code&gt;.  So,

&lt;blockquote&gt;&lt;pre&gt;square(3)
  &amp;rightarrow; (&amp;lambda; x: x*x)(3)
  &amp;rightarrow; 3*3
  &amp;rightarrow; 9
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;small&gt;
&lt;p&gt; Most functional languages don&apos;t allow you to redefine a name once you&apos;ve
    bound it to a value; if you have a function like &lt;code&gt;square&lt;/code&gt; it
    wouldn&apos;t make much sense to redefine it in another part of the program as
    &lt;code&gt;x*x*x&lt;/code&gt;.  This is vary different from imperative languages,
    where variables represent state and vary all over the place.  (Names that
    represent the arguments of functions are only defined inside any one call
    to the function, so &lt;code&gt;x&lt;/code&gt; can have different values in
    &lt;code&gt;square(2)&lt;/code&gt; and &lt;code&gt;square(3)&lt;/code&gt; and nobody gets
    confused.)
&lt;/p&gt;&lt;/small&gt;&lt;/blockquote&gt;

&lt;p&gt; Lambda calculus lends itself to &lt;em&gt;recursive&lt;/em&gt; functions -- functions
    that call themselves -- and recursion is particularly useful when you&apos;re
    dealing with lists.  You do something to the first thing on the list, and
    then combine that with the result of doing the same thing to the rest of
    the list.Suppose you have a list of numbers, like &lt;code&gt;(6 2 8 3)&lt;/code&gt;.
    If you want another list that contains the squares of those numbers, you
    can use a function called &lt;code&gt;map&lt;/code&gt; that takes two arguments: a
    function and a list.  It returns the result of applying the function to
    each element of the list.  So

&lt;blockquote&gt;&lt;pre&gt;map(square, (6, 2, 8, 3))
 &amp;rightarrow; (36, 4, 64, 9)
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt; It&apos;s pretty easy to define &lt;code&gt;map&lt;/code&gt;, too.  It&apos;s just
&lt;blockquote&gt;&lt;pre&gt;
map = &amp;lambda; (f, l):
	if isEmpty(l)
           then l
	   else cons(f(first(l)), map(f, rest(l)))
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;small&gt;
&lt;p&gt; The &lt;code&gt;cons&lt;/code&gt; function constructs a new list that consists of its
    first argument, which can be anything, tacked onto the front of its second
    argument, which is a list.  Using &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt;
    as the names of the functions that get the first item in a list, and the
    remainder of the list after the first item, is pretty common tese days.
    &lt;a href=&quot;https://en.wikipedia.org/wiki/CAR_and_CDR&quot;&gt;Historically&lt;/a&gt;, the
    function that returns the first item in a list is called &lt;code&gt;car&lt;/code&gt;,
    and the function that returns the rest of the list is called
    &lt;code&gt;cdr&lt;/code&gt; (pronounced sort of like &quot;could&apos;r&quot;).

&lt;p&gt; I know, the classic introduction to recursive functions is factorial.
    Lists are more interesting.  Besides, I couldn&apos;t resist an excuse for
    mentioning &quot;car&quot;.  We&apos;ll see &quot;cat&quot; in a future post when I discuss
    scripting languages.
&lt;/p&gt;&lt;/p&gt;&lt;/small&gt;&lt;/blockquote&gt;

&lt;p&gt; We call &lt;code&gt;map&lt;/code&gt; a &quot;higher-level&quot; function because it takes a
    function as one of its arguments.  Other useful higher-level functions
    include &lt;code&gt;filter&lt;/code&gt;, which takes a boolean function (one that
    returns true or false) and &lt;code&gt;flatmap&lt;/code&gt;, which takes a function
    that returns lists and flattens them out into into a single list.  (Some
    languages call that &lt;code&gt;concatmap&lt;/code&gt;.)  &lt;strong&gt;Higher-level
    functions are what make functional languages powerful, beautiful, and easy
    to program in.&lt;/strong&gt;

&lt;p&gt; Now, Church&apos;s lambda calculus was purely mathematical -- Church used it to
    prove things about what kinds of functions were computable, and which
    weren&apos;t, which is exactly what Alan Turing did with the Turing Machine.
    We&apos;ll save that for another post, except to point out that &lt;em&gt;Church&apos;s
    lambda calculus can compute anything that a Turing machine can compute,
    and vice versa.&lt;/em&gt;

&lt;p&gt; But in 1958 John McCarthy at MIT invented a simple way of representing
    lambda expressions as lists, so that they could be processed by a
    computer:  just represent a function and its arguments as a list with the
    function first, followed by its arguments.  Trivial?  Yes.  But
    brilliant.  His paper included a simple function called &lt;code&gt;eval&lt;/code&gt;
    that takes a list representing a function and its arguments, and returns
    the result.  Steve Russell realized that it wouldn&apos;t be hard to implement
    &lt;code&gt;eval&lt;/code&gt; in machine language (on an IBM 704).

&lt;p&gt; I&apos;ll save the details for another post, but the result was a language
    called &lt;a href=&quot;https://en.wikipedia.org/wiki/Lisp_(programming_language)&quot;&gt;Lisp&lt;/a&gt;.  It&apos;s the second oldest programming language still in use.  The
    post about LISP will explain how it works (elsewhere I&apos;ve described
    &lt;code&gt;eval&lt;/code&gt; as &lt;a href=&quot;https://www.quora.com/What-is-the-most-amazing-piece-of-software-in-the-world/answer/Stephen-M-Bear&quot;&gt;The most amazing piece of software in the world&lt;/a&gt;), and hopefully show
    you why Kanef&apos;s song &lt;a href=&quot;http://songworm.com/lyrics/songworm-parody/EternalFlame.html&quot;&gt;The
    Eternal Flame&lt;/a&gt; says that God wrote the universe in LISP.  Programmers
    may want to take a look at &lt;a href=&quot;https://stephen.savitzky.net/Doc/single-link/&quot;&gt;&quot;Sex and the Single
    Link&quot;&lt;/a&gt;.

&lt;h2&gt;And finally,&lt;/h2&gt;

&lt;p&gt; I&apos;d be particularly interested in seeing comments from the
    &lt;em&gt;non-&lt;/em&gt;programmers among my readers, if I haven&apos;t lost you all by
    now.  Was this post interesting?  Was it understandable?  Was it too long?
    Were my examples sufficiently silly?  Inquiring minds...


&lt;p&gt; &lt;em&gt;Another fine post from
    &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer Curmudgeon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1628698&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1628698.html</comments>
  <category>curmudgeon</category>
  <category>programming</category>
  <category>computers</category>
  <category>structured</category>
  <category>fp</category>
  <category>languages</category>
  <category>oop</category>
  <category>software</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>15</lj:reply-count>
</item>
</channel>
</rss>
