<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>freakingpenguin blog</title><id>https://freakingpenguin.com/feed.xml</id><subtitle>Recent Posts</subtitle><updated>2024-03-06T00:00:00Z</updated><link href="https://freakingpenguin.com/feed.xml" rel="self" /><link href="https://freakingpenguin.com" /><entry><title>Haunt and Hoot and Blocks oh my!</title><id>https://freakingpenguin.com/blog/haunt-and-hoot-and-blocks-oh-my.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2025-03-13T00:00:00Z</updated><link href="https://freakingpenguin.com/blog/haunt-and-hoot-and-blocks-oh-my.html" rel="alternate" /><content type="html">&lt;p&gt;This post coincides with the release of 0.2.0 of Guile Blocks, an Org
Mode inspired implementation of source blocks in Guile Scheme. This
post demonstrates some of the functionality I've been working on. You
can find the code for this post &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/blog/tree/master/item/posts/guile-blocks/4-hoot.sxml&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I previously wrote another post showcasing more new functionality.
You can find that post &lt;a href=&quot;guile-blocks-i-have-concepts-of-a-plan.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h1&gt;Hoot&lt;/h1&gt;&lt;p&gt;Hoot is now supported! Hoot is a project by the Spritely Institute
used to run Scheme code in WebAssembly (Wasm) GC-capable web browsers. From the
perspective of a blogger, using Hoot works like this:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Write Scheme code that performs some kind of calculation.&lt;/li&gt;&lt;li&gt;Add Wasm imports to manipulate things outside the Wasm environment.&lt;/li&gt;&lt;li&gt;Load the Wasm module using a JavaScript shim.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;That second item is where the magic happens. Imports are JavaScript
functions, and can take and return values. These values can be common
types like integers or strings, but also more complicated types like
Scheme procedures!&lt;/p&gt;&lt;p&gt;In the below example, I have a Hoot block that uses two imports, one
to insert text into an HTML element and one to run a Guile function on
a timer.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;use-modules&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guile&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;hoot&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;ffi&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ice-9&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;*rotation*&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;pi&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;3.141592654&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;distance-max&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;inside-donut?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;expt&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;expt&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;expt&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;expt&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Invalid coordinate&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;coordinate-&amp;gt;distance&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;degrees&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;radians&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;degrees&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;pi&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;180&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;shape-coordinate&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cos&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;radians&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;inside-donut?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;shape-coordinate&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;nan&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1+&lt;/span&gt;  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;shape-coordinate&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;sin&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;radians&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Invalid coordinates&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;distance-&amp;gt;ascii&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;asciiscale&lt;/span&gt;
    &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;.'`^\&amp;quot;,:;Il!i&amp;gt;&amp;lt;~+_-?][}{1)(|\\/tfjrxzXYUQ0OZmwqhao*#MW&amp;amp;8%B@$&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;nan?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#\space&lt;/span&gt;
      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;asciiscale&lt;/span&gt;
                  &lt;span class=&quot;syntax-comment&quot;&gt;;; at distance=distance-max, we'd get (string-ref a
&lt;/span&gt;                  &lt;span class=&quot;syntax-comment&quot;&gt;;; (length a)), which would cause an error.
&lt;/span&gt;                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1-&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-length&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;asciiscale&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;inexact-&amp;gt;exact&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;round&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-length&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;asciiscale&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                                                 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;distance&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;distance-max&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;coordinate-&amp;gt;ascii&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rotation&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;distance-&amp;gt;ascii&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;coordinate-&amp;gt;distance&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rotation&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;generate-coordinates&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Generate an equidistant list of coordinates of length @var{resolution}
between -1 and 1.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;even?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Resolution must be odd.&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-comment&quot;&gt;;; e.g. 5-&amp;gt;'(-1 -0.5 0 0.5 1)
&lt;/span&gt;  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;point-vals&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;iota&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1+&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-symbol&quot;&gt;-1&lt;/span&gt;
                          &lt;span class=&quot;syntax-comment&quot;&gt;;; -1 + x*resolution = 1
&lt;/span&gt;                          &lt;span class=&quot;syntax-comment&quot;&gt;;; x = 2 / resolution
&lt;/span&gt;                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-comment&quot;&gt;;; '(((-1 -1) (-1 -0.5) ...) ((-0.5 -1) ...) ...)
&lt;/span&gt;    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;syntax-symbol&quot;&gt;point-vals&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;syntax-symbol&quot;&gt;point-vals&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;generate-circle&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rotation&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-join&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list-&amp;gt;string&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;coordinate-&amp;gt;ascii&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coordinate&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rotation&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;syntax-symbol&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;generate-coordinates&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define-foreign&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;display-circle&lt;/span&gt;
  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;my_dom&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;set_element&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;extern&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define-foreign&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;add-timer&lt;/span&gt;
  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;my_control&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;registerTimer&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;extern&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;extern&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;update-circle&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;51&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;set!&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;*rotation*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;*rotation*&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;*rotation*&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display-circle&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;generate-circle&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;resolution&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;*rotation*&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delay-in-ms&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;add-timer&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;delay-in-ms&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;procedure-&amp;gt;external&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;update-circle&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;script type=&quot;text/javascript&quot;&gt;function set_element_contents(value) {
  var paragraph = document.getElementById('hoot-donut-sxml');
  paragraph.textContent = value;
}

async function load() {
  await Scheme.load_main('/static/wasm/donut.wasm', {
    reflect_wasm_dir: '/static/wasm',
    user_imports: {
      my_dom: {
        set_element: set_element_contents
      },
      my_control: {
        registerTimer(delay_in_seconds, f) { setInterval(f, delay_in_seconds); }
      }
    }
  });
}

window.addEventListener('load', load);&lt;/script&gt;&lt;/div&gt;&lt;pre id=&quot;hoot-donut-sxml&quot; style=&quot;line-height: 1.0; font-size: 50%;&quot;&gt;&lt;/pre&gt;&lt;p&gt;For those who want to set up a Hoot+Haunt environment of their own, be
aware that Hoot only works on &amp;quot;bleeding edge&amp;quot; versions of Guile. If
you're using Guix to set up the environment, be sure that Haunt is
configured to use &lt;code&gt;guile-next&lt;/code&gt; and not &lt;code&gt;guile&lt;/code&gt;. Otherwise
you may encounter build failures depending on how exactly you're
invoking Hoot.&lt;/p&gt;&lt;p&gt;Here's an example of how to do that.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guile-&amp;gt;guile-next&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;package&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;inherit&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;modify-inputs&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;package-inputs&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;replace&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;guile&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;guile-next&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guile-&amp;gt;guile-next&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;haunt&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;syntax-comment&quot;&gt;;;=&amp;gt; a variant of haunt that uses guile-next&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There's definitely more work to be done. For one, the JavaScript
wrappers aren't handled in the most elegant way, and the scripts
themselves are completely inline (as opposed to written to a file).
This isn't hard for a user to fix, but it isn't great either.&lt;/p&gt;&lt;p&gt;It would also be nice to support more Wasm runtimes, such as Ruby or
Rust. This may result in some backwards-incompatible changes to Guile
Blocks's Hoot support as things are refactored.&lt;/p&gt;&lt;h1&gt;Info!&lt;/h1&gt;&lt;p&gt;Guile Blocks now has an info manual! An online mirror of the
 manual is hosted at &lt;a href=&quot;https://guile-blocks.info&quot;&gt;guile-blocks.info&lt;/a&gt;. Forgive the rough edges, the pipeline to convert Org to TexInfo to
both Info and HTML is rough.&lt;/p&gt;&lt;h1&gt;Ngspice&lt;/h1&gt;&lt;p&gt;Guile Blocks now supports Ngspice! As always, it is possible pipe the
output from Ngspice to graphing programs like Gnuplot to generate graphs.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;.title dual rc ladder
R1 int in 10k
V1 in 0 dc 0 ac 1 PULSE (0 5 1u 1u 1u 1 1)
R2 out int 1k
C1 int 0 1u
C2 out 0 100n
.control
ac dec 10 1 100k
wrdata /dev/stdout vdb(out)
.endc
.end&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-guile-blocks-ngspice-graph.png&quot; /&gt;&lt;/div&gt;</content></entry><entry><title>Guix Tricks: Managing secrets using password-store and run-time
decryption scripts.</title><id>https://freakingpenguin.com/blog/guix-tricks-managing-secrets-using-password-store-and-run-time-decryption-scripts.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-12-10T12:00:00Z</updated><link href="https://freakingpenguin.com/blog/guix-tricks-managing-secrets-using-password-store-and-run-time-decryption-scripts.html" rel="alternate" /><content type="html">&lt;h1&gt;Intro&lt;/h1&gt;&lt;p&gt;Guix is a package management tool with support for declarative
operation. By declarative, I mean I can write various objects—such as
an operating system configuration—in a text file. Guix will take that
text file and use it to create what I want. For example...&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%simple-os&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;operating-system&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;host-name&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;komputilo&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;timezone&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;America/New_York&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;locale&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;en_US.UTF-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bootloader&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bootloader-configuration&lt;/span&gt;
                 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bootloader&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;grub-bootloader&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;targets&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/dev/sdX&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-systems&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-system&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-system-label&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;my-root&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mount-point&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;ext4&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;syntax-symbol&quot;&gt;%base-file-systems&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;user-account&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;alice&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;comment&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Bob's sister&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;users&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;supplementary-groups&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;wheel&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;audio&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;video&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                 &lt;span class=&quot;syntax-symbol&quot;&gt;%base-user-accounts&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Generally speaking, anything stored in these files or built from them
should be considered public knowledge. Even if I decide
not to share the declarative files, the outputs from building them are
placed in a location called the store, unencrypted and globally
readable on the hard drive. It would be trivial for an attacker to
capture private information from these files.&lt;/p&gt;&lt;p&gt;This presents a challenge. How can we use private information (i.e.
secrets) in these files without leaking said secrets?&lt;/p&gt;&lt;p&gt;There are three solutions I can think of.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create files containing secrets manually and avoid using Guix. Set
permissions to limit readability.&lt;/li&gt;&lt;li&gt;Use a service to store secrets in the store encrypted, then decrypt
them on boot and place them in the desired location.&lt;/li&gt;&lt;li&gt;Store the secrets encrypted, then run scripts to retrieve them on an
as-needed basis.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In this post I will be discussing how I implement the 3rd solution.
If 2 sounds interested, check out &lt;a href=&quot;https://github.com/fishinthecalculator/sops-guix&quot;&gt;sops-guix&lt;/a&gt;.&lt;/p&gt;&lt;h1&gt;Runtime Decryption and Retrieval&lt;/h1&gt;&lt;h2&gt;The Not State of the Art Solution&lt;/h2&gt;&lt;p&gt;I store my secrets encrypted in a separate, private Git repository
using &lt;a href=&quot;https://www.passwordstore.org/&quot;&gt;password-store&lt;/a&gt;. For this strategy to work, the service or program being configured
needs to support running a script to retrieve a secret.&lt;/p&gt;&lt;p&gt;Consider my git configuration. I regularly use the &lt;code&gt;$ git send-email&lt;/code&gt; command. While I could manually decrypt my password and paste that
when prompted, I would rather git do that automatically. Fortunately,
git supports running an arbitrary command to retrieve the password.
This is done by setting &lt;code&gt;core.askPass&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;I could construct my git config like this:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; Git does not actually support arguments for askPass.
&lt;/span&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; For brevity I am going to pretend it does.
&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rsent-git-config-file&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;plain-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;git-config&amp;quot;&lt;/span&gt;
                   &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;
[core]
        askPass = pass ls Passwords/MyEmailAccount&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;# Contents of .config/git/config
[core]
        askPass = pass ls Passwords/MyEmailAccount&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;While it works in this example, this solution is not as general
purpose as it could be. This solution:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Requires an environment where the PATH environment variable is already
set.&lt;/li&gt;&lt;li&gt;Makes it challenging to switch off of password-store in the future.&lt;/li&gt;&lt;li&gt;Creates an unlinked dependency in my code because I have to install
password-store elsewhere.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Some of these issues can be mitigated while still invoking pass
directly but I believe there's a better way.&lt;/p&gt;&lt;h2&gt;A More Guixy Way&lt;/h2&gt;&lt;p&gt;Instead of invoking pass directly in my git config file, I go
another route. In essence, I write a function that takes a &amp;quot;key&amp;quot; for
what I want to retrieve. This function returns a script that, when
invoked, decrypts the secret associated with said key and returns its
value.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rsent-get-smtp-password-script&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;get-secret-program-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;git-getpass&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Passwords/MyEmailAccount&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rsent-git-config-file&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mixed-text-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;git-config&amp;quot;&lt;/span&gt;
                   &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;
[core]
        askPass = &amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rsent-get-smtp-password-script&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;
&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;# Contents of .config/git/config
[core]
        askPass = /gnu/store/...-git-getpass&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;get-secret-program-file&lt;/code&gt; in turn looks something like this:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;get-secret-program-file&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Returns a file-like object capable of retrieving the secret for @var{key}.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;program-file&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#$&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;get-secret&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can probably guess, most of the magic happens in
another function called &lt;code&gt;get-secret&lt;/code&gt;. This function is quite a bit &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/rsent/tree/f37511d6e343bb42518ebf36ad382181d6e661d0/item/rsent/utils/secrets.scm#L96&quot;&gt;more complicated&lt;/a&gt; than I want to dive into, but I'll share an abbreviated
version. (Until recently this function was short, but then &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/rsent/commit/3f9f4f3b9c7b44b916e59218659c2fa4cae73cd0&quot;&gt;GnuPG pinentry fun&lt;/a&gt; happened.)&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;get-secret&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Returns a @code{gexp} that returns the associated secret for @var{key}.
Key should be in the form of a password-store path.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;use-modules&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ice-9&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ice-9&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;popen&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ice-9&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;rdelim&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;current-error-port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;~!Fetching secret for ~a... &amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#$key&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;open-input-pipe&lt;/span&gt;
                    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt;
                     &lt;span class=&quot;syntax-symbol&quot;&gt;#$&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;password-store&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/pass&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                     &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot; ls &amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#$key&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;read-line&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;close-pipe&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;eof-object?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Failed to retrieve secret for&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#$key&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;current-error-port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;~!done~%&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-symbol&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I want to emphasize how flexible this solution is. Any arbitrary
