<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>freakingpenguin blog</title><id>https://freakingpenguin.com/feeds/tags/haunt.xml</id><subtitle>Tag: haunt</subtitle><updated>2024-03-06T00:00:00Z</updated><link href="https://freakingpenguin.com/feeds/tags/haunt.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>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>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></feed>