Scheme code can be placed in &lt;code&gt;get-secret&lt;/code&gt;, invoking any combination of external programs. If in the future I
want to switch to another secret management system, I only need to
rework one function and everything that works with secrets will use
the new system.&lt;/p&gt;&lt;h1&gt;Conclusion&lt;/h1&gt;&lt;p&gt;Guix does not have an official integrated method for secrets
management. This leads to users creating ad-hoc solutions. One such
method is creating executable scripts that can decrypt and retrieve
secrets, then embedding those scripts in the appropriate program or
service.&lt;/p&gt;&lt;p&gt;Here are the positives to this approach:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Secrets are always encrypted on disk.&lt;/li&gt;&lt;li&gt;Works for both Guix System and Guix Home.&lt;/li&gt;&lt;li&gt;It is easy to migrate between different methods for storing secrets.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;However, there are limitations:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The services and/or programs being configured need to support
executing programs to retrieve secrets.&lt;/li&gt;&lt;li&gt;User interaction is generally recommended to protect against
unauthorized access.&lt;/li&gt;&lt;li&gt;The creator is responsible for ensuring the script is secure,
especially if it is designed to operate non-interactivity&lt;/li&gt;&lt;li&gt;Debugging requires a thorough understanding of the context the
script is running in. For example, system services have a barer environment than
home services.&lt;/li&gt;&lt;/ol&gt;</content></entry><entry><title>Guile Blocks: I Have Concepts of a Plan</title><id>https://freakingpenguin.com/blog/guile-blocks-i-have-concepts-of-a-plan.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-09-11T00:00:00Z</updated><link href="https://freakingpenguin.com/blog/guile-blocks-i-have-concepts-of-a-plan.html" rel="alternate" /><content type="html">&lt;p&gt;I recently released v0.1.0 of Guile Blocks, an Org Mode
inspired implementation of source blocks in Guile Scheme. This post
demonstrates some of the functionality I've been working on since
then.&lt;/p&gt;&lt;h1&gt;PlantUML&lt;/h1&gt;&lt;p&gt;PlantUML diagrams are now supported.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;@startuml
Alice -&amp;gt; Bob: Authentication Request
Bob --&amp;gt; Alice: Authentication Response

Alice -&amp;gt; Bob: Another authentication Request
Alice &amp;lt;-- Bob: Another authentication Response
@enduml&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;/static/images/charts/guile-blocks-plantuml.png&quot; /&gt;&lt;/div&gt;&lt;p&gt;PlantUML was tricky to support. This is because of how PlantUML
handles writing and naming the output diagram. By priority, PlantUML names the
output diagram in one of two ways:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Is there a filename in the UML code? e.g. &lt;code&gt;@startuml &amp;lt;filename&amp;gt; ... @enduml&lt;/code&gt;&lt;/li&gt;&lt;li&gt;What is the filename passed on the command line? e.g. &lt;code&gt;$ plantuml &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Option 1 is interesting, but in order to print the block,
I need the PlantUML evaluator to return the filename. PlantUML is
stingy and does not print the filename to stdout. This means the only
way to get the output filename is by parsing the UML diagram in Guile.&lt;/p&gt;&lt;p&gt;This wouldn't be too bad, but unfortunately these diagrams are not
restricted to &lt;code&gt;@startuml&lt;/code&gt; tags. They may also be &lt;code&gt;@startjson&lt;/code&gt;, &lt;code&gt;@startsalt&lt;/code&gt;, and more. A regex could handle this, but that solution
feels... icky. I want to minimize the linkage between Guile Blocks and
the supported languages when possible.&lt;/p&gt;&lt;p&gt;Option 2 also isn't great. Behind the scenes Guile Blocks creates a
temporary file (of the form &lt;code&gt;/tmp/fileXXXXXX&lt;/code&gt;) and passes that to PlantUML. This means that any diagram that does
not contain a filename in its code will have a random name.&lt;/p&gt;&lt;p&gt;Worse, PlantUML also does &lt;em&gt;not&lt;/em&gt; write the output diagram to the current working directory. For
whatever reason it writes to the same directory as the input file.
Writing diagrams to &lt;code&gt;/tmp&lt;/code&gt; isn't very useful.&lt;/p&gt;&lt;p&gt;So, if both option 1 and option 2 aren't viable, I'm left with no
other choice but to create a 3rd option. To do this, I use a
comparatively niche PlantUML feature, pipe output. When &lt;code&gt;-pipe&lt;/code&gt; is passed, PlantUML writes the output diagram to stdout instead of a
file. From there I can capture the diagram as a bytevector and write it
to a file in Scheme.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;run-plantuml&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;format-flag&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;-t&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;output-dir&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-comment&quot;&gt;;; Guile will error if the output directory does not exist.
&lt;/span&gt;    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mkdir-p&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;output-dir&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;call-with-output-file&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;filename&lt;/span&gt;
      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;put-bytevector&lt;/span&gt;
         &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;
         &lt;span class=&quot;syntax-comment&quot;&gt;;; Output is a raw image, not a string. Avoid corruption
&lt;/span&gt;         &lt;span class=&quot;syntax-comment&quot;&gt;;; caused by conversion to string.
&lt;/span&gt;         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bv-in-&amp;gt;string-in&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;eval-from-stdin-bytevector&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt;
          &lt;span class=&quot;syntax-symbol&quot;&gt;%plantuml-command&lt;/span&gt;
          &lt;span class=&quot;syntax-symbol&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;,@flags&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,format-flag&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;-pipe&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This did require reworking my evaluator functions to be a bit more
generic.&lt;/p&gt;&lt;h2&gt;Bytevector Evaluators&lt;/h2&gt;&lt;p&gt;Previously, Guile Blocks was designed around string-based evaluators,
or evaluators that take and receive strings, when invoking external
processes. These work well in most cases. However, the process of
encoding an image into a string and writing said string to a file
corrupts the image (at least for PNGs). To resolve this, I rewrote the
evaluators to operate on bytevectors and added a layer of wrapper
functions to convert those bytevectors to and from strings.&lt;/p&gt;&lt;p&gt;I quite like how the bytevector translation functions look.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bv-in-&amp;gt;string-in&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bv-func&lt;/span&gt; &lt;span class=&quot;syntax-keyword&quot;&gt;#:key&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bv-func&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-&amp;gt;bytevector&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;string&lt;/span&gt;
                               &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;
                                   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;fluid-ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%default-port-encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-symbol&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bv-out-&amp;gt;string-out&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bv-func&lt;/span&gt; &lt;span class=&quot;syntax-keyword&quot;&gt;#:key&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;args&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bv-func&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;syntax-comment&quot;&gt;;; Conditional as bv-func may return #&amp;lt;eof&amp;gt; which is not a
&lt;/span&gt;      &lt;span class=&quot;syntax-comment&quot;&gt;;; bytevector.
&lt;/span&gt;      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bytevector?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bytevector-&amp;gt;string&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;
                              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;
                                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;fluid-ref&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%default-port-encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bv-in-out-&amp;gt;string-in-out&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bv-func&lt;/span&gt; &lt;span class=&quot;syntax-keyword&quot;&gt;#:key&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bv-in-&amp;gt;string-in&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bv-out-&amp;gt;string-out&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bv-func&lt;/span&gt; &lt;span class=&quot;syntax-keyword&quot;&gt;#:encoding&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;syntax-keyword&quot;&gt;#:encoding&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I find it neat how generic these functions are. &lt;em&gt;Any&lt;/em&gt; function that takes a bytevector as its first argument can be wrapped
to take a string instead, independent of the rest of its signature.
The same goes for any function that returns a bytevector.&lt;/p&gt;&lt;p&gt;This allows mo to trivially support both string and bytevector based
evaluators. Unfortunately the naming scheme is still a bit clunky.&lt;/p&gt;&lt;h1&gt;C&lt;/h1&gt;&lt;p&gt;C code is also supported.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;stdio.h&amp;gt;

&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Hello world!\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;Hello world!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At present this support is fairly barebones. Snippets are compiled to
a temporary file using GCC and executed.&lt;/p&gt;&lt;p&gt;The only interesting trick here is learning about GCC's &lt;code&gt;-x&lt;/code&gt; flag. Like before, the C code is stored in a &lt;code&gt;/tmp/fileXXXXXX&lt;/code&gt; file and passed to GCC on the command line. It turns out that when a
file is missing an extension, GCC does not know how to compile it. I
can override this by changing the invocation to &lt;code&gt;$ gcc /tmp/fileXXXXXX -x c&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Supporting other GCC languages like C++ should be as simple as
changing the extension.&lt;/p&gt;</content></entry><entry><title>Guile Blocks: Fleshing out the Concept</title><id>https://freakingpenguin.com/blog/guile-blocks-fleshing-out-the-concept.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-07-30T00:00:00Z</updated><link href="https://freakingpenguin.com/blog/guile-blocks-fleshing-out-the-concept.html" rel="alternate" /><content type="html">&lt;p&gt;This post is a continuation of a &lt;a href=&quot;https://freakingpenguin.com/blog/guile-blocks-proof-of-concept.html&quot;&gt;previous post&lt;/a&gt; and is meant to further showcase &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/guile-blocks&quot;&gt;Guile Blocks&lt;/a&gt;, an Org Mode inspired implementation of source blocks in Guile Scheme.&lt;/p&gt;&lt;p&gt;This post will omit discussing the technical implementation. At
present, documentation for Guile Blocks can be found in its &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/guile-blocks&quot;&gt;README&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The source code for this page found &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/blog/tree/master/item/posts/guile-blocks/2.sxml&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h1&gt;Graphs&lt;/h1&gt;&lt;p&gt;Graphs can be created using &lt;a href=&quot;http://www.gnuplot.info&quot;&gt;gnuplot&lt;/a&gt;. You can either feed gnuplot raw data or generate the data from another
block.&lt;/p&gt;&lt;p&gt;This graph is created by using a block containing space-delimited
data:&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;set title 'Hello world!'
plot '-' with lines
1 1
2 2
3 3
4 4&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-guile-blocks-demo-1.png&quot; /&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;Whereas this graph is created by running the following Ruby code with
a gnuplot block in a pipeline:&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;def fibonacci(n)
   n &amp;lt;= 1 ? n :  fibonacci(n - 1) + fibonacci(n - 2)
end

10.times do |n|
  puts &amp;quot;#{n} #{fibonacci(n)}&amp;quot;
end&lt;/code&gt;&lt;/pre&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-guile-blocks-demo-2.png&quot; /&gt;&lt;/div&gt;&lt;/p&gt;&lt;h1&gt;LaTeX&lt;/h1&gt;&lt;p&gt;LaTeX snippets and equations are supported. These equations are
converted to MathML using &lt;a href=&quot;https://dlmf.nist.gov/LaTeXML/&quot;&gt;LaTeXML&lt;/a&gt;. If your browser does not support MathML, you may find odd behavior in
this section.&lt;/p&gt;&lt;p&gt;Equations can be either simple or complex.&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;\frac{1}{2}&lt;/code&gt;&lt;/pre&gt;&lt;math display=&quot;block&quot; alttext=&quot;\frac{1}{2}&quot;&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mfrac&gt;&lt;/math&gt;&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;\oint \vec{E}\cdot \mathrm{d}\vec{A} =
\frac{q_{\mathrm{enc}}}{\varepsilon_0}&lt;/code&gt;&lt;/pre&gt;&lt;math display=&quot;block&quot; alttext=&quot;\oint\vec{E}\cdot\mathrm{d}\vec{A}=\frac{q_{\mathrm{enc}}}{\varepsilon_{0}}&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;∮&lt;/mo&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;E&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;→&lt;/mo&gt;&lt;/mover&gt;&lt;mo lspace=&quot;0.222em&quot;&gt;⋅&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot; lspace=&quot;0.055em&quot;&gt;d&lt;/mo&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;→&lt;/mo&gt;&lt;/mover&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;msub&gt;&lt;mi&gt;q&lt;/mi&gt;&lt;mi&gt;enc&lt;/mi&gt;&lt;/msub&gt;&lt;msub&gt;&lt;mi&gt;ε&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;Inline equations are also supported. For example, &lt;math display=&quot;inline&quot; alttext=&quot;\sqrt{54}&quot;&gt;&lt;msqrt&gt;&lt;mn&gt;54&lt;/mn&gt;&lt;/msqrt&gt;&lt;/math&gt;. &lt;/p&gt;&lt;p&gt;Like before, these equations can be quite complicated. For instance,
here is a special case of the Schrödinger equation: &lt;math display=&quot;inline&quot; alttext=&quot;i\hbar\frac{\partial}{\partial t}\Psi(x,t)=\left[-\frac{\hbar^{2}}{2m}\frac{%
\partial^{2}}{\partial x^{2}}+V(x,t)\right]\Psi(x,t)&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;ℏ&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mfrac&gt;&lt;mo&gt;∂&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;∂&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ψ&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;msup&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;ℏ&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mfrac&gt;&lt;msup&gt;&lt;mo&gt;∂&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;∂&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Ψ&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;,&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;.&lt;/p&gt;&lt;h1&gt;Tables&lt;/h1&gt;&lt;p&gt;Data can be formatted in the same style as Org-mode tables.&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;def fibonacci(n)
   n &amp;lt;= 1 ? n :  fibonacci(n - 1) + fibonacci(n - 2)
end

10.times do |n|
  puts &amp;quot;#{n} #{fibonacci(n)}&amp;quot;
end&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;| 0 |  0 |
| 1 |  1 |
| 2 |  1 |
| 3 |  2 |
| 4 |  3 |
| 5 |  5 |
| 6 |  8 |
| 7 | 13 |
| 8 | 21 |
| 9 | 34 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</content></entry><entry><title>Guix Tricks: Soft-pinning channels in a channels.scm file.</title><id>https://freakingpenguin.com/blog/guix-tricks-soft-pinning-channels-in-a-channelsscm-file.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-05-26T12:00:00Z</updated><link href="https://freakingpenguin.com/blog/guix-tricks-soft-pinning-channels-in-a-channelsscm-file.html" rel="alternate" /><content type="html">&lt;h1&gt;Problem&lt;/h1&gt;&lt;p&gt;Guix is a very powerful tool to integrate into a project's toolchain.
This isn't just for build systems. It can also apply to tools like
interactive interpreters and debuggers. By creating a project-wide &lt;code&gt;channels.scm&lt;/code&gt; file, you can prepend tool scripts with both &lt;code&gt;guix time-machine&lt;/code&gt; and &lt;code&gt;guix shell&lt;/code&gt; invocations. This allows for easy integration of additional Guix
channels and ensures that every developer has development tools
available to them that aren't reliant on the outside environment.&lt;/p&gt;&lt;p&gt;You can see an example of me using this &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/blog/tree/53b1d18aea0fe7353d9cfdc2a5b8e7f393cf06a3/item/.dir-locals.el&quot;&gt;here&lt;/a&gt; to invoke a Guile REPL with the Guix and rsent-freakingpenguin
channels. This includes a dependency of rsent-freakingpenguin:
guile-blocks. I also use it in the &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/blog/tree/53b1d18aea0fe7353d9cfdc2a5b8e7f393cf06a3/item/bin/serve&quot;&gt;./bin/serve&lt;/a&gt; script to build and locally deploy the website for testing.&lt;/p&gt;&lt;p&gt;However, one challenge of &lt;code&gt;guix time-machine&lt;/code&gt; is that unless you are willing to pin channels to specific commits,
it will ALWAYS try to pull the latest version of that channel. Because
channels are always changing (particularly the Guix channel) this can
introduce significant delays when, say, invoking a Guile REPL after a
new Guix commit was pushed.&lt;/p&gt;&lt;p&gt;As mentioned, one solution is to pin channels to specific version or
branches. However, this has several drawbacks:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The commit needs to be updated regularly to ensure
compatibility with newer tools.&lt;/li&gt;&lt;li&gt;When first run, developers still need to pull an entirely different
commit to what they're running.&lt;/li&gt;&lt;li&gt;It implies that the developer tools require that specific commit to
function even if that is not the case.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;My proposed solution to this is a concept I'll call &amp;quot;soft-pinning&amp;quot;,
which means &amp;quot;try to use whatever commit of this channel that is
currently present on the user's profile&amp;quot;. This will let us mix and
match channels into different categories. One category is kept up to
date at all times while the other is only updated as the user updates
their system.&lt;/p&gt;&lt;h1&gt;Solution&lt;/h1&gt;&lt;p&gt;To implement this, we can take advantage of the fact that &lt;code&gt;channels.scm&lt;/code&gt; is Guile Scheme code and use the &lt;code&gt;current-channels&lt;/code&gt; procedure in the &lt;code&gt;(guix describe)&lt;/code&gt; module. Here's the code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; Use this file with time-machine -C to get an up to date copy of
&lt;/span&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; this channel and any dependencies.
&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;use-modules&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;srfi&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;srfi-1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ice-9&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;control&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;soft-pin-channel&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;input-channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Given @var{channel}, return a new version of channel that uses the
current profile's commit of said channel. If the channel is not present,
commit is #f.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;desired-channel?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;equal?&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;channel-name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;input-channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;channel-name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;profile-commit&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;input-channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;call/ec&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;desired-channel?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;channel-commit&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;current-channels&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;channel&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;inherit&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;input-channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;profile-commit&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;input-channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-comment&quot;&gt;;; Note that if you try running this in a container (say, the
&lt;/span&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; project's interactive Guile), the commit picked up will match the
&lt;/span&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; Guix package in the container's profile. It will not match the
&lt;/span&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; user's current profile channel commit.
&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cons*&lt;/span&gt;
 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;channel&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'freakingpenguin&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;file://&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;getcwd&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;soft-pin-channel&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%default-guix-channel&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, invoking the Guile REPL is instantaneous as long as the
freakingpenguin channel does not change. I no longer have a minute
delay or more every time a new Guix commit is pushed, while still not
having to pin Guix at a specific commit.&lt;/p&gt;</content></entry><entry><title>Guix Tricks: Self-contained shebang scripts.</title><id>https://freakingpenguin.com/blog/guix-tricks-self-contained-shebang-scripts.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-05-11T12:00:00Z</updated><link href="https://freakingpenguin.com/blog/guix-tricks-self-contained-shebang-scripts.html" rel="alternate" /><content type="html">&lt;h1&gt;Intro&lt;/h1&gt;&lt;p&gt;I like scripts. You like scripts. We all like scripts. But, I don't
like that when I give a script to someone else, they need to install
X, Y, and Z packages for that script to work. I don't like that my
scripts may behave differently depending on the user's environment. I
don't like needing to install a bunch of packages in a CI environment
before running my&lt;code&gt;./bin/*&lt;/code&gt;scripts. If ONLY someone could help me!&lt;/p&gt;&lt;p&gt;Consider the &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/blog/tree/master/item/bin/readme-html&quot;&gt;following script&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;#!/usr/bin/env&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;emacs&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;-x&lt;/span&gt;
&lt;span class=&quot;syntax-comment&quot;&gt;;; -*- mode: emacs-lisp; -*-
&lt;/span&gt;&lt;span class=&quot;syntax-comment&quot;&gt;;; https://orgmode.org/manual/Bare-HTML.html
&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-head&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-head-extra&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-head-include-default-style&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-head-include-scripts&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-postamble&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-preamble&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-use-infojs&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;org-html-mathjax-template&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;defvar&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;build-status-image&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;#+ATTR_HTML: :alt builds.sr.ht status
[[https://builds.sr.ht/~freakingpenguin/&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;getenv&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;repo&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;]&amp;quot;&lt;/span&gt;
&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;[https://builds.sr.ht/~freakingpenguin/&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;getenv&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;repo&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;.svg]]
&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;find-file-noselect&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;nth&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;build-status-image&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;org-html-export-to-html&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a script that takes an org-mode file and generates an HTML
file. A perfect task for a CI job. Ideally, we want this script to
contain all the information required to run it, including the packages
it requires. Keeping this information together in one file makes it
easier to track and simpler for anyone to run the script.&lt;/p&gt;&lt;p&gt;To both install Emacs AND run the script in one go, all we have to do
is replace the shebang with this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#!/usr/bin/env -S guix shell emacs emacs-htmlize -- emacs -x&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I like this because it lets me avoid needing to learn complicated
tools like Docker for something that should be a simple task. A
concept like &amp;quot;run command X with software Y in a containerized
environment&amp;quot; can be expressed using basic tooling (shebangs) everyone
is already familiar with. I may know how Docker works and how to write
Dockerfiles, but without regular, consistent use it's easy to forget
their syntax and need to relearn it yet again. Shell scripts are
universal. 💕&lt;/p&gt;&lt;h1&gt;Another example&lt;/h1&gt;&lt;p&gt;You can go one step further and run the script in a containerized
environment to ensure that you captured all possible dependencies and
that the behavior is consistent regardless of the user's environment.&lt;/p&gt;&lt;p&gt;For particularly version-sensitive scripts, you can combine this
with guix time-machine. Then, all dependencies required to run the
script can be near-effortlessly frozen and guaranteed to run
identically between invocations.&lt;/p&gt;&lt;p&gt;Using guix shell in shebangs makes running arbitrary projects with
Emacs's&lt;code&gt;compile-command&lt;/code&gt; a breeze, since it boils down the complicated task of environment
setup all the way down to just a running a script. Like, for example,
with how I build this site. In&lt;code&gt;./bin/serve&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#!/usr/bin/env -S guix shell ruby ruby-colorize -- ruby
# -*- mode: ruby; -*-
require 'optparse'
require 'colorize'
require 'socket'

bind = &amp;quot;localhost&amp;quot;
quiet = &amp;quot;&amp;quot;
no_substitutes = &amp;quot;&amp;quot;
options = {}
OptionParser.new do |opts|
  opts.on(&amp;quot;-p&amp;quot;, &amp;quot;--public&amp;quot;, &amp;quot;Bind to 0.0.0.0 instead of localhost&amp;quot;) do
    bind = &amp;quot;0.0.0.0&amp;quot;
  end

  opts.on(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;, &amp;quot;Minimize output.&amp;quot;) do
    quiet = &amp;quot;-q&amp;quot;
  end

  opts.on(&amp;quot;-s&amp;quot; &amp;quot;--no-substitutes&amp;quot;, &amp;quot;Do not use substitutes&amp;quot;) do
    # Helpful if there are network issues
    no_substitutes = &amp;quot;--no-substitutes&amp;quot;
  end
end.parse!

puts &amp;quot;Building site&amp;quot;.red
puts site_dir = `guix time-machine -C channels.scm -- \
                      build #{no_substitutes} #{quiet} -f guix.scm`
                  .chomp + &amp;quot;/site&amp;quot;
raise &amp;quot;Build Failure&amp;quot; unless $?.success?

ip_address = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}.ip_address.to_s
puts &amp;quot;Serving site publicly on #{ip_address}&amp;quot;.red unless bind == &amp;quot;localhost&amp;quot;
system(&amp;quot;guix time-machine -C channels.scm -- shell #{no_substitutes} \
              -CN --no-cwd --expose=#{site_dir}=/srv/html python --   \
              python3 -m http.server -d /srv/html --bind #{bind}&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I can add &lt;code&gt;(compile-command .
 &amp;quot;./bin/serve -p&amp;quot;)&lt;/code&gt; to &lt;code&gt;.dir-locals.el&lt;/code&gt;, without
 needing to worry about &lt;code&gt;direnv&lt;/code&gt;, syncing separate scripts and
 Dockerfiles, or anything else.&lt;/p&gt;</content></entry><entry><title>Guile Blocks: Proof of Concept</title><id>https://freakingpenguin.com/blog/guile-blocks-proof-of-concept.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-04-01T18:49:00Z</updated><link href="https://freakingpenguin.com/blog/guile-blocks-proof-of-concept.html" rel="alternate" /><content type="html">&lt;h1&gt;Introduction&lt;/h1&gt;&lt;p&gt;Hi! This is an introductory page demonstrating &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/guile-blocks&quot;&gt;Guile Blocks&lt;/a&gt;, an Org Mode inspired implementation of source blocks in Guile Scheme.&lt;/p&gt;&lt;p&gt;You're encouraged to read the project README before or alongside this
post. This post primarily exists to demonstrate their real-life usage.
The README covers more technical details.&lt;/p&gt;&lt;p&gt;I also encourage checking out the source file for this post. You can find that &lt;a href=&quot;https://git.sr.ht/~freakingpenguin/blog/tree/master/item/posts/guile-blocks/1.sxml&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h1&gt;Blocks&lt;/h1&gt;&lt;p&gt;Blocks are records &lt;em&gt;primarily&lt;/em&gt; composed of two fields: arbitrary
code (usually a string) and a language.&lt;/p&gt;&lt;p&gt;The syntax for defining code blocks looks like this:&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define-block&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;foo&lt;/span&gt;
  &lt;span class=&quot;syntax-keyword&quot;&gt;#:code&lt;/span&gt;     &lt;span class=&quot;syntax-symbol&quot;&gt;bar&lt;/span&gt;
  &lt;span class=&quot;syntax-keyword&quot;&gt;#:language&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;A language is another record composed of two elements: an
alist of decorators and an evaluator. Decorators are outside the scope
of this article but they are how features like syntax highlighting are
executed.&lt;/p&gt;&lt;p&gt;Evaluators, meanwhile, are simply functions that take a value and
return a result. In most cases, this means taking in a script and
evaluating that script appropriately. For example, the Python
evaluator invokes Python and writes the script to Python's stdin.
Whatever Python prints to stdout is captured and returned.&lt;/p&gt;&lt;p&gt;The blocks shown in the following segment were run when the website
was built. The results were not prepopulated.&lt;/p&gt;&lt;p&gt;It's easy to support different languages. Here's some Ruby code.&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;puts &amp;quot;Ahh, General Kenobi. You are a bold one.&amp;quot;.upcase&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;AHH, GENERAL KENOBI. YOU ARE A BOLD ONE.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;And here is some Elixir code. This was actually created by running two
separate blocks as a pipeline.&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;IO.write (1 + 7)&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;8&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;Syntax highlighting isn't just supported for Guile! The provided
languages that support syntax highlighting use David Thompson's
guile-syntax-highlight. However, any highlighter could be used.&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-keyword&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;syntax-ident&quot;&gt;screen&lt;/span&gt; &lt;span class=&quot;syntax-ident&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-builtin-property&quot;&gt;min-width&lt;/span&gt;: &lt;span class=&quot;syntax-number&quot;&gt;720px&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-prelude&quot;&gt;pre&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-comment&quot;&gt;/* Don't shrink code block font when there's enough width. */&lt;/span&gt;
        &lt;span class=&quot;syntax-builtin-property&quot;&gt;font-size&lt;/span&gt;: &lt;span class=&quot;syntax-number&quot;&gt;1em&lt;/span&gt;&lt;span class=&quot;syntax-comma&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</content></entry><entry><title>Haunt can handle org-mode source blocks too! Kinda.</title><id>https://freakingpenguin.com/blog/haunt-can-handle-org-mode-source-blocks-too-kinda.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-03-02T13:15:00Z</updated><link href="https://freakingpenguin.com/blog/haunt-can-handle-org-mode-source-blocks-too-kinda.html" rel="alternate" /><content type="html">&lt;p&gt;One of the things I miss now that my blog has moved to Guile Haunt is
the lack of source blocks. This post is a proof of concept for how I
may go about handling them in the future.&lt;/p&gt;&lt;p&gt;For those who aren't aware, org-mode source blocks are a way for you
to embed executable code and their result(s) in org-mode documents. They have a lot of features, but a basic source block would be
&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#+begin_src C
  printf(&amp;quot;Hello world!\n&amp;quot;);
#+end_src

#+RESULTS:
: Hello world!&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I would talk about the implementation more, but the code is simple
enough that I'll let it do the talking. If you're not familiar with
SXML, the 12 word summary is &amp;quot;it's HTML, but instead of &amp;lt;p&amp;gt; it's (p
and instead of &amp;lt;/p&amp;gt; it's )&amp;quot;.&lt;/p&gt;&lt;p&gt;Here is a barebones code block showing how by treating code as data,
we can both output the code as a string and evaluate it.&lt;/p&gt;&lt;p&gt;&lt;div class=&quot;code-block-maybe-results&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;Results:&lt;pre&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;Interestingly, this method can work on itself. Here is (most of) the code used to make it happen.&lt;/p&gt;&lt;p&gt;&lt;div class=&quot;code-block-maybe-results&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;sxml-code-block&lt;/span&gt;
            &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt;
            &lt;span class=&quot;syntax-keyword&quot;&gt;#:key&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;evaluator&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cut&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;interaction-environment&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;lexer&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;lex-scheme&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;raw?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;fmt&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;raw?&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;~a&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;~y&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;code-block-maybe-results&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;pre&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;highlights-&amp;gt;sxml&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;highlight&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;lexer&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;fmt&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;syntax-symbol&quot;&gt;,@&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;evaluator&lt;/span&gt;
                  &lt;span class=&quot;syntax-symbol&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Results:&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;pre&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;fmt&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;evaluator&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;sxml-code-block&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;Results:&lt;pre&gt;&lt;code&gt;(div (@ (class &amp;quot;code-block-maybe-results&amp;quot;))
     (pre (code ((span (@ (class &amp;quot;syntax-open&amp;quot;)) &amp;quot;(&amp;quot;)
                 (span (@ (class &amp;quot;syntax-symbol&amp;quot;)) &amp;quot;+&amp;quot;)
                 &amp;quot; &amp;quot;
                 (span (@ (class &amp;quot;syntax-symbol&amp;quot;)) &amp;quot;1&amp;quot;)
                 &amp;quot; &amp;quot;
                 (span (@ (class &amp;quot;syntax-symbol&amp;quot;)) &amp;quot;1&amp;quot;)
                 (span (@ (class &amp;quot;syntax-close&amp;quot;)) &amp;quot;)&amp;quot;)
                 &amp;quot;\n&amp;quot;)))
     &amp;quot;Results:&amp;quot;
     (pre (code &amp;quot;2\n&amp;quot;)))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;One major disadvantage of this approach is that Scheme sexps do not
preserve the input formatting. For example, &lt;code&gt;'(foo bar)&lt;/code&gt; and &lt;code&gt;'(foo       bar)&lt;/code&gt; are identical as soon as Scheme starts interpreting them. At present I
am relying on Guile's &amp;quot;pretty-printer&amp;quot; to do the heavy lifting, but
ideally I'd come up with a mechanism that let's me preserve the input
format. This approach also does not allow for comments.&lt;/p&gt;&lt;p&gt;We can work around these issues by performing &lt;a href=&quot;https://www.gnu.org/software/guile/manual/html_node/Fly-Evaluation.html&quot;&gt;Fly Evaluation&lt;/a&gt; with eval-string instead of eval&lt;/p&gt;&lt;p&gt;&lt;div class=&quot;code-block-maybe-results&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;syntax-comment&quot;&gt;;ooooh a comment. Pretty.
&lt;/span&gt;   &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;Results:&lt;pre&gt;&lt;code&gt;2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;But the editing experience is... unpleasant. After all, we're no
longer writing code. Instead, we're writing a string of code,
stripping away all of our fancy editing tools. This kind of defeats
the entire goal of &amp;quot;code as data&amp;quot;. Perhaps this can be made less
painful using Skribe instead of raw SXML, but in another post I will
instead try going down a different path; write a macro capable of
taking a raw, &amp;quot;unquoted&amp;quot; sexp and converting it into a string and
before calling&lt;code&gt;sxml-code-block&lt;/code&gt;. This shouldn't be &lt;i&gt;that hard&lt;/i&gt;... right?&lt;/p&gt;&lt;p&gt;One last tidbit for the road. As written, this awkward, not great
source block evaluator can work with other languages, just as long as
a Scheme evaluator function is written. As a very limited proof of
concept, here's some Ruby code.&lt;/p&gt;&lt;p&gt;&lt;div class=&quot;code-block-maybe-results&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Ah, General Kenobi. You are a bold one.&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;.upcase&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;Results:&lt;pre&gt;&lt;code&gt;AH, GENERAL KENOBI. YOU ARE A BOLD ONE.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;The code for this was:&lt;div class=&quot;code-block-maybe-results&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;eval-ruby&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;open-input-pipe&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;ruby -e '&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;'&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;read-line&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;close-pipe&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;sxml-code-block&lt;/span&gt;
   &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;puts \&amp;quot;Ah, General Kenobi. You are a bold one.\&amp;quot;.upcase&amp;quot;&lt;/span&gt;
   &lt;span class=&quot;syntax-keyword&quot;&gt;#:evaluator&lt;/span&gt;
   &lt;span class=&quot;syntax-symbol&quot;&gt;eval-ruby&lt;/span&gt;
   &lt;span class=&quot;syntax-keyword&quot;&gt;#:raw?&lt;/span&gt;
   &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;Now from here on out, every time I need to build my blog I will spin
up a Ruby VM just to capitalize a string. Do you think God stays in
heaven because he too lives in fear of what he's created?&lt;/p&gt;</content></entry><entry><title>Hello world from Guile Haunt!</title><id>https://freakingpenguin.com/blog/hello-world-from-guile-haunt.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2024-01-15T20:56:00Z</updated><link href="https://freakingpenguin.com/blog/hello-world-from-guile-haunt.html" rel="alternate" /><content type="html">&lt;p&gt;Hello world!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;something-bad?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;glyph-test?&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;You shouldn't have done that!&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;LaTeX math code using MathJax: \( sin (x) = \frac{y}{2a} \)&lt;/p&gt;&lt;p&gt;MathJax was removed since this post was written in favor of MathML.&lt;/p&gt;</content></entry><entry><title>stm8-card: Frame Buffers</title><id>https://freakingpenguin.com/blog/stm8-card-frame-buffers.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2021-06-24T17:30:00Z</updated><link href="https://freakingpenguin.com/blog/stm8-card-frame-buffers.html" rel="alternate" /><content type="html">&lt;h1&gt;Background&lt;/h1&gt;&lt;p&gt;I recently designed and fabricated a printed circuit board (PCB)
business card. I used a STM8S003F3 microcontroller along with a
SSD1306 display. This business card has my name, contact info, and
other information on a silkscreen layer. The microcontroller runs a
&amp;quot;space-invaders-esque&amp;quot; game, communicating with the display over I2C.&lt;/p&gt;&lt;p&gt;You can view the code and board files &lt;a href=&quot;https://gitlab.com/rjsent/stm8_card&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;h1&gt;The Problem&lt;/h1&gt;&lt;p&gt;The most natural way to control a display is to create what's called a
&lt;em&gt;frame buffer&lt;/em&gt;. We would allocate enough space in the microcontrollers
memory so that every pixel is 1 bit. Every time we want to change the
display, we can just set or reset bits in the frame buffer, and then
transmit the entire frame buffer.&lt;/p&gt;&lt;p&gt;However, eight bit microcontrollers are very resource limited. My display's
dimensions are 128x32, or 4096 pixels. If I used 1 bit to represent
each pixel, I will use 512 bytes of RAM. The microcontroller I'm
using has 1024 bytes.&lt;/p&gt;&lt;p&gt;This doesn't sound so bad, right? I have over twice the memory needed
for my frame buffer! Well, there's a &lt;em&gt;slight&lt;/em&gt; issue.&lt;/p&gt;&lt;p&gt;Of those 1024 bytes, 512 are reserved for the &lt;em&gt;stack&lt;/em&gt;. The stack keeps
track of where we are in the program, local variables that are in use,
and similar. As you might expect, that means the stack is
&lt;strong&gt;absolutely essential&lt;/strong&gt;. We obviously can't chop out the entire stack
for our frame buffer. It's possible to only store part of our frame
buffer where the stack is, but it's challenging to determine how much
of the stack is in use at any time. The stack could overwrite part of
our frame buffer as we jump between functions, which would corrupt our
display into a mess of pixels.&lt;/p&gt;&lt;p&gt;Okay, so we went from having 1024 bytes of memory in the microcontroller to 512.
That's still enough for our frame buffer, so what's the big deal?
Well, I need to store more stuff than just the frame buffer outside of
the stack. The space invaders code (&lt;code&gt;space_invaders.c&lt;/code&gt;) has several
&lt;em&gt;statically allocated&lt;/em&gt; variables. That means these variables are not
stored in the stack, but in that 512 bytes area. (It works out to
about 176 bytes.)&lt;/p&gt;&lt;p&gt;Now we're down to 336 bytes, which somehow needs to represent 512
bytes of data. Sounds like a problem, doesn't it?&lt;/p&gt;&lt;h1&gt;Making due with less, drawing a display without a complete frame buffer&lt;/h1&gt;&lt;p&gt;So creating a 512 byte frame buffer is a bust. Fortunately though,
there are some ways I could work around this! One option, and the one
I went with, was to only draw half the display at a time! I
created a function in &lt;code&gt;ssd1306.h&lt;/code&gt; with the following signature.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-comment&quot;&gt;/* I dunno if an enum is the best way to do this, but I'm doing it! */&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;ssd1306_side_t&lt;/span&gt;;
  &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;
  &lt;span class=&quot;syntax-comment&quot;&gt;/* Draw the frame buffer to the selected side */&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;draw_half&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ssd1306_side_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's take a look at how ~draw_half()~ works, shall we?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;draw_half&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;ssd1306_side_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;change_start_right&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;CONTROL_BYTE&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;CO_DATA&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;DC_COMMAND&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;,
      &lt;span class=&quot;syntax-symbol&quot;&gt;CMD_ADDR_COL&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;SSD1306_WIDTH&lt;/span&gt; / &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;SSD1306_WIDTH&lt;/span&gt; - &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;,
      &lt;span class=&quot;syntax-symbol&quot;&gt;CMD_ADDR_PAGE&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;change_start_left&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;CONTROL_BYTE&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;CO_DATA&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;DC_COMMAND&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;,
      &lt;span class=&quot;syntax-symbol&quot;&gt;CMD_ADDR_COL&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;SSD1306_WIDTH&lt;/span&gt; / &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt; - &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;,
      &lt;span class=&quot;syntax-symbol&quot;&gt;CMD_ADDR_PAGE&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;err&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;err&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;send_data&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;change_start_right&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;change_start_right&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;syntax-special&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;change_start_right&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;syntax-symbol&quot;&gt;err&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;send_data&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;change_start_left&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;change_start_left&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;syntax-special&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;change_start_left&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;err&lt;/span&gt; != &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;err&lt;/span&gt;;

    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_frame_buffer&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I have two arrays with 7 bytes of data in them called
&lt;code&gt;change_start_right&lt;/code&gt; and &lt;code&gt;change_start_left&lt;/code&gt;. When &lt;code&gt;draw_half(LEFT)&lt;/code&gt;
is called, I send &lt;code&gt;change_start_left&lt;/code&gt; to the display, and vice versa.
[fn:4:That &lt;code&gt;sizeof&lt;/code&gt; nonsense lets me add and remove elements to
&lt;code&gt;change_start_*&lt;/code&gt; without needing to change the second argument to
&lt;code&gt;send_data()&lt;/code&gt;.] When &lt;code&gt;change_start_left&lt;/code&gt; is sent, the pixel
addressing looks like&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/stm8-card-addressing-left.png&quot; alt=&quot;left half&quot; /&gt;&lt;/p&gt;&lt;p&gt;and when &lt;code&gt;change_start_right&lt;/code&gt; is sent&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/stm8-card-addressing-right.png&quot; alt=&quot;right half&quot; /&gt;&lt;/p&gt;&lt;p&gt;Obviously this is a little scaled down compared to a 128x32 pixel
display, but it illustrates the point. The first bit of my frame
buffer is sent to the top left of the half we are on, then we move
across horizontally until reaching the halfway point. We then jump
down a row and repeat!&lt;/p&gt;&lt;p&gt;For completeness, &lt;code&gt;draw_frame_buffer()&lt;/code&gt; looks like&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;control_byte&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;frame_buffer&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;BUF_SIZE&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;SSD1306_Data&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;control_byte&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;CONTROL_BYTE&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;CO_DATA&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;DC_DATA&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
  &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;draw_frame_buffer&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;send_data&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;SSD1306_Data&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;control_byte&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Every transmission needs to start with a control byte. I can't start a
transmission, send a control byte, stop it, start a new one, and send
the frame buffer. It needs to be one continuous message.
&lt;code&gt;send_bytes()&lt;/code&gt; (which is just a wrapper for &lt;code&gt;i2c_send_bytes()&lt;/code&gt;) takes
an array of data and a size, and will just send that array over. In
other words, I can't tell &lt;code&gt;i2c_send_bytes()&lt;/code&gt; &amp;quot;Hey, send this byte
first, then send these 256 bytes&amp;quot;.&lt;/p&gt;&lt;p&gt;I could make &lt;code&gt;frame_buffer&lt;/code&gt; a 257 byte array, and remember that the
first byte represents the control byte, not pixels. This is an ugly
solution in my eyes and will complicate later code. Instead,
remembering that an array is just a block of continuous memory, I
found a second solution. I created a structure with the control byte
first, followed by the frame buffer. The elements in a structure are
continuous [fn:5:Sorta. There is something called structure &amp;quot;padding&amp;quot;.
However, since I'm dealing with 8 bit data in an 8 bit
microcontroller, it's not an issue. Even if that wasn't enough, the
fact that everything is 8 bits or an array of 8 bit elements, padding
won't be added. &lt;em&gt;Technically&lt;/em&gt; though I don't know if the C standard
guarantees this. Some compilers support structure &amp;quot;packing&amp;quot; with a
compile-time flag, which is guaranteed to prevent this issue. I am
using SDCC, which does not.], so to &lt;code&gt;send_bytes()&lt;/code&gt;, this is just a 257
byte array.&lt;/p&gt;&lt;h1&gt;Manipulating the frame buffer: drawing images&lt;/h1&gt;&lt;p&gt;We're almost done here. There's just one element missing. If I had a
512 byte frame buffer, I could easily draw an image (e.g. a spaceship)
by going to the x and y coordinates in the frame buffer, then drawing
the pixels.&lt;/p&gt;&lt;h2&gt;Representing images with structs&lt;/h2&gt;&lt;p&gt;I chose to use two different structs to represent images.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-keyword&quot;&gt;#define&lt;/span&gt; MAX_FRAMES    (4) /* up to 4 frames of animation */
  &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;height&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;uint8_t&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;pixels&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;

  &lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;DrawableImage&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;state&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;Image&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;images&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;MAX_FRAMES&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;Image&lt;/code&gt;  is a struct that contains the raw data of the image, along
with the dimensions so it is drawn properly. For instance, if I want
to represent&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/stm8-card-image-struct.png&quot; alt=&quot;spaceship&quot; /&gt;&lt;/p&gt;&lt;p&gt;as a struct, I would write&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;spaceship_pixels&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x21&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x00&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x00&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x41&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x80&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x00&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x21&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xC1&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xC0&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x8F&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xFF&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xFF&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x0F&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xFF&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xFF&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x81&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xC1&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0xC0&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x41&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x80&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x00&lt;/span&gt;,
    &lt;span class=&quot;syntax-symbol&quot;&gt;0x61&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x00&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;0x00&lt;/span&gt;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;

  &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;spaceship_image&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    .&lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;24&lt;/span&gt;, .&lt;span class=&quot;syntax-symbol&quot;&gt;height&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;8&lt;/span&gt;, .&lt;span class=&quot;syntax-symbol&quot;&gt;pixels&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;spaceship_pixels&lt;/span&gt;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This pixels array goes from the top left pixel of the image (red
square), left to right, marking which pixels need to be on. &lt;code&gt;0x21&lt;/code&gt;
means the 3rd pixel &lt;code&gt;0b0010&lt;/code&gt; and the 8th pixel &lt;code&gt;0b0001&lt;/code&gt; are both lit,
while the rest of that row is off. Because I include the width and
height, I know when I need to wrap around to the next row, as well as
how many rows there are in total. (In theory I could remove &lt;code&gt;height&lt;/code&gt;
as the pixel array length + width can be used to calculate the height.
&lt;code&gt;height = sizeof(spaceship_pixels) / (width/8)&lt;/code&gt;)&lt;/p&gt;&lt;p&gt;This &lt;code&gt;spaceship_image&lt;/code&gt; variable contains everything I need to know
about the image itself. Because I separated &lt;code&gt;Image&lt;/code&gt; and
&lt;code&gt;DrawableImage&lt;/code&gt;, I can declare my &lt;code&gt;Image&lt;/code&gt; structs as &lt;code&gt;const&lt;/code&gt;. This
means the array of pixels, width, and height are all stored in program
(flash) memory, not RAM. Otherwise, I'd be very limited after using
257 bytes for my frame buffer and 512 bytes for the stack, with only
255 bytes left for everything else.&lt;/p&gt;&lt;p&gt;By doing so, the &lt;code&gt;DrawableImage&lt;/code&gt; struct has to contain a pointer to
the &lt;code&gt;Image&lt;/code&gt; struct, as they are in different locations in memory. I
also want my images to be animated, so I have an array of pointers to
&lt;code&gt;Image&lt;/code&gt; structs. That's what &lt;code&gt;const struct Image *images[MAX_FRAMES];&lt;/code&gt;
means. &lt;code&gt;images&lt;/code&gt; is an array of pointers to const Image structures.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; fields of the &lt;code&gt;DrawableImage&lt;/code&gt; structure tell us the
coordinates of the top left pixel of the display. &lt;code&gt;state&lt;/code&gt; is the frame
of animation we're on. Every time we want to move the image to a new
frame, all we have to do is increment &lt;code&gt;state&lt;/code&gt;, while ensuring it's a
valid number.&lt;/p&gt;&lt;h2&gt;Using these structs to draw on the display&lt;/h2&gt;&lt;p&gt;So, hopefully now we understand how I represent images using two
separate structures. By doing so, I can combine related data together,
hopefully making it easier to actually draw them on the display. I
want to have a method called &lt;code&gt;draw_image()&lt;/code&gt; in &lt;code&gt;ssd1306.c/h&lt;/code&gt; that
takes a &lt;code&gt;DrawableImage&lt;/code&gt; structure, then modifies the frame buffer so
that the correct pixels are lit up. The next time the frame buffer is
transmitted, the display should update accordingly.&lt;/p&gt;&lt;p&gt;Because my frame buffer is split in half, there's one other thing that
I need to pass &lt;code&gt;draw_image()&lt;/code&gt;. The &lt;code&gt;DrawableImage&lt;/code&gt; can be located
anywhere on the display, on either half. If I am going to use the
frame buffer to update the left half of the display, and I send a
&lt;code&gt;DrawableImage&lt;/code&gt; that's located on the right half, nothing should
update. If the &lt;code&gt;DrawableImage&lt;/code&gt; is in between the two halves, only part
of it should be drawn. Therefore I have a second argument called &lt;code&gt;side&lt;/code&gt; that
tells &lt;code&gt;draw_image()&lt;/code&gt; how the &lt;code&gt;DrawableImage&lt;/code&gt; should be drawn depending
on which half we're on. (e.g. If the &lt;code&gt;DrawableImage&lt;/code&gt; is on the left half
but &lt;code&gt;side&lt;/code&gt; says &lt;code&gt;RIGHT&lt;/code&gt;, don't change any pixels in the frame buffer!)&lt;/p&gt;&lt;h3&gt;Breaking apart &lt;code&gt;draw_image()&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;Here's the first few lines of code of &lt;code&gt;draw_image()&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-comment&quot;&gt;/* in ssd1306.h */&lt;/span&gt;
  &lt;span class=&quot;syntax-keyword&quot;&gt;#define&lt;/span&gt; REDRAW_OTHER_HALF                         (1)
  &lt;span class=&quot;syntax-comment&quot;&gt;/* in ssd1306.c */&lt;/span&gt;

  &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;DrawableImage&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;ssd1306_side_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; -&lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;images&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt;;
    &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;need_redraw&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;;                                         &lt;span class=&quot;syntax-comment&quot;&gt;/* flag for if any pixels outside bounds of buffer */&lt;/span&gt;
    &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First, we perform a simple check to help verify that the &lt;code&gt;DrawableImage&lt;/code&gt; is
valid. If we did not perform this check, we'd be drawing garbage on
the screen! This actually was a big issue for several days that wasn't
immediately obvious. I changed an unrelated part of my code to return
&lt;code&gt;NULL&lt;/code&gt; under certain conditions, but wasn't checking if the image was
&lt;code&gt;NULL&lt;/code&gt; when calling &lt;code&gt;draw_image()&lt;/code&gt;. This is what that looked like.&lt;/p&gt;&lt;p&gt;&lt;video src=&quot;/static/videos/stm8_card_null_pointer_glich_157fd06.mp4&quot; controls=&quot;true&quot; alt=&quot;video&quot;&gt;&lt;/video&gt;&lt;/p&gt;&lt;p&gt;I declare two variables, &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;need_redraw&lt;/code&gt;. &lt;code&gt;width&lt;/code&gt; is just a
shorthand so I don't need to write
&lt;code&gt;image-&amp;gt;images[image-&amp;gt;state]-&amp;gt;width&lt;/code&gt; every time. (This monstrosity
means &amp;quot;go to the &lt;code&gt;DrawableImage&lt;/code&gt; struct pointed to by the &lt;code&gt;image&lt;/code&gt;
pointer, get the &lt;code&gt;Image&lt;/code&gt; structure for the current frame of animation
we're on, then get the &lt;code&gt;width&lt;/code&gt; of that &lt;code&gt;Image&lt;/code&gt; structure).&lt;/p&gt;&lt;p&gt;&lt;code&gt;need_redraw&lt;/code&gt; is a flag variable. If the image we're drawing is
partially or fully on the other half of the screen, it will be set to
&lt;code&gt;REDRAW_OTHER_HALF&lt;/code&gt;, telling whatever function called this one &amp;quot;Hey,
this &lt;code&gt;DrawableImage&lt;/code&gt; needs to be drawn again later&amp;quot;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-comment&quot;&gt;/* don't waste time drawing images that don't appear */&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;LEFT&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; &amp;gt; &lt;span class=&quot;syntax-symbol&quot;&gt;BUF_WIDTH&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;need_redraw&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; + &lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt; &amp;lt; &lt;span class=&quot;syntax-symbol&quot;&gt;BUF_WIDTH&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;need_redraw&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we're on the left half of the screen and the x coordinate of the
top left of our image is greater than the halfway coordinate of our display,
then we need to draw the image again! Remember, the coordinates tell
us the location of the top left pixel of the &lt;code&gt;DrawableImage&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;There's actually a bug here at the time of this writing. I need to
return &lt;code&gt;REDRAW_OTHER_HALF&lt;/code&gt; (if I want the code to exit immediately).
As &lt;code&gt;need_redraw&lt;/code&gt; was not set yet, I am returning &lt;code&gt;0&lt;/code&gt;, meaning
the image does not need to be redrawn!&lt;/p&gt;&lt;h3&gt;The really ugly part of &lt;code&gt;draw_image()&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;Heads up. This next part is a doozy comparatively.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;images&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;height&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;++&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-special&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;j&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;j&lt;/span&gt; &amp;lt; &lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;j&lt;/span&gt;++&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We have two nested for loops that will iterate through the pixels of
the &lt;code&gt;Image&lt;/code&gt;. Unfortunately, because this is C, there's no concept of a
&lt;code&gt;Pixel&lt;/code&gt; type. I need to use as little storage as possible, so I have
my pixels represented as an array of 8-bit characters.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;subscript&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt; + &lt;span class=&quot;syntax-symbol&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; / &lt;span class=&quot;syntax-symbol&quot;&gt;8&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bit_num&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;7&lt;/span&gt; - &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;width&lt;/span&gt; + &lt;span class=&quot;syntax-symbol&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; % &lt;span class=&quot;syntax-symbol&quot;&gt;8&lt;/span&gt;;
  &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;subscript&lt;/code&gt; tells me which 8-bit sequence will contain the pixel I
need. Similarly, &lt;code&gt;bit_num&lt;/code&gt; is the number of the specific bit within
the bit. For example, &lt;code&gt;subscript = 2&lt;/code&gt; and &lt;code&gt;bit_num = 3&lt;/code&gt; means I will
be looking at the 4th bit within the 3rd byte. By looking at this bit,
I'll know if the pixel should be on or off.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;images&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;pixels&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;subscript&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; &amp;amp; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bit_num&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; != &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that's exactly what I do! I access the pixel data through a fairly
obtuse chain of arrow (&lt;code&gt;-&amp;gt;&lt;/code&gt;) operators, testing if the specific bit is
high or low. If it is high, I continue.&lt;/p&gt;&lt;p&gt;Technically, I could &lt;code&gt;clear&lt;/code&gt; the pixel if it is zero. This would prevent
images from overlapping, which I don't want.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;signed&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;xcord&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt; + &lt;span class=&quot;syntax-symbol&quot;&gt;j&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;ycord&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;image&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;y&lt;/span&gt; + &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;;
  &lt;span class=&quot;syntax-comment&quot;&gt;/* ... */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After that, I need to generate the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; coordinates to place
the pixel. Because I already have the coordinate for the top left of
my image, I just need to add my &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; values to find the
coordinates of the pixel!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;side&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;xcord&lt;/span&gt; -= &lt;span class=&quot;syntax-symbol&quot;&gt;SSD1306_WIDTH&lt;/span&gt; / &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There's one last small adjustment I need to make. My frame buffer is
half the width of the display. (64x32 instead of 128x32). If I want to
draw on the right half of the display and try using the x coordinate
without modifying it, I'll be attempting to draw a pixel outside of my
frame buffer! So, I subtract 64 from the x coordinate if &lt;code&gt;side&lt;/code&gt; is
&lt;code&gt;RIGHT&lt;/code&gt;, protecting against this.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;draw_pixel&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;xcord&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;ycord&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;INVALID&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;need_redraw&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;REDRAW_OTHER_HALF&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Before returning &lt;code&gt;need_redraw&lt;/code&gt;, I have one final thing to do. Actually
updating the pixel in my frame buffer! In the interest of space, I
won't actually go into the details of how &lt;code&gt;draw_pixel()&lt;/code&gt; works.
Suffice to say that it takes a coordinate between &lt;code&gt;(0, 0)&lt;/code&gt; and &lt;code&gt;(63, 31)&lt;/code&gt;, toggling the correct bit in the frame buffer. If that coordinate
is invalid, it returns &lt;code&gt;INVALID&lt;/code&gt;. By checking the return value, I will
know if any coordinates of my image fall outside of that area,
suggesting it is either corrupt or—more likely—on the other half of
the screen, meaning the image needs to be redrawn to fully appear on
the display.&lt;/p&gt;&lt;h1&gt;Using &lt;code&gt;draw_image()&lt;/code&gt; and pals to draw on a display&lt;/h1&gt;&lt;p&gt;By this point, you are probably confused as to how this code actually
works. I talked a lot about drawing and redrawing the display.
Hopefullly a brief example of using these methods will help. Here is a
modified snippet of code in my &lt;code&gt;main()&lt;/code&gt; method that is run in an
infinite loop.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;syntax-special&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span class=&quot;syntax-symbol&quot;&gt;3&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;++&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;lasers&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;debug_drawableimage_playerlaser&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;invader_lasers&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;debug_drawableimage_invaderlaser&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;invaders&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;debug_drawableimage_invader&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;lasers&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;invader_lasers&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;invaders&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;draw_half&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;clear_buffer&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span class=&quot;syntax-symbol&quot;&gt;3&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;++&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;lasers&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;invader_lasers&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;draw_image&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;invaders&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;draw_half&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;RIGHT&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;clear_buffer&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;lasers[]&lt;/code&gt;, &lt;code&gt;invader_lasers[]&lt;/code&gt;, and &lt;code&gt;invaders[]&lt;/code&gt;
are all arrays of 3 &lt;code&gt;DrawableImages&lt;/code&gt;. First, I update the
&lt;code&gt;DrawableImage&lt;/code&gt; to the most recent ones reported by my Space Invaders
game. How Space Invaders creates these &lt;code&gt;DrawableImages&lt;/code&gt; is not really
relevent right now.&lt;/p&gt;&lt;p&gt;I then attempt to draw the images on the left half of the screen. Some
of these &lt;code&gt;DrawableImages&lt;/code&gt; will not be drawn because they are on the
right. This is totally fine! &lt;code&gt;draw_image()&lt;/code&gt; does nothing in that case.&lt;/p&gt;&lt;p&gt;&lt;code&gt;draw_half()&lt;/code&gt; will take the contents of the frame buffer, and send
that information to the display. This is what physically causes the
display to update, showing the new pixels on the screen. I then clear
the buffer to all zeroes so that the left half will not overlap with
the right half.&lt;/p&gt;&lt;p&gt;This entire process is repeated on the right half.&lt;/p&gt;&lt;p&gt;Here's the final result!&lt;/p&gt;&lt;p&gt;&lt;video src=&quot;/static/videos/stm8_card_mostly_done.webm&quot; controls=&quot;true&quot; alt=&quot;final result business card&quot;&gt;&lt;/video&gt;&lt;/p&gt;</content></entry><entry><title>Circular pointers in C</title><id>https://freakingpenguin.com/blog/circular-pointers-in-c.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2021-04-15T12:35:00Z</updated><link href="https://freakingpenguin.com/blog/circular-pointers-in-c.html" rel="alternate" /><content type="html">&lt;h1&gt;What is a circular pointer?&lt;/h1&gt;&lt;p&gt;Full disclosure, I almost cannot think of any practical value to this
post. It's provided also entirely as a &amp;quot;Huh, that's a weird thing you
can do in C&amp;quot;, rather than an actually useful technique. The only
purpose I can see is to use them for a circularly linked list with one
element. There may be another term that's in use, but I do not know
what it is.&lt;/p&gt;&lt;p&gt;A circular pointer is a pointer that, well, points to itself! No
matter how many times we dereference that pointer, we should still be
at the same spot. For example,&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/charts/mermaid-circular-pointer-example.png&quot; alt=&quot;mermaid diagram&quot; /&gt;&lt;/p&gt;&lt;p&gt;Another way to think about it is &lt;code&gt;****p == p&lt;/code&gt;. Let's try to think of
some ways to implement this!&lt;/p&gt;&lt;h1&gt;Failed Attempt&lt;/h1&gt;&lt;p&gt;The first thought that might come to our mind might be something like
what's below. Because (spoilers) this code seg faults, I wrote a
signal handler so we still see some kind of results.&lt;/p&gt;&lt;p&gt;Calling most library functions in signal handlers is a bad idea, so
I'm using the &lt;code&gt;write()&lt;/code&gt; system call. Headers are excluded for
compactness. I'm using &lt;code&gt;fflush()&lt;/code&gt; as &lt;code&gt;printf()&lt;/code&gt; buffers its output.
Otherwise, the first &lt;code&gt;printf()&lt;/code&gt; will not appear. Lastly, even though
an error occurs, I'm exiting with a zero exit code because of
=org-babel= limitations. You can find out more about this in [*Crash
and burn programming](this post).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  void segfault(int sig_num) {
    fflush(stdout);
    write(STDOUT_FILENO, &amp;quot;Segfault!\n&amp;quot;, 9);
    _exit(0);
  }

  int main(void) {
    signal(SIGSEGV, segfault);
    int *p;
    printf(&amp;quot;p 0x%x\n&amp;quot;, p);
    ,*p = p; /* segfault occurs here */
    printf(&amp;quot;****p %x&amp;quot;, ****(int ****)p);
  }&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;#+RESULTS:
: p 0x0
: Segfault!&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we walk through the code, we can figure out the problem. We
allocate space for an integer pointer p, which contains 0. We then
attempt to store the value in p, 0, in the value pointed to by p, 0.
In other words, we're attempting to dereference a &lt;code&gt;NULL&lt;/code&gt; pointer,
causing a seg fault.&lt;/p&gt;&lt;h1&gt;Some background&lt;/h1&gt;&lt;p&gt;Okay, so all we need to do is &lt;code&gt;malloc()&lt;/code&gt; space for the pointer p to
point to. Easy, right? Before we get to that though, there's a few
things we have to keep in mind.&lt;/p&gt;&lt;h2&gt;Malloc with multiple levels of pointers&lt;/h2&gt;&lt;p&gt;First, we need to be careful
allocating space for variables when using multiple levels of pointers.
For example,&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int **p = malloc(sizeof (int));
  ,**p = 1;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will seg fault! p is a pointer to a pointer containing an int. When we
malloc memory, malloc will return a pointer to a block of memory large
enough to contain an int. If we type &lt;code&gt;**p&lt;/code&gt;, we're saying &amp;quot;Go to the
malloced block, then go to where the malloced block is pointing at
and set that block to 1&amp;quot;. Because &lt;code&gt;malloc()&lt;/code&gt;'d memory can be anything,
we are accessing memory at random! This is an easy recipe for a seg
fault. One way to fix this is to use multiple variables, for
instance...&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int *p1  = malloc(sizeof (int));
  int **p2 = &amp;amp;p1;
  ,**p2    = 7;
  printf(&amp;quot;***p2 %d&amp;quot;, **p2);&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;#+RESULTS:
: ***p2 7&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Compile time errors dereferencing pointers&lt;/h2&gt;&lt;p&gt;Next up, if we have &lt;code&gt;int *p&lt;/code&gt;, then &lt;code&gt;p&lt;/code&gt; is an &lt;code&gt;int *&lt;/code&gt;. If we try to do &lt;code&gt;**p&lt;/code&gt;, our
compiler will complain about an invalid type argument and fail to compile. You can't
dereference an &lt;code&gt;int *&lt;/code&gt; two times!&lt;/p&gt;&lt;p&gt;The compiler helpfully assumes that you would never dereference a
pointer more than the number of pointers you have. In other words,&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int *p = malloc(sizeof (int));
  printf(&amp;quot;*p1 %d\n&amp;quot;, *p);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will compile, but&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int *p  = malloc(sizeof (int));
  printf(&amp;quot;**p1 %d\n&amp;quot;, **p);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will not compile. The compiler sees that *p1 is an int pointer, so it
knows &lt;code&gt;**p&lt;/code&gt; is always invalid. If we pretend seg faults don't exist
for a second, we can fix this issue using casts! A cast tells the
compiler &amp;quot;Hey, I know that &lt;code&gt;p&lt;/code&gt; is an integer pointer, but I need you
to treat this as another type for right now&amp;quot;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int *p  = malloc(sizeof (int));
  printf(&amp;quot;**p %l&amp;quot;, **(int **)p);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case, we're saying &amp;quot;Hey, you know that integer pointer p?
Let's treat it as pointer to a pointer to an integer for right now&amp;quot;.&lt;/p&gt;&lt;h2&gt;&lt;code&gt;sizeof (int *)&lt;/code&gt; vs &lt;code&gt;sizeof (int)&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;The last thing to remember deals with sizes. In 64-bit systems, a
pointer is 64-bits long, regardless of the type it points to. &lt;code&gt;sizeof int* == sizeof char* =​= sizeof double** =​= 8&lt;/code&gt;. Using what we've
learned so far, let's say we have the following code block.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int *p = malloc(sizeof (int));
  ,*p = (int)p;
  printf(&amp;quot;**p %d&amp;quot;, **(int **)p);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We've managed to get everything right! Except for one little part.
&lt;code&gt;*p&lt;/code&gt; is an integer, not an integer pointer. We store the integer
pointer &lt;code&gt;p&lt;/code&gt; in &lt;code&gt;*p&lt;/code&gt;. Because &lt;code&gt;sizeof (int *) =​= 8&lt;/code&gt; and &lt;code&gt;sizeof (int) == 4&lt;/code&gt; (on my machine), part of the pointer is chopped off! &lt;code&gt;p&lt;/code&gt; needs
to point to a type that is the same size (or larger) than an integer
pointer.[fn:2:Or any non-function pointer. There is no guarantee that
a function pointer is the same size as a integer/double/etc pointer,
and they're more of a abstraction that exists in our code than
something that's really &amp;quot;there&amp;quot;, like integers in memory.]&lt;/p&gt;&lt;p&gt;The C standard actually includes an integer type that is guaranteed to
be the same size as a pointer, the signed &lt;code&gt;intptr_t&lt;/code&gt; or unsigned
&lt;code&gt;uintptr_t&lt;/code&gt; types defined in =stdint.h=. I'll stay away from these
since I'm worried it'll make it a bit more confusing.&lt;/p&gt;&lt;p&gt;Time to put all of this into the most pointless (HAHAHAHAHA) practice
imaginable.&lt;/p&gt;&lt;h1&gt;Circular pointers with &lt;code&gt;malloc()&lt;/code&gt;!&lt;/h1&gt;&lt;p&gt;Let's take what we've learned and try to create a pointer that points
to itself, and one where we can dereference it as many times as we want!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int main(void) {
    long *p = malloc(sizeof (long *));
    ,*p = (long)p;  /* cast isn't required here */
    printf(&amp;quot;p    0x%lx\n&amp;quot;,  p);
    printf(&amp;quot;*p   0x%lx\n&amp;quot;,  *p);
    printf(&amp;quot;**p  0x%lx\n&amp;quot;,  **(long **)p);
    printf(&amp;quot;***p 0x%lx\n&amp;quot;,  ***(long ***)p);
  }&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;#+RESULTS:
| p    | 0x558366a4c2a0 |
| *p   | 0x558366a4c2a0 |
| **p  | 0x558366a4c2a0 |
| ***p | 0x558366a4c2a0 |&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Look at that! We've successfully created a pointer that points to
itself! No matter how many times we dereference it, we are still
looking at the same pointer.&lt;/p&gt;&lt;p&gt;For fun, let's create a loop so we can deference the pointer as many
times as we want very easily.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  int main() {
    long *p = malloc(sizeof (long *));
    ,*p = (long)p;
    for (int i = 0; i &amp;lt; 5; i++) {
      long ptemp = *p;
      printf(&amp;quot;%d 0x%lx\n&amp;quot;, i, *p);
      p = (long *)ptemp;
    }
  }&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;| i |    dereference |
|---+----------------|
| 0 | 0x55ffc15d32a0 |
| 1 | 0x55ffc15d32a0 |
| 2 | 0x55ffc15d32a0 |
| 3 | 0x55ffc15d32a0 |
| 4 | 0x55ffc15d32a0 |&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And there we go. This is one option for how we can implement a pointer
that points to itself, no matter how many times we dereference it. If
we wanted to, we add more pointers, creating a circularly linked list
that looks like&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/charts/mermaid-circular-pointer-list-example.png&quot; alt=&quot;mermaid diagram&quot; /&gt;&lt;/p&gt;&lt;h1&gt;Circular pointers with structs!&lt;/h1&gt;&lt;p&gt;Another option that saves us from all this casting is to use structs.
Because a struct can contain anything[fn:3:Except for a struct
containing itself directly.], even a pointer to a struct of
the same type, we can do the following.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  struct p_self {
    struct p_self *p;
    int magic;
  };

  int main() {
    struct p_self p = { .p = &amp;amp;p, .magic = 4032 };
    printf(&amp;quot;magic %d&amp;quot;, p.p-&amp;gt;p-&amp;gt;p-&amp;gt;p-&amp;gt;p-&amp;gt;magic);
  }&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;#+RESULTS:
: magic 4032&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To my knowledge, we can't make &lt;code&gt;p&lt;/code&gt; a pointer to a struct very
compactly. If we create a compound literal like&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  struct p_self *p = &amp;amp;(struct p_self){ .p = /* problem */, .magic = 4032 };&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;we have a problem. The compound literal needs to contain a field that
contains it's own address. I don't believe it is possible to do this,
as there's no way to refer to the compound literal we are inside of.
(This could be avoided by not using compound literals and introducing
a second variable, but I'd rather not.)&lt;/p&gt;&lt;p&gt;Regardless, what we can conclude from this is that pointers are weird
and confusing and there's many little ways to mess up, especially as
we do increasingly weird stuff with them. But it's fun!&lt;/p&gt;</content></entry><entry><title>Fourier Part 2: Integrating a discontinuous function</title><id>https://freakingpenguin.com/blog/fourier-part-2-integrating-a-discontinuous-function.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2021-04-10T00:00:00Z</updated><link href="https://freakingpenguin.com/blog/fourier-part-2-integrating-a-discontinuous-function.html" rel="alternate" /><content type="html">&lt;h1&gt;Checking if &lt;code&gt;gsl_integration_qng()&lt;/code&gt; will work&lt;/h1&gt;&lt;p&gt;At the end of &lt;a href=&quot;https://www.freakingpenguin.com/blog/fourier-part-1-what-is-a-fourier-series.html&quot;&gt;part 1&lt;/a&gt;, I suggested
that &lt;code&gt;gsl_integration_qng()&lt;/code&gt; would not be able to successfully
integrate the function we want to find the Fourier series of. Here is
the function I will find the Fourier series of.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-fourier-function-orig.png&quot; alt=&quot;A graph showing a sawtooth wave function with discontinuous jumps
between teeth. Similar in shape to a series of forward slashes.&quot; /&gt;&lt;/p&gt;&lt;p&gt;Because this function is discontinuous, we have to approximate it with
a Fourier series instead of a Taylor series. If we recall the formulas
shown in the last part, we know that we will have to integrate &lt;math display=&quot;inline&quot; alttext=&quot;f(x)&quot;&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt; from &lt;math display=&quot;inline&quot; alttext=&quot;0&quot;&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/math&gt; to &lt;math display=&quot;inline&quot; alttext=&quot;2l&quot;&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt;, among other things. Before calculating the
Fourier series, let's try using &lt;code&gt;gsl_integration_qng()&lt;/code&gt; to perform
basic integration.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;stdio.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;math.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;gsl/gsl_integration.h&amp;gt;

&lt;span class=&quot;syntax-comment&quot;&gt;/* f(x) = x for 0 &amp;lt;= x &amp;lt; 4, repeating */&lt;/span&gt;
&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;4&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;fmod&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;8&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_function&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;function&lt;/span&gt; = &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;num_evals&lt;/span&gt;;

  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_qng&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;,
      		&lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt;,
      		&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;, &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;num_evals&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;result error num_evals\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;%f %f %zu\n&amp;quot;&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;num_evals&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;|    result |    error | num_evals |
| 14.804436 | 8.015135 |        21 |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Well, something happened here, but it's not quite what we wanted. We
told &lt;code&gt;GSL&lt;/code&gt; to take gsl_integral-i. Since we're dealing with a
discontinuous function, we can rewrite this as gsl-integral-rewrite-i. Now I'm no mathematician, but this answer should be
16, not 14.8. Additionally, our error is very large, and if I attempt
to lower &lt;code&gt;err_rel&lt;/code&gt; to a smaller value, &lt;code&gt;GSL&lt;/code&gt; yells at me saying that
it failed to reach the requested error.&lt;/p&gt;&lt;p&gt;This is not a problem on &lt;code&gt;GSL&lt;/code&gt;'s end. We aren't using the right
integration function for the job! According to the &lt;code&gt;GSL&lt;/code&gt; manual,&lt;/p&gt;&lt;blockquote&gt;The QNG algorithm is a non-adaptive procedure which uses fixed
Gauss-Kronrod-Patterson abscissae to sample the integrand at a maximum
of 87 points. It is provided for fast integration of smooth functions.
&lt;/blockquote&gt;&lt;p&gt;While that's a lot of words, the important part is the last sentence. &lt;code&gt;gsl_integration_qng()&lt;/code&gt; is for smooth functions. Our function is not smooth, it has a discontinuity! We will need to find an alternative
function in &lt;code&gt;GSL&lt;/code&gt; that can handle discontinuous graphs.&lt;/p&gt;&lt;aside&gt;&lt;p&gt;Strictly speaking, this isn't actually true. Because the discontinuity occurs
at the limits of integration for our function (as long as we only integrate
from 0 to 4), we can use &lt;code&gt;gsl_integration_qng()&lt;/code&gt;. Not all functions
are like this, so it's still best to find an alternative.&lt;/p&gt;&lt;/aside&gt;&lt;h1&gt;&lt;code&gt;gsl_integration_qng()&lt;/code&gt; and discontinuities&lt;/h1&gt;&lt;p&gt;Fortunately we do not have to look far. The very next function
mentioned in the
&lt;a href=&quot;https://www.gnu.org/software/gsl/doc/html/integration.html&quot;&gt;manual&lt;/a&gt; is what we need. &lt;code&gt;gsl_integration_qag()&lt;/code&gt; has the following signature.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_qag&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_function&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;,
            &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;b&lt;/span&gt;,
            &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;epsabs&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;epsrel&lt;/span&gt;,
            &lt;span class=&quot;syntax-symbol&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;key&lt;/span&gt;,
            &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;workspace&lt;/span&gt;,
            &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;abserr&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;f&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;epsabs&lt;/code&gt;, &lt;code&gt;epsrel&lt;/code&gt;, &lt;code&gt;result&lt;/code&gt;, and &lt;code&gt;abserr&lt;/code&gt; are all the same as &lt;code&gt;gsl_integration_qng()&lt;/code&gt;. We can see that several
new terms are introduced however.&lt;/p&gt;&lt;p&gt;&lt;code&gt;workspace&lt;/code&gt; is a pointer to an area of memory used by &lt;code&gt;gsl_integration_qag&lt;/code&gt;. We allocate space by using the &lt;code&gt;gsl_integration_workspace_alloc()&lt;/code&gt; function, This function is passed
an integer to adjust how much memory we want to allocate. Whatever
integer we pass to &lt;code&gt;gsl_integration_workspace_alloc()&lt;/code&gt;we need to
ensure that &lt;code&gt;limit&lt;/code&gt; is the same. This way, &lt;code&gt;gsl_integration_qag&lt;/code&gt;
knows how much memory it has available.&lt;/p&gt;&lt;p&gt;&lt;code&gt;key&lt;/code&gt; is a integer between 0 through 6. &lt;code&gt;GSL&lt;/code&gt; recommends using higher values when integrating smooth
functions, and lower values when functions are discontinuous.
&lt;/p&gt;&lt;p&gt;Let's see how well &lt;code&gt;gsl_integration_qag()&lt;/code&gt; performs!
&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;stdio.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;math.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;gsl/gsl_integration.h&amp;gt;

&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;4&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;fmod&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1024&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;w&lt;/span&gt;
    = &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace_alloc&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;8&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_function&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;function&lt;/span&gt; = &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1e&lt;/span&gt;-&lt;span class=&quot;syntax-symbol&quot;&gt;7&lt;/span&gt;;

  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_qag&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;,
      		&lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt;,
      		&lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;w&lt;/span&gt;,
      		&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-comment&quot;&gt;/* get into the habit of freeing memory when done! */&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace_free&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;result error\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;%f %f\n&amp;quot;&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;| result | error |
|   16.0 |   0.0 |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Look at that! We are getting the exact value we expected, even though
we're integrating with a discontinuity. We are now at the point where
we can calculate the Fourier series for our function.
&lt;/p&gt;&lt;h1&gt;Generating our Fourier series&lt;/h1&gt;&lt;p&gt;Let's recall that we can find our &lt;math display=&quot;inline&quot; alttext=&quot;a_{n}&quot;&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; and &lt;math display=&quot;inline&quot; alttext=&quot;b_{n}&quot;&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; coefficients
with the following formulas.
&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;a_{n}=\frac{1}{l}\int_{0}^{2l}f(x)\cos(\frac{n\pi x}{l})dx&quot;&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;b_{n}=\frac{1}{l}\int_{0}^{2l}f(x)\sin(\frac{n\pi x}{l})dx&quot;&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;GSL&lt;/code&gt; expects us to only pass one function to it as an argument. That
means that, unlike before, we can't just pass a pointer to our function
&lt;code&gt;f(x)&lt;/code&gt;, as &lt;code&gt;GSL&lt;/code&gt; won't be multiplying it by the cosine and sine terms.&lt;/p&gt;&lt;p&gt;There are a couple of solutions to this that I can think of. The first
is to make use of the &lt;code&gt;void *&lt;/code&gt; argument that &lt;code&gt;GSL&lt;/code&gt; includes in the
&lt;code&gt;gsl_function&lt;/code&gt; structure. Using this, we could pass extra information
to &lt;code&gt;f(x)&lt;/code&gt;, adapting it to our specific n value.
&lt;/p&gt;&lt;p&gt;Alternatively, we could write a parent function, like &lt;code&gt;aorb_subn()&lt;/code&gt;. This
function would then be stored in the &lt;code&gt;gsl_function&lt;/code&gt; structure. The
advantage of this approach is that the function we want the Fourier
series of, &lt;code&gt;f(x)&lt;/code&gt;, is distinct in our code. This should make it a bit
easier to change &lt;code&gt;f(x)&lt;/code&gt; to any function that we want. This is the
approach that I will take. &lt;/p&gt;&lt;p&gt;To make this code hopefully a bit more modular, I moved the
integration out of main, and instead into a function called
&lt;code&gt;get_aorb_subn()&lt;/code&gt;. This function calculates the nth Fourier
coefficient for a function &lt;code&gt;f(x)&lt;/code&gt;, using the variable &lt;code&gt;get_a&lt;/code&gt; to
determine if it should calculate &lt;math display=&quot;inline&quot; alttext=&quot;a_{n}&quot;&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; or &lt;math display=&quot;inline&quot; alttext=&quot;b_{n}&quot;&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt;. It may be
better to wrap this in a &lt;code&gt;fourier&lt;/code&gt; structure that contains the two
terms, but I elected not to do that to hopefully maintain some vague
semblance of readability.&lt;/p&gt;&lt;p&gt;This is what the code to calculate the Fourier series looks like.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;stdbool.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;stdio.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;math.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;gsl/gsl_integration.h&amp;gt;

&lt;span class=&quot;syntax-keyword&quot;&gt;#define&lt;/span&gt; PI 3.14159
&lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;4&lt;/span&gt;;
&lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;l&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt; / &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;;

&lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;aorb_params&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;*&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;calc_a&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;

&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;fmod&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;aorb_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;aorb_params&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;trig&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;calc_a&lt;/span&gt; ? &lt;span class=&quot;syntax-symbol&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;PI&lt;/span&gt;*&lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt;*&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;/&lt;span class=&quot;syntax-symbol&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; : &lt;span class=&quot;syntax-symbol&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;PI&lt;/span&gt;*&lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt;*&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;/&lt;span class=&quot;syntax-symbol&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;-&amp;gt;&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;trig&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;get_aorb_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;*&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt;,
      	       &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;get_a&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;normalization&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;/&lt;span class=&quot;syntax-symbol&quot;&gt;l&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;get_a&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt; == &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;normalization&lt;/span&gt; /= &lt;span class=&quot;syntax-symbol&quot;&gt;2&lt;/span&gt;;

  &lt;span class=&quot;syntax-symbol&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1024&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;w&lt;/span&gt;
    = &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace_alloc&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_function&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt; .&lt;span class=&quot;syntax-symbol&quot;&gt;function&lt;/span&gt; = &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;aorb_subn&lt;/span&gt;,
    .&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt; = &amp;amp;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;aorb_params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt; .&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;, .&lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;n&lt;/span&gt;,
      		 .&lt;span class=&quot;syntax-symbol&quot;&gt;calc_a&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;get_a&lt;/span&gt; &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1e&lt;/span&gt;-&lt;span class=&quot;syntax-symbol&quot;&gt;7&lt;/span&gt;;

  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_qag&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;,
      		&lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt;,
      		&lt;span class=&quot;syntax-symbol&quot;&gt;limit&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;w&lt;/span&gt;,
      		&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_workspace_free&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;

  &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;normalization&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;upto&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;10&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;a_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;upto&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;b_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;upto&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;period&lt;/span&gt;;

  &lt;span class=&quot;syntax-special&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span class=&quot;syntax-symbol&quot;&gt;upto&lt;/span&gt;; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;++&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;a_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;get_aorb_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;b_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;get_aorb_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
    &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;%d %f %f\n&amp;quot;&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;a_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;b_subn&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;| n | a_subn |    b_subn |
|---+--------+-----------|
| 0 |    2.0 |       0.0 |
| 1 | -7e-06 | -1.273242 |
| 2 | -7e-06 | -0.636621 |
| 3 | -7e-06 | -0.424414 |
| 4 | -7e-06 |  -0.31831 |
| 5 | -7e-06 | -0.254648 |
| 6 | -7e-06 | -0.212207 |
| 7 | -7e-06 | -0.181892 |
| 8 | -7e-06 | -0.159155 |
| 9 | -7e-06 | -0.141471 |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Like I mentioned before, &lt;code&gt;aorb_subn&lt;/code&gt; is a &amp;quot;parent function&amp;quot; that
combines &lt;code&gt;f(x)&lt;/code&gt; and the sine/cosine term. This is the function we
integrate, and we provide it enough information to know what term we
are calculating.
&lt;/p&gt;&lt;p&gt;Interestingly, if we use the &lt;math display=&quot;inline&quot; alttext=&quot;\pi&quot;&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/math&gt; constant &lt;code&gt;M_PI&lt;/code&gt;, the integration
fails due to roundoff error. Fortunately we can get &amp;quot;close enough&amp;quot;
values by just using a few less digits.&lt;/p&gt;&lt;p&gt;Once we graph the Fourier series generated by these coefficients, this
is what we get.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-asubn-bsubn.png&quot; alt=&quot;A graph showing an approximation of a sawtooth function generated using a Fourier series.
The approximation is periodic.&quot; /&gt;&lt;/p&gt;&lt;p&gt;And there we are! Here is a Fourier series generated for a discontinuous
periodic function. The more terms we add, the more accurate the approximation.&lt;/p&gt;</content></entry><entry><title>Fourier Part 1: What is a Fourier series?</title><id>https://freakingpenguin.com/blog/fourier-part-1-what-is-a-fourier-series.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2021-04-06T00:00:00Z</updated><link href="https://freakingpenguin.com/blog/fourier-part-1-what-is-a-fourier-series.html" rel="alternate" /><content type="html">&lt;h1&gt;An overview of Taylor series&lt;/h1&gt;&lt;p&gt;A fourier expansion is a way for us to approximate a function. If
you've taken calculus before, you may have heard of a similar concept,
Taylor series. With Taylor series, we can approximate any function as
a sum of polynomials. For example, we can write &lt;math display=&quot;inline&quot; alttext=&quot;\sin x&quot;&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁡&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt; as
&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;\sin x=x-\frac{x^{3}}{3!}+\frac{x^{5}}{5!}-\frac{x^{7}}{7!}&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁡&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/msup&gt;&lt;mrow&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;!&lt;/mo&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mfrac&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;/msup&gt;&lt;mrow&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo&gt;!&lt;/mo&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;/msup&gt;&lt;mrow&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mo&gt;!&lt;/mo&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;p&gt;If we were to graph this, we see that as more terms are
added, our approximation becomes more and more accurate. Here's a
small demonstration.
&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-taylor-example.png&quot; alt=&quot;A graph showing sin(x) and two Taylor series approximations with 3 and 5 terms.&quot; /&gt;&lt;/p&gt;&lt;p&gt;In the graph below, I tried demonstrating how the Taylor series can
&amp;quot;home in&amp;quot; on a function. Since we can't add part of a term in a Taylor
series, I tried to demonstrate this effect by multiplying the term by
a value. For example, when you see 1.1 terms, that means the first
term + 0.1 * the second term. For &lt;math display=&quot;inline&quot; alttext=&quot;\sin x&quot;&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁡&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt;, that's &lt;math display=&quot;inline&quot; alttext=&quot;\sin x=x-0.1*\frac{x^{3}}{3!}&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁡&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mrow&gt;&lt;mn&gt;0.1&lt;/mn&gt;&lt;mo rspace=&quot;0.222em&quot; lspace=&quot;0.222em&quot;&gt;∗&lt;/mo&gt;&lt;mfrac&gt;&lt;msup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/msup&gt;&lt;mrow&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;!&lt;/mo&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-taylor-animated-example.gif&quot; alt=&quot;An animated graph showing how adding terms to the Taylor series improves its accuracy.&quot; /&gt;&lt;/p&gt;&lt;p&gt;Now, Taylor series can be useful, but they have significant
limitations. First, we see that the Taylor series does a poor job
modeling periodic functions. Even though &lt;math display=&quot;inline&quot; alttext=&quot;\sin x&quot;&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁡&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt; repeats, our
Taylor series does not. At large &lt;math display=&quot;inline&quot; alttext=&quot;x&quot;&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/math&gt; values, this Taylor series is
completely wrong!&lt;/p&gt;&lt;p&gt;Second, a Taylor series relies on the function being continuous (no
holes or jumps). In addition to the function being continous, its
derivatives must be as well. Let's consider the following graph.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/static/images/graphs/gnuplot-discontinuous-derivative.png&quot; alt=&quot;A graph showing a piecewise function y=-x for x&amp;lt;0 and y=x for x&amp;gt;=0, along with its first derivative.&quot; /&gt;&lt;/p&gt;&lt;p&gt;Even though &lt;math display=&quot;inline&quot; alttext=&quot;f(x)&quot;&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt; is continuous, its derivative &lt;math display=&quot;inline&quot; alttext=&quot;f^{\prime}(x)&quot;&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;′&lt;/mo&gt;&lt;/msup&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt; is
not. As such, a Taylor series cannot be used to approximate this
function. This issue would come up even if &lt;math display=&quot;inline&quot; alttext=&quot;f^{\prime\prime\prime\prime\prime\prime\prime\prime\prime\prime}(x)&quot;&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;′′′′′′′′′′&lt;/mo&gt;&lt;/msup&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt; was
discontinuous. (Keep in mind that discontinuous is not the same thing
as 0! We can model &lt;math display=&quot;inline&quot; alttext=&quot;f(x)=x&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt; as a Taylor series, as its
higher order derivatives are continuous. They just also happen to be
0. Also, &lt;math display=&quot;inline&quot; alttext=&quot;f(x)=x&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt; is its own Taylor series.)&lt;/p&gt;&lt;p&gt;So, to summarize, Taylor series have the following issues:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;They do not model periodic functions well&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;They require the function and all of its derivatives to be continuous&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Fortunately, the Fourier series provides answers to both of these
problems! (At least for most functions. Some functions, like a
function that is discontinuous everywhere, exist solely for the
purpose of making us sad.)&lt;/p&gt;&lt;h1&gt;What we're all here for, Fourier series&lt;/h1&gt;&lt;p&gt;I'll be sticking to the basics of Fourier series for now. Let's assume
we have a periodic function &lt;math display=&quot;inline&quot; alttext=&quot;f(x)&quot;&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt; that has a period of &lt;math display=&quot;inline&quot; alttext=&quot;T&quot;&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/math&gt;. I
am going to fintroduce the symbol l-i where &lt;math display=&quot;inline&quot; alttext=&quot;l=\frac{T}{2}&quot;&gt;&lt;mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;/math&gt;. While this isn't the only option, we can write the Fourier series as&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;f(x)=\sum_{n=0}^{\infty}a_{n}\cos(\frac{n\pi x}{l})\ +b_{n}\sin(\frac{n\pi x}{%
l})&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo rspace=&quot;0.111em&quot;&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;munderover&gt;&lt;mo movablelimits=&quot;false&quot;&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/munderover&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo stretchy=&quot;false&quot; rspace=&quot;0.500em&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;p&gt;In this case, we can find &lt;math display=&quot;inline&quot; alttext=&quot;a_{n}&quot;&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; and &lt;math display=&quot;inline&quot; alttext=&quot;b_{n}&quot;&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; with the formulas&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;a_{n}=\frac{1}{l}\int_{0}^{2l}f(x)\cos(\frac{n\pi x}{l})dx&quot;&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;b_{n}=\frac{1}{l}\int_{0}^{2l}f(x)\sin(\frac{n\pi x}{l})dx&quot;&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;p&gt;I won't go into detail as to where these formulas come from. (That is
left as an exercise for the reader. Hah!) However, I will point out
that we can adjust the limits of integration to any values we want,
just as long as the difference between the upper and lower limits
equals our period.&lt;/p&gt;&lt;p&gt;There is one special case that we need to discuss. When &lt;math display=&quot;inline&quot; alttext=&quot;n=0&quot;&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;/math&gt;,
we need a new formula for &lt;math display=&quot;inline&quot; alttext=&quot;a_{0}&quot;&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;. This formula will look like&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;a_{0}=\frac{1}{2l}\int_{0}^{2l}f(x)dx&quot;&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;p&gt;Fortunately there is no special case for &lt;math display=&quot;inline&quot; alttext=&quot;b_{0}&quot;&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;. This occurs due to
the fact that &lt;math display=&quot;inline&quot; alttext=&quot;a_{0}&quot;&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt; is a constant term ( &lt;math display=&quot;inline&quot; alttext=&quot;\cos 0=1&quot;&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo lspace=&quot;0.167em&quot;&gt;⁡&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/math&gt; ) as
opposed to periodic.&lt;/p&gt;&lt;p&gt;That is all the theory that we need to calculate the Fourier series!
As long as we can find a library that can perform integration for us,
we should be able to calculate the Fourier series for any periodic
function.&lt;/p&gt;&lt;h1&gt;Using GSL to calculate an integral&lt;/h1&gt;&lt;h2&gt;Explanation of &lt;code&gt;gsl_integration_qng()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;Because of inscrutible magic mumbo jumbo, I decided to use C for
calculating the Fourier expansion. In order to do that, I needed to
pick out a library that could perform the integration for me. I
settled on &lt;code&gt;GSL&lt;/code&gt; or the GNU Scientific Library. There are many, many,
MANY functions available in this library, but luckily I only need to
worry about integration.&lt;/p&gt;&lt;p&gt;Before going too far into Fourier stuff, I'm going to do a simple
sanity check so I can make sure I'm calculating integrals correctly. I
want to calculate the following integral.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;math display=&quot;block&quot; alttext=&quot;\int_{0}^{8}xdx&quot;&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;8&lt;/mn&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;&lt;/div&gt;&lt;p&gt;To do this using &lt;code&gt;GSL&lt;/code&gt;, I can use the &lt;code&gt;gsl_integration_qng()&lt;/code&gt; function.
This function has the following signature.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_qng&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_function&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;,
            &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;b&lt;/span&gt;,
            &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;epsabs&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;epsrel&lt;/span&gt;,
            &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;abserr&lt;/span&gt;,
            &lt;span class=&quot;syntax-symbol&quot;&gt;size_t&lt;/span&gt; * &lt;span class=&quot;syntax-symbol&quot;&gt;neval&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;f&lt;/code&gt; is a pointer to a structure that contains a function pointer. For
those who don't speak nerd, this is how &lt;code&gt;gsl-integration-qng()&lt;/code&gt; knows
what function to integrate. It's our &lt;code&gt;f(x)&lt;/code&gt;. (Mostly. The reason for
making it a structure is because the structure also contains a &lt;code&gt;void *&lt;/code&gt; or void pointer. This void pointer can be used to pass parameters
to the function. This could be used to let us change the slope of the
function without having to modify the function itself.&lt;/p&gt;&lt;p&gt;&lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are the lower and upper limits of integration.
That's fairly straightforward.&lt;/p&gt;&lt;p&gt;&lt;code&gt;epsabs&lt;/code&gt; and &lt;code&gt;epsrel&lt;/code&gt; help &lt;code&gt;gsl_integration_qng()&lt;/code&gt; decide when to stop
integrating. It's not possible to integrate the function to an exact
value with &lt;code&gt;GSL&lt;/code&gt;. Instead, it tries to zero in on a specific value or
best guess as to what the answer is. &lt;code&gt;epsabs&lt;/code&gt; is the absolute error
that we want. If &lt;code&gt;epsabs&lt;/code&gt; = 0.1, we don't know what the answer is, but
we know we are no more than 0.1 away from it. &lt;code&gt;epsrel&lt;/code&gt; is similar, but
percentage based instead of absolute. (e.g. &lt;code&gt;epsrel&lt;/code&gt; = 0.01 means our
answer is within 1% of the actual value.)&lt;/p&gt;&lt;p&gt;&lt;code&gt;result&lt;/code&gt; and &lt;code&gt;abserr&lt;/code&gt; are used by the function to store the result
and estimated absolute error, respectively. The number of iterations
it took to calculate the result is stored in &lt;code&gt;neval&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;It is possible for the integration to fail. This might happen if we
set the error tolerances too tight. Since the function we're
integrating is so simple, I don't think that's a likely concern.&lt;/p&gt;&lt;h2&gt;&lt;code&gt;gsl_integration_qng()&lt;/code&gt; in use&lt;/h2&gt;&lt;p&gt;To compile this program, you will need to tell the compiler what
external libraries to use. You can do with with the &lt;code&gt;-lgsl&lt;/code&gt; compile
flag, e.g. &lt;code&gt;gcc main.c -lgsl&lt;/code&gt;. Because &lt;code&gt;GSL&lt;/code&gt; depends on another
library, &lt;code&gt;CBLAS&lt;/code&gt;, you will also need the &lt;code&gt;-lcblas&lt;/code&gt; flag. If &lt;code&gt;CBLAS&lt;/code&gt;
isn't available, you can use a version of &lt;code&gt;CBLAS&lt;/code&gt; provided by &lt;code&gt;GSL&lt;/code&gt;
with &lt;code&gt;-lgslcblas&lt;/code&gt;. (Don't forget to install &lt;code&gt;GSL&lt;/code&gt;!) Since I'm using
some math function, I'm also going to include the math library with
&lt;code&gt;-lm&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;In the end, our command will look like &lt;code&gt;gcc main.c -lgsl -lcblas -lm&lt;/code&gt;,
which will compile &lt;code&gt;main.c&lt;/code&gt; and create an output file &lt;code&gt;a.out&lt;/code&gt;.
(Actually I'm using &lt;code&gt;org-babel&lt;/code&gt; so I don't have to deal with this, but
I'm assuming most readers here are not.)&lt;/p&gt;&lt;p&gt;Alright! Time to integrate! I need to preface the &lt;code&gt;gsl_integration.h&lt;/code&gt;
header with &lt;code&gt;gsl/&lt;/code&gt; as the headers are installed in a &lt;code&gt;gsl&lt;/code&gt;
subdirectory. (If you installed this through your systems package
manager, you can probably find this file in &lt;code&gt;/usr/include/gsl/&lt;/code&gt;.)&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;stdio.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;gsl/gsl_integration.h&amp;gt;
&lt;span class=&quot;syntax-keyword&quot;&gt;#include&lt;/span&gt; &amp;lt;math.h&amp;gt;

&lt;span class=&quot;syntax-comment&quot;&gt;/* This is where we define the function */&lt;/span&gt;
&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;, &lt;span class=&quot;syntax-special&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;x&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;8&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_function&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;function&lt;/span&gt; = &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;num_evals&lt;/span&gt;;

  &lt;span class=&quot;syntax-symbol&quot;&gt;gsl_integration_qng&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;F&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;low&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;high&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_abs&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;err_rel&lt;/span&gt;,
      		&amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;, &amp;amp;&lt;span class=&quot;syntax-symbol&quot;&gt;num_evals&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;result error num_evals\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
  &lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;%f %f %zu\n&amp;quot;&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;result&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;error&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;num_evals&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;Results:
&lt;code&gt;| result | error | num_evals |
|   32.0 |   0.0 |        21 |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There we go! &lt;code&gt;GSL&lt;/code&gt; was able to successfully integrate &lt;math display=&quot;inline&quot; alttext=&quot;\int_{0}^{8}xdx&quot;&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;8&lt;/mn&gt;&lt;/msubsup&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo lspace=&quot;0em&quot;&gt;⁢&lt;/mo&gt;&lt;mrow&gt;&lt;mo rspace=&quot;0em&quot;&gt;𝑑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;/math&gt;.&lt;/p&gt;&lt;p&gt;In the next part, we'll start using &lt;code&gt;GSL&lt;/code&gt; to calculate the Fourier
series of a discontinuous, periodic function. We'll see if we can
naively get away with using the simple &lt;code&gt;gsl_integration_qng()&lt;/code&gt;
function, or if we need to find a more complicated, but more powerful, alternative. &lt;/p&gt;</content></entry><entry><title>Are bus errors still commonplace? Plus a bonus discussion on org-babel.</title><id>https://freakingpenguin.com/blog/are-bus-errors-still-commonplace-plus-a-bonus-discussion-on-org-babel.html</id><author><name>Richard Sent</name><email>richard@freakingpenguin.com</email></author><updated>2021-03-24T00:00:00Z</updated><link href="https://freakingpenguin.com/blog/are-bus-errors-still-commonplace-plus-a-bonus-discussion-on-org-babel.html" rel="alternate" /><content type="html">&lt;h1&gt;What is a bus error?&lt;/h1&gt;&lt;p&gt;I was reading through Peter Linden's &lt;em&gt;Expert C Programming&lt;/em&gt; when I
noticed an interesting example. On page 189, Peter talks about how one
can cause a bus error. I've never had a bus error occur before. Maybe
they're a solved problem?&lt;/p&gt;&lt;p&gt;Before we get too far ahead of ourselves, a bus error can occur when
we access a variable at an address that's not valid for that variable.
An address is not valid if the address is not evenly divisible by the
length of the variable. In other words...&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-comment&quot;&gt;/* sizeof (int) == 4 */&lt;/span&gt;
&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;p1&lt;/span&gt; = *&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;5&lt;/span&gt;;
&lt;span class=&quot;syntax-comment&quot;&gt;/* Causes a bus error, 5 % 4 != 0 */&lt;/span&gt;

&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;p2&lt;/span&gt; = *&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;32&lt;/span&gt;;
&lt;span class=&quot;syntax-comment&quot;&gt;/* No bus error, 32 % 4 == 0 */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Realistically these programs would immediately seg fault as we
don't have access to arbitrary memory addresses. (Unless we were
working with embedded systems, perhaps...). To avoid this, we
can use a union.&lt;/p&gt;&lt;h1&gt;Peter Linden's Code&lt;/h1&gt;&lt;p&gt;Using the sample code in &lt;em&gt;Expert C Programming&lt;/em&gt;, pg.
189, I am going to see if it causes a bus error.&lt;/p&gt;&lt;p&gt;The address of the union must be divisible by 4 (or &lt;code&gt;sizeof int&lt;/code&gt;),
as it can store an integer. As long as &lt;code&gt;sizeof int &amp;gt; sizeof char&lt;/code&gt;
(or &lt;code&gt;sizeof int &amp;gt; 1&lt;/code&gt; as &lt;code&gt;sizeof char == 1&lt;/code&gt;), we can successfully
get our bus error.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-special&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;u&lt;/span&gt;;
&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &amp;amp;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;u&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
,*&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;17&lt;/span&gt;;
&lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;*p %d\n&amp;quot;&lt;/span&gt;, *&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;#+RESULTS:
: *p 17&lt;/p&gt;&lt;p&gt;Look at that! No problems.&lt;/p&gt;&lt;p&gt;x86 is very forgiving when it comes to misalignment errors. For the
most part, they just don't happen. This is great for us, but what if
we ported this code over to a platform that is less friendly, like
ARM?&lt;/p&gt;&lt;p&gt;Ideally, we want to see if a bus error &lt;em&gt;can&lt;/em&gt; occur in our code, so
that way we can avoid them during development, as opposed to fixing it
later.&lt;/p&gt;&lt;p&gt;Looking through the &lt;code&gt;gcc&lt;/code&gt; manual, I found a compile flag that will be
useful.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;fsanitize=undefined&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector.
Various computations are instrumented to detect undefined behavior at
runtime.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;By adding the &lt;code&gt;-fsanitize=undefined&lt;/code&gt; compile flag, our program will
print a runtime error whenever one occurs.&lt;/p&gt;&lt;p&gt;There are similar flags, &lt;code&gt;-fsanitize=address&lt;/code&gt; and &lt;code&gt;-fsanitize=thread&lt;/code&gt;,
that can be useful for runtime error checking; look at the &lt;code&gt;gcc&lt;/code&gt;
manual for more information. I can combine options with commas, i.e.
&lt;code&gt;-fsanitize=address,thread,undefined&lt;/code&gt;.&lt;/p&gt;&lt;h1&gt;&lt;code&gt;-fsanitize=undefined&lt;/code&gt;&lt;/h1&gt;&lt;p&gt;There is one change that I need to make to the code. When a runtime
error occurs, the results are printed to &lt;code&gt;stderr&lt;/code&gt;. When we're looking
at our code through a terminal, &lt;code&gt;stderr&lt;/code&gt; and &lt;code&gt;stdout&lt;/code&gt; might seem like
the exact same thing.&lt;/p&gt;&lt;p&gt;I am not running this code through a terminal. I'm using &lt;code&gt;org-babel&lt;/code&gt;,
a very powerful tool for literate programming. If our
program runs successfully, &lt;code&gt;org-babel&lt;/code&gt; will tell us the results.&lt;/p&gt;&lt;p&gt;Unfortunately, these results don't include &lt;code&gt;stderr&lt;/code&gt;. In order to see
the runtime error occur, I need to close &lt;code&gt;stderr&lt;/code&gt;, then change
&lt;code&gt;stderr&lt;/code&gt;'s file descriptor to point to &lt;code&gt;stdout&lt;/code&gt;. This is what the
&lt;code&gt;dup2()&lt;/code&gt; function is doing.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;dup2&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;STDOUT_FILENO&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;STDERR_FILENO&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;

&lt;span class=&quot;syntax-special&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;u&lt;/span&gt;;
&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &amp;amp;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;u&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
,*&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;17&lt;/span&gt;;
&lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;*p %d\n&amp;quot;&lt;/span&gt;, *&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
&lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;p %lld\n&amp;quot;&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;#+RESULTS:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/tmp/babel-YOFYnN/C-src-93AiCJ.c:17:6: runtime error: store to misaligned address 0x7ffec796bddd for type 'int', which requires 4 byte alignment
0x7ffec796bddd: note: pointer points here
 40 5a 14 84 55 00 00  e0 be 96 c7 fe 7f 00 00  00 f5 9a c3 4a 31 08 2e  00 00 00 00 00 00 00 00  25
             ^ 
/tmp/babel-YOFYnN/C-src-93AiCJ.c:18:3: runtime error: load of misaligned address 0x7ffec796bddd for type 'int', which requires 4 byte alignment
0x7ffec796bddd: note: pointer points here
 40 5a 14 84 11 00 00  00 be 96 c7 fe 7f 00 00  00 f5 9a c3 4a 31 08 2e  00 00 00 00 00 00 00 00  25
             ^ 
,*p 17
p 140732246965725&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And it works! We can now see the runtime error! We're trying to access
an integer at address 140732246965725, which is not divisible by 4
(AKA &lt;code&gt;sizeof int&lt;/code&gt;). Thus, a bus error occurs.&lt;/p&gt;&lt;h1&gt;Crash and burn programming&lt;/h1&gt;&lt;p&gt;Running code and printing out runtime errors is great. However, there's a
saying in programming called &amp;quot;Fail early, fail often&amp;quot;. What if we
don't just want an error message printed? What if, instead, we want
the program to immediately crash? After all, this is what would
actually happen if we were on a CPU architecture that couldn't handle
misaligned addresses.&lt;/p&gt;&lt;p&gt;I looked through the &lt;code&gt;gcc&lt;/code&gt; manual and saw the &lt;code&gt;-fno-sanitize-recover=all&lt;/code&gt;
option. Supposedly, it does the following:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;-fsanitize-recover=all&lt;/code&gt; and &lt;code&gt;-fno-sanitize-recover=all&lt;/code&gt; is also
accepted, the former enables recovery for all sanitizers that
support it, the latter disables recovery for all sanitizers that
support it.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Let's try it! I'm going to add &lt;code&gt;-fno-sanitize-recover=all&lt;/code&gt; as a
compile flag. This should cause the program to immediately crash,
only printing the error message.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;dup2&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;STDOUT_FILENO&lt;/span&gt;, &lt;span class=&quot;syntax-symbol&quot;&gt;STDERR_FILENO&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;

&lt;span class=&quot;syntax-special&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-special&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;;
  &lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;i&lt;/span&gt;;
&lt;span class=&quot;syntax-close&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;u&lt;/span&gt;;
&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt; = &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;int&lt;/span&gt; *&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &amp;amp;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;u&lt;/span&gt;.&lt;span class=&quot;syntax-symbol&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;
,*&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt; = &lt;span class=&quot;syntax-symbol&quot;&gt;17&lt;/span&gt;;
&lt;span class=&quot;syntax-symbol&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;p %d\n&amp;quot;&lt;/span&gt;, *&lt;span class=&quot;syntax-symbol&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Huh? Why wasn't the error message printed? Crashing the program is
what we wanted, but not without the error message! Without an error
message, all we're doing is making our program harder to debug.&lt;/p&gt;&lt;p&gt;Fortunately, this isn't our fault. The error message is actually being
printed, and it is being printed to &lt;code&gt;stdout&lt;/code&gt;. If we were running our
program in a terminal, we'd see the error message we expect.&lt;/p&gt;&lt;p&gt;Unfortunately, this is a limitation of &lt;code&gt;org-babel&lt;/code&gt;.
&lt;code&gt;-fno-sanitize-recover=all&lt;/code&gt; causes a nonzero exit code to be returned
on failure. &lt;code&gt;org-babel&lt;/code&gt; does not like nonzero exit codes and fails to
evaluate &lt;code&gt;stdout&lt;/code&gt; when this happens. It does evaluate &lt;code&gt;stderr&lt;/code&gt; when
the exit code is nonzero, but only to a separate temporary buffer. At
least this works outside of &lt;code&gt;org-babel&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;There's a (brief) discussion of this issue on the mailing list
&lt;a href=&quot;https://lists.gnu.org/archive/html/emacs-orgmode/2016-05/msg00204.html&quot;&gt;here&lt;/a&gt;.
Given that this thread is 5 years old, I'm not holding my breath for a
fix.&lt;/p&gt;&lt;p&gt;There is an easy solution for &lt;code&gt;sh&lt;/code&gt; scripts; just create a line at the
end with &lt;code&gt;:&lt;/code&gt;. Unfortunately since this is C, that's not really an
option.&lt;/p&gt;&lt;h1&gt;Wrapping it up&lt;/h1&gt;&lt;p&gt;The entire point of this endeavour is to try to make sure our code is
portable. When I write a program for one system, that program better
work on as many other systems as possible.&lt;/p&gt;&lt;p&gt;If any college students read this, professors don't like the &amp;quot;but it
worked on my machine!&amp;quot; excuse. (On the other hand, it takes one &lt;em&gt;mean&lt;/em&gt;
professor to test with a different architecture in order to if you were
careful about memory alignment. We can't predict everything!)&lt;/p&gt;&lt;p&gt;&lt;code&gt;-fsanitize=undefined&lt;/code&gt; is a great flag to add when compiling; it
catches more than just memory alignment! If you add the flag and
forget about it, you will at least get a warning when undefined
behavior occurs! I'd much rather have a program that doesn't work but
I know why then a program that doesn't work and I don't know why.&lt;/p&gt;</content></entry></feed>