<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/~yorgey/forest/default.xsl"?>
<fr:tree xmlns:fr="http://www.forester-notes.org" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" root="false" base-url="/~yorgey/forest/">
  <fr:frontmatter>
    <fr:authors>
      <fr:author>
        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
      </fr:author>
    </fr:authors>
    <fr:date>
      <fr:year>2026</fr:year>
      <fr:month>8</fr:month>
      <fr:day>22</fr:day>
    </fr:date>
    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W33/</fr:uri>
    <fr:display-uri>2026-W33</fr:display-uri>
    <fr:route>/~yorgey/forest/2026-W33/</fr:route>
    <fr:title text="Weeknotes for 21 August 2026 (week 33)">Weeknotes for 21 August 2026 (week 33)</fr:title>
  </fr:frontmatter>
  <fr:mainmatter>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
          </fr:author>
        </fr:authors>
        <fr:date>
          <fr:year>2026</fr:year>
          <fr:month>8</fr:month>
          <fr:day>22</fr:day>
        </fr:date>
        <fr:title text="Swarm">Swarm</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p>This week was the 5-year anniversary of my <fr:link href="https://github.com/swarm-game/swarm/commit/479b10e98685cdc4c7c7f1935b679b6b83819dcf" type="external">first commit to the
  Swarm repo</fr:link>—back in August of 2021, at the start of my sabbatical.  It's been a wonderful, wild ride.  The project has gone much farther than I could have imagined, and been more professionally fruitful than I would have thought possible!  And a big part of the reason it's remained fun for so long is the cool community of other contributors the project has attracted.</html:p>
        <html:p>There's been a flurry of activity this week from several other contributors, so I've spent a decent bit of time reviewing PRs.  Among other cool things, there have been some fantastic improvements to memory usage and performance.</html:p>
        <html:p>I've also continued working on an integrated help system this week.  It's coming along nicely.  One of the few things still missing is the ability to specify a table of contents for a given page, from which we can automatically display next/previous/up links.  I basically plan to steal the way Sphinx does this with the <html:code>toctree</html:code> directive.</html:p>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
          </fr:author>
        </fr:authors>
        <fr:date>
          <fr:year>2026</fr:year>
          <fr:month>8</fr:month>
          <fr:day>22</fr:day>
        </fr:date>
        <fr:title text="First-year student advising">First-year student advising</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p>I spent a substantial amount of time this week meeting with my cohort of 14 first-year student advisees—first as a group, and then individually.  In past years, they have come to campus with blank slates and we would spend the first week frantically building their schedules, resolving conflicts, finding alternate classes when the class they wanted is too full, and so on.  It didn't leave much time for anything besides putting out fires.  Starting last year, we have a new system in place where they meet with someone virtually over the summer to put together an initial course schedule.  By the time they arrive on campus they already have a mostly-solid schedule, and I just have to help fill it out with an extra class or two.  It is much more civilized and leaves plenty of time for chatting and getting to know them and what they are interested in.  Talking to people all day is a lot, but aside from that it was quite enjoyable; they all seem like lovely human beings with a wide variety of interests.</html:p>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
          </fr:author>
        </fr:authors>
        <fr:date>
          <fr:year>2026</fr:year>
          <fr:month>8</fr:month>
          <fr:day>22</fr:day>
        </fr:date>
        <fr:title text="Semester prep">Semester prep</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p>The fall semester is almost upon us.  When I haven't been doing advising stuff I have been working hard on preparing for my fall courses.  I'll be co-teaching our introductory programming course with my colleague, and we don't plan to change much about the course, which by this point is a well-oiled machine.  On the other hand, I am making a few more changes to Algorithms this semester.  In order to reduce incentives for LLM use, I'm adding an extra midterm exam and having some required office hour visits.  But the extra exam makes it more awkward to fit in weekly problem sets at reasonable times, which suddenly made me wonder today whether I could do something more flexible, like assigning individual problems every day and having them choose a portfolio of problems to solve. I still need to work out a lot of details.</html:p>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" numbered="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
          </fr:author>
        </fr:authors>
        <fr:date>
          <fr:year>2026</fr:year>
          <fr:month>8</fr:month>
          <fr:day>22</fr:day>
        </fr:date>
        <fr:title text="Hanabi">Hanabi</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p>I have continued to enjoy <fr:link href="https://hanabi.github.io/" type="external">Hanabi</fr:link> a lot—playing sometimes with my 14yo and sometimes with strangers on <fr:link href="https://hanab.live/lobby" type="external">Hanab Live</fr:link>.  I think I enjoy it for many of the same reasons that I enjoy bridge—it is collaborative rather than competitive (I'm super competitive and it's easy for me to get stressed out about winning and losing), and involves teamwork, communication, and logical deduction.  I'm always happy to teach others, so if you're intrigued and would like to learn how to play, let me know!</html:p>
        <html:p>
          <html:img src="/~yorgey/forest/bafkrmiavv3meudblpszzjrxqoxl2cz7prgz5wf5dxawjsf3cu5zy5bb2ia.png" />
        </html:p>
      </fr:mainmatter>
    </fr:tree>
  </fr:mainmatter>
  <fr:backmatter>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="References">References</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Context">Context</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
              </fr:author>
            </fr:authors>
            <fr:date>
              <fr:year>2026</fr:year>
              <fr:month>2</fr:month>
              <fr:day>13</fr:day>
            </fr:date>
            <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/005U/</fr:uri>
            <fr:display-uri>005U</fr:display-uri>
            <fr:route>/~yorgey/forest/005U/</fr:route>
            <fr:title text="Brent Yorgey › Weeknotes"><fr:link href="/~yorgey/forest/index/" title="Brent Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/index/" display-uri="index" type="local">Brent Yorgey</fr:link> › Weeknotes</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>This page has an <fr:link href="/~yorgey/forest/005U/atom.xml" type="external">atom feed</fr:link>.</html:p>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>2</fr:month>
                  <fr:day>13</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W06/</fr:uri>
                <fr:display-uri>2026-W06</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W06/</fr:route>
                <fr:title text="Weeknotes for 13 February 2026 (week 6)">Weeknotes for 13 February 2026 (week 6)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Inspired by <fr:link href="https://www.jonmsterling.com/019X/" type="external">Jon Sterling</fr:link> and <fr:link href="https://liamoc.net/forest/loc-001B/index.xml" type="external">Liam O'Connor</fr:link>, this is my first attempt at writing <fr:link href="https://www.jonmsterling.com/01JS/" type="external">weeknotes</fr:link>.  It seems like it could be a useful practice, but one that I won't be able to evaluate without trying it.</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>14</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/005V/</fr:uri>
                    <fr:display-uri>005V</fr:display-uri>
                    <fr:route>/~yorgey/forest/005V/</fr:route>
                    <fr:title text="Thoughts on pedagogy and community-building">Thoughts on pedagogy and community-building</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This semester I am participating in a "teaching square" with several colleagues, where we visit and observe each other's classes—not for the purpose of evaluation, or even constructive criticism, but merely to observe and reflect on our own teaching. On Monday I visited a class taught by one of my colleagues (who shall remain anonymous for now since I don't know whether she would want to be identified publicly in this context).  I very much enjoyed watching the way my colleague got the students to engage actively with her and with each other.  It seemed like the students in the class all knew each others' names, which in my experience is rare, even in a small class.  I don't think this was a coincidence—it was something my colleague intentionally cultivated.</html:p>
                    <html:p>This week I also read <fr:link href="/~yorgey/forest/shriramkrishnamurthi/" title="Shriram Krishnamurthi" uri="http://ozark.hendrix.edu/~yorgey/forest/shriramkrishnamurthi/" display-uri="shriramkrishnamurthi" type="local">Shriram Krishnamurthi</fr:link>'s <fr:link href="https://parentheticallyspeaking.org/articles/pedagogy-recommendations/" type="external">pedagogy recommendations</fr:link>, and among other good advice, he also says several things about creating community within the classroom (such as getting students to introduce themselves to each other repeatedly).</html:p>
                    <html:p>I'm still thinking about what, if anything, I might concretely do differently in my classes, but it's been good to think about.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>14</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/005W/</fr:uri>
                    <fr:display-uri>005W</fr:display-uri>
                    <fr:route>/~yorgey/forest/005W/</fr:route>
                    <fr:title text="Forester setup for Discrete Math lecture notes">Forester setup for Discrete Math lecture notes</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I spent a bunch of time this week writing <fr:link href="/~yorgey/forest/0021/" title="Discrete Mathematics Spring 2026 lecture notes" uri="http://ozark.hendrix.edu/~yorgey/forest/0021/" display-uri="0021" type="local">Discrete Math lecture notes</fr:link> in Forester, and tweaking my Forester setup to make the process more efficient and the results prettier.

<html:ul><html:li>I used <fr:link href="https://pandoc.org/" type="external">Pandoc</fr:link> to write a <fr:link href="https://github.com/byorgey/pandoc-forester" type="external">janky script</fr:link> that takes my existing LaTeX lecture notes and makes a first pass at converting them into Forester syntax.  There's still lots more features I could add, and it's nowhere near being a complete, general-purpose pandoc writer (I'm not sure it will ever be), but it already saves me time.</html:li>

  <html:li>After <fr:link href="https://lists.sr.ht/~jonsterling/forester-discuss/%3CCAH0njdutB1dVSn4gMRHKFyZhgSzVcrr5KmpCj_3PDoRCqSk_Uw@mail.gmail.com%3E" type="external">asking for advice on the forester-discuss mailing list</fr:link> and getting a helpful response, I created some <fr:link href="https://github.com/byorgey/forest/blob/main/trees/sproof.tree" type="external">simple Forester macros</fr:link> for typesetting calculational proofs, like so:

    <html:p><html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[2n - 1 > 7]]></fr:tex></html:div>

      
  <fr:tex display="inline"><![CDATA[\leftrightarrow  \quad \quad \quad ]]></fr:tex> { add <fr:tex display="inline"><![CDATA[1]]></fr:tex> to both sides }

      
  <html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[2n > 8]]></fr:tex></html:div>

      
  <fr:tex display="inline"><![CDATA[\leftrightarrow  \quad \quad \quad ]]></fr:tex> { divide both sides by <fr:tex display="inline"><![CDATA[2]]></fr:tex> }

      
  <html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[n > 4]]></fr:tex></html:div></html:p></html:li>

  <html:li>When teaching my Discrete Math students to write proofs, I emphasize the way the proofs should be structured, <html:em>i.e.</html:em> nested.  I have not yet gone so far as teaching them via a proof assistant like Lean or Agda—I'm not sure I ever will—but I get as close as possible while still writing proofs on paper.  I spent a bit of time tweaking some CSS to be able to easily typeset things like this:

  
  
    
    <fr:tree show-metadata="false" toc="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link></fr:author></fr:authors><fr:date><fr:year>2026</fr:year><fr:month>2</fr:month><fr:day>14</fr:day></fr:date><fr:taxon>Proof</fr:taxon></fr:frontmatter><fr:mainmatter>
    Let <fr:tex display="inline"><![CDATA[k]]></fr:tex> be an arbitrary integer; then we must show <fr:tex display="inline"><![CDATA[\mathrm {Odd}(k) \to  \mathrm {Odd}(k^2)]]></fr:tex>.
    
  <fr:tree show-metadata="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link></fr:author></fr:authors><fr:date><fr:year>2026</fr:year><fr:month>2</fr:month><fr:day>14</fr:day></fr:date><fr:taxon>Subproof</fr:taxon></fr:frontmatter><fr:mainmatter>
      Suppose <fr:tex display="inline"><![CDATA[\mathrm {Odd}(k)]]></fr:tex>, that is, there exists an integer <fr:tex display="inline"><![CDATA[j]]></fr:tex> such that <fr:tex display="inline"><![CDATA[k = 2j+1]]></fr:tex>.  Then we must show that <fr:tex display="inline"><![CDATA[k^2]]></fr:tex> is also odd.
      
  <fr:tree show-metadata="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link></fr:author></fr:authors><fr:date><fr:year>2026</fr:year><fr:month>2</fr:month><fr:day>14</fr:day></fr:date><fr:taxon>Subproof</fr:taxon></fr:frontmatter><fr:mainmatter>
        <fr:tex display="inline"><![CDATA[k^2 = (2j+1)^2 = 4j^2 + 4j + 1 = 2(2j^2 + 2j) + 1]]></fr:tex>, so <fr:tex display="inline"><![CDATA[k^2]]></fr:tex> is odd since it is one more than twice an integer.
      </fr:mainmatter></fr:tree>

      Since we showed <fr:tex display="inline"><![CDATA[k^2]]></fr:tex> is odd under the supposition that <fr:tex display="inline"><![CDATA[k]]></fr:tex> is odd, we have proved the implication <fr:tex display="inline"><![CDATA[\mathrm {Odd}(k) \to  \mathrm {Odd}(k^2)]]></fr:tex>.
    </fr:mainmatter></fr:tree>

    Since <fr:tex display="inline"><![CDATA[k]]></fr:tex> was an arbitrary integer, we have proved <fr:tex display="inline"><![CDATA[\forall  {n}: {\mathbb {N}}.\; \mathrm {Odd}(n) \to  \mathrm {Odd}(n^2)]]></fr:tex>.
  </fr:mainmatter></fr:tree>
  


  This works by creating a new taxon called "Subproof" and using CSS to hide the header and draw a bar on the side.  I'm not sure if there's a better way to accomplish this, but it works pretty well for now.
  </html:li></html:ul></html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>14</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/005X/</fr:uri>
                    <fr:display-uri>005X</fr:display-uri>
                    <fr:route>/~yorgey/forest/005X/</fr:route>
                    <fr:title text="Classical vs constructive logic in Discrete Math">Classical vs constructive logic in Discrete Math</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Aside from such technical fiddling, I've also spent a good deal of time over the past few weeks rethinking my approach to teaching logic and proofs in my <fr:link href="/~yorgey/forest/0020/" title="MATH 240, Discrete Mathematics" uri="http://ozark.hendrix.edu/~yorgey/forest/0020/" display-uri="0020" type="local">Discrete Math course</fr:link>, inspired by <fr:link href="https://mathstodon.xyz/@emilyriehl/115804882229302713" type="external">Emily Riehl's approach</fr:link> and by <fr:link href="https://mathstodon.xyz/@mjd/115730298446604383" type="external">a rant by Mark Jason Dominus about teaching constructive logic</fr:link>.</html:p>
                    <html:p>Of course I love constructive logic; but I have come to the conclusion that, in my context at least, I think there are still good reasons for teaching classical logic (and teaching it <html:em>first</html:em>).  So I didn't end up making the radical changes I thought I might; but it was still a very useful exercise, as I did end up reorganizing things in some significant ways.  At some point I will write up a more detailed explanation of how I have decided to teach the course, and why.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>13</fr:day>
                    </fr:date>
                    <fr:title text="Curling">Curling</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>On a completely different note, I watched a lot of curling this week.  It looks like a lot of fun; I wish I could try it!</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>2</fr:month>
                  <fr:day>21</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W07/</fr:uri>
                <fr:display-uri>2026-W07</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W07/</fr:route>
                <fr:title text="Weeknotes for 20 February 2026 (week 7)">Weeknotes for 20 February 2026 (week 7)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Spent a bunch of time this week grading, dealing with
administrative stuff, and <fr:link href="/~yorgey/forest/0060/" title="Set theory" uri="http://ozark.hendrix.edu/~yorgey/forest/0060/" display-uri="0060" type="local">writing more lecture notes</fr:link>. Besides those I did a couple other things of interest:</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>21</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/0075/</fr:uri>
                    <fr:display-uri>0075</fr:display-uri>
                    <fr:route>/~yorgey/forest/0075/</fr:route>
                    <fr:title text="Swarm hacking">Swarm hacking</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I spent a while finishing up <fr:link href="https://github.com/swarm-game/swarm/pull/2688" type="external">this pull request</fr:link> for <fr:link href="/~yorgey/forest/000O/" title="Swarm" uri="http://ozark.hendrix.edu/~yorgey/forest/000O/" display-uri="000O" type="local">Swarm</fr:link>.  Right now, Swarm feels like it's kind of in this big slog/plateau where we've added all the "easy" features, and now in order to reach the ultimate vision there are a bunch of really hard, big projects/refactorings/redesigns that need to happen.  Stuff that's not sexy and that players will never notice.  Fortunately, although I certainly enjoy adding exciting features, I also really enjoy the <html:em>craft</html:em> of writing and refactoring code, of thinking hard about problems and coming up with elegant schemes for solving them.  I don't get to do a whole lot of that otherwise, so I'm really glad to have this somewhat-frivolous-but-surprisingly-professionally-fruitful project to work on.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>21</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/0074/</fr:uri>
                    <fr:display-uri>0074</fr:display-uri>
                    <fr:route>/~yorgey/forest/0074/</fr:route>
                    <fr:title text="The Farmer Was Replaced">The Farmer Was Replaced</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I started playing <fr:link href="https://store.steampowered.com/app/2060160/The_Farmer_Was_Replaced/" type="external">The Farmer Was Replaced</fr:link>—someone recommended it because of its similarities to Swarm.  There definitely are some similarities: in both games, you program robots to move around in a grid world collecting resources to unlock new programming language features.  (There are also some big differences, of course, such as the fact that Swarm has a much cooler programming language.)</html:p>
                    <html:p>The game feels like it is trying to be a fun way for people to learn programming.  But having taught literally hundreds of beginners how to program, I can tell you unequivocally that no one is going to be learning how to program from this game if they don't already have some other prior programming experience.  Still, it's a pretty fun game, and very polished; the implementation of the in-game Python-esque language is very impressive.</html:p>
                    <html:p>I haven't finished the game yet, still need to solve some mazes and implement a better snake-playing robot...</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>2</fr:month>
                  <fr:day>27</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W08/</fr:uri>
                <fr:display-uri>2026-W08</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W08/</fr:route>
                <fr:title text="Weeknotes for 27 February 2026 (week 8)">Weeknotes for 27 February 2026 (week 8)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>28</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/0087/</fr:uri>
                    <fr:display-uri>0087</fr:display-uri>
                    <fr:route>/~yorgey/forest/0087/</fr:route>
                    <fr:title text="Material set theory, universal sets, and pedagogy">Material set theory, universal sets, and pedagogy</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>In my <fr:link href="/~yorgey/forest/0020/" title="MATH 240, Discrete Mathematics" uri="http://ozark.hendrix.edu/~yorgey/forest/0020/" display-uri="0020" type="local">Discrete Mathematics course</fr:link> I am currently teaching (traditional, material) set theory.  I've recently noticed several instances where we really "want" to have a universe of discourse, <html:em>i.e.</html:em> a global set <fr:tex display="inline"><![CDATA[U]]></fr:tex> of which which other sets under consideration are subsets.</html:p>
                    <html:ul><html:li>Of course the notion of <html:em>set complement</html:em> doesn't make sense without a universe of discourse; complement with respect to what?</html:li>
  <html:li>I typically introduce set equality by defining <fr:tex display="inline"><![CDATA[A = B]]></fr:tex> to mean <fr:tex display="inline"><![CDATA[(A \subseteq  B) \land  (B \subseteq  A)]]></fr:tex>.  But sometimes we would really like to treat set equality extensionally, <html:em>i.e.</html:em> <fr:tex display="block"><![CDATA[(A = B) \leftrightarrow  (\forall  x. x \in  A \leftrightarrow  x \in  B).]]></fr:tex>  But what is the <fr:tex display="inline"><![CDATA[\forall ]]></fr:tex> quantifying over?  For this to make sense, we must posit that we are quantifying over some kind of universe.</html:li>
  <html:li>As for the subset relation itself, I typically define <fr:tex display="inline"><![CDATA[A \subseteq  B]]></fr:tex> as <fr:tex display="inline"><![CDATA[\forall  x \in  A. x \in  B]]></fr:tex>, but perhaps it is nicer to define it as <fr:tex display="block"><![CDATA[\forall  x \in  U. (x \in  A) \to  (x \in  B).]]></fr:tex>  If we define it that way, the extensional and subset-both-ways definitions of set equality are simply related by the fact that <fr:tex display="inline"><![CDATA[\forall ]]></fr:tex> distributes over <fr:tex display="inline"><![CDATA[\land ]]></fr:tex>:
  
  <html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[\forall  x: U. (x \in  A) \leftrightarrow  (x \in  B)]]></fr:tex></html:div>

  
  <fr:tex display="inline"><![CDATA[\equiv  \quad \quad \quad ]]></fr:tex> { Definition of <fr:tex display="inline"><![CDATA[\leftrightarrow ]]></fr:tex> }

  
  <html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[\forall  x: U. ((x \in  A) \rightarrow  (x \in  B)) \land  ((x \in  B) \rightarrow  (x \in  A))]]></fr:tex></html:div>

  
  <fr:tex display="inline"><![CDATA[\equiv  \quad \quad \quad ]]></fr:tex> { <fr:tex display="inline"><![CDATA[\forall ]]></fr:tex> distributes over <fr:tex display="inline"><![CDATA[\land ]]></fr:tex> }

  
  <html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[(\forall  x: U. (x \in  A) \rightarrow  (x \in  B)) \land  (\forall  x: U. (x \in  B) \rightarrow  (x \in  A))]]></fr:tex></html:div>

  
  <fr:tex display="inline"><![CDATA[\equiv  \quad \quad \quad ]]></fr:tex> { Definition of <fr:tex display="inline"><![CDATA[\subseteq ]]></fr:tex> }

  
  <html:div style="margin-left: 30px"><fr:tex display="inline"><![CDATA[(A \subseteq  B) \land  (B \subseteq  A)]]></fr:tex></html:div></html:li></html:ul>
                    <html:p>But saying "there always has to be a universal set <fr:tex display="inline"><![CDATA[U]]></fr:tex>" is kind of equivalent to saying that we want our sets to be <html:em>typed</html:em>: you can't just have "a set", you have to
say what universe the elements are going to be chosen from, <html:em>i.e.</html:em> the type of the elements.</html:p>
                    <html:p>What I would <html:em>really</html:em> like to do is start with some basic type theory, then later introduce sets as <fr:tex display="inline"><![CDATA[\mathrm {Set}(T) \equiv  T \to  2]]></fr:tex>, and build up from there.  But that would be a big change.  It's too late for this semester, but maybe next year...</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>28</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/0088/</fr:uri>
                    <fr:display-uri>0088</fr:display-uri>
                    <fr:route>/~yorgey/forest/0088/</fr:route>
                    <fr:title text="Re-reading The Goblin Emperor">Re-reading <html:em>The Goblin Emperor</html:em></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This week I've re-read Katherine Addison's <html:em>The Goblin Emperor</html:em> for the third time.  It's not the kind of thing I usually read; I usually can't stand a lot of politics (for example, I found Kim Stanley Robinson's Mars trilogy tiresome at times).  But there is something so wholesome and inspiring about a character who has a lot of power but works very hard to Do The Right Thing in the midst of a system rife with corruption and greed.</html:p>
                    <html:p>The week before, I read the third book in the spin-off <html:em>Chronicles of Osreth</html:em> trilogy, <html:em>The Tomb of Dragons</html:em>. I enjoy them for similar reasons to <html:em>The Goblin Emperor</html:em>, and I also enjoy the more mystery/detective slant.  I thought I had already read the first two books in the series, but it turns out that I only read the first—oops!  There were multiple references in the third book to things I didn't remember, which I initially chalked up to having read the second book too long ago, but it turns out it was because I actually haven't read it at all.  So I decided I will go back and re-read the first book (<html:em>Witness for the Dead</html:em>) before reading the second, but then I figured I might as well go all the way back and re-read <html:em>The Goblin Emperor</html:em> first.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>3</fr:month>
                  <fr:day>6</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W09/</fr:uri>
                <fr:display-uri>2026-W09</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W09/</fr:route>
                <fr:title text="Weeknotes for 6 March 2026 (week 9)">Weeknotes for 6 March 2026 (week 9)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>14</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00BN/</fr:uri>
                    <fr:display-uri>00BN</fr:display-uri>
                    <fr:route>/~yorgey/forest/00BN/</fr:route>
                    <fr:title text="Swarm module export">Swarm module export</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Earlier this week I was hacking on <fr:link href="https://github.com/swarm-game/swarm" type="external">Swarm</fr:link>, adding an <html:code>export</html:code> construct that allows you to re-export either individual names or entire modules from a given module.  I thought this was going to be easy, but I couldn't figure out how to make it work.  I finally realized that I had been Doing It Wrong™: after typechecking, I was doing a second pass over the type-annotated syntax tree for a module to collect up the names and types of things that should be exported.  But with <html:code>export</html:code> in the mix, there was no longer enough information to figure this out just by looking at the syntax (even when fully type-annotated).  The correct (and obvious in retrospect) thing to do is to instead collect up exported names and their types <html:em>during</html:em> typechecking.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>14</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00BM/</fr:uri>
                    <fr:display-uri>00BM</fr:display-uri>
                    <fr:route>/~yorgey/forest/00BM/</fr:route>
                    <fr:title text="Theorems with both constructive and non-constructive proofs">Theorems with both constructive and non-constructive proofs</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've been working on writing up some advanced, optional notes for my Discrete Mathematics students (mostly second-year undergraduates) on classical vs constructive logic, and I wanted a good example of a theorem with both non-constructive and constructive proofs.</html:p>
                    <html:p>A typical example of a non-constructive proof is of the infinitude of primes: for any natural number <fr:tex display="inline"><![CDATA[n]]></fr:tex>, we consider the number <fr:tex display="inline"><![CDATA[n! + 1]]></fr:tex>: either it is prime, or it is divisible by one which must be larger than <fr:tex display="inline"><![CDATA[n]]></fr:tex>, since <fr:tex display="inline"><![CDATA[n! + 1]]></fr:tex> is clearly not divisible by anything <fr:tex display="inline"><![CDATA[\leq  n]]></fr:tex>.  This is supposedly nonconstructive since it uses LEM to conclude that <fr:tex display="inline"><![CDATA[n!+1]]></fr:tex> is either prime or not, but this is totally unsatisfactory to me.  Since primality is decidable, this instance of LEM is actually constructively provable, and the whole proof immediately becomes an algorithm for computing a prime larger than any <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>(Another typical "example" is the so-called proof by contradiction that <fr:tex display="inline"><![CDATA[\sqrt {2}]]></fr:tex> is irrational; but of course, it is not a proof by contradiction at all.)</html:p>
                    <html:p>I <fr:link href="https://mathstodon.xyz/@byorgey/116161000975437554" type="external">asked for examples on Mastodon</fr:link>, which led to a very interesting discussion.</html:p>
                    <html:ul><html:li><fr:link href="https://mathstodon.xyz/@nemo@camp.crates.im/116161539623110695" type="external">Henrý Ólson suggested</fr:link> the theorem "there exist irrational <fr:tex display="inline"><![CDATA[a]]></fr:tex> and <fr:tex display="inline"><![CDATA[b]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a^b]]></fr:tex> is rational".
  <html:ul><html:li>The nonconstructive proof uses LEM: <fr:tex display="inline"><![CDATA[\sqrt {2}^{\sqrt {2}}]]></fr:tex> is either rational or not; if so, it satisfies the theorem, and if not, <fr:tex display="inline"><![CDATA[(\sqrt {2}^{\sqrt {2}})^{\sqrt {2}} = 2]]></fr:tex> does.</html:li>
    <html:li>Constructively, we can show that <fr:tex display="inline"><![CDATA[\lg  9]]></fr:tex> is irrational and that <fr:tex display="inline"><![CDATA[(\sqrt  2)^{\lg  9} = 3]]></fr:tex>.</html:li></html:ul>
  This is covered by Andrej Bauer in <fr:link href="https://math.andrej.com/2016/10/10/five-stages-of-accepting-constructive-mathematics/" type="external">Five Stages of Accepting Constructive Mathematics</fr:link>, but I had forgotten it.  It's a pretty good example to show to undergraduates, since the proof with LEM is very clearly nonconstructive, and the whole thing (including proofs of irrationality for <fr:tex display="inline"><![CDATA[\sqrt {2}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\lg  9]]></fr:tex>) requires only some basic number theory.
  </html:li>

  <html:li>I came up with the theorem "For every natural <fr:tex display="inline"><![CDATA[n]]></fr:tex>, there exists <fr:tex display="inline"><![CDATA[m > n]]></fr:tex> which is not square".
  <html:ul><html:li>Both the nonconstructive and constructive proofs depend on the (constructively proved) lemma that if <fr:tex display="inline"><![CDATA[m]]></fr:tex> is square then <fr:tex display="inline"><![CDATA[m+1]]></fr:tex> is not.</html:li>
    <html:li>The nonconstructive proof proceeds by contradiction: suppose every <fr:tex display="inline"><![CDATA[m > n]]></fr:tex> is square.  Then in particular <fr:tex display="inline"><![CDATA[n+1]]></fr:tex> and <fr:tex display="inline"><![CDATA[n+2]]></fr:tex> are square, but the lemma immediately yields a contradiction.</html:li>
    <html:li>The constructive proof considers <fr:tex display="inline"><![CDATA[(n+1)^2+1]]></fr:tex>, which is immediately seen to be non-square by the lemma.</html:li></html:ul>
  Jim Kingdon <fr:link href="https://mathstodon.xyz/@soaproot@sfba.social/116163371993733542" type="external">protested</fr:link>, not unreasonably, that the nonconstructive proof has a similar problem as the proof of infinitude of primes. Since the property of being square is decidable, one can turn the nonconstructive proof into a constructive one fairly easily: just decide whether <fr:tex display="inline"><![CDATA[n+1]]></fr:tex> is a square; if not, we have our non-square, and if so, the lemma tells us <fr:tex display="inline"><![CDATA[n+2]]></fr:tex> must be non-square.  This is true, but I still like this example a bit better than the infinitude of primes: that one directly uses an instance of LEM which is constructively provable, whereas this one uses a proof by contradiction.
  </html:li>

  <html:li>Jim Kingdon <fr:link href="https://mathstodon.xyz/@soaproot@sfba.social/116163239275063779" type="external">also gave another example</fr:link>, <fr:link href="https://en.wikipedia.org/wiki/B%C3%A9zout's_identity" type="external">Bézout's identity</fr:link>.  This seems like a nice example, and one that is accessible to undergraduates, but I'm still confused about it!
  <html:ul><html:li>The constructive proof is via the <fr:link href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm" type="external">Extended Euclidean Algorithm</fr:link>.</html:li>
    <html:li>The typical non-constructive proof considers the set <fr:tex display="block"><![CDATA[\{ax + by \mid  a, b \in  \Z , ax + by > 0\}]]></fr:tex> and notes that it must have a smallest element by the well-ordering property, then proceeds to prove that this smallest positive element is in fact the GCD of <fr:tex display="inline"><![CDATA[a]]></fr:tex> and <fr:tex display="inline"><![CDATA[b]]></fr:tex>.  Intuitively, this seems clearly non-constructive, since it does not actually help you compute the smallest element of the set.  But I am still a bit confused about where exactly a classical axiom ends up getting used.  The version of the well-ordering principle which says that <html:em>every</html:em> set has a well-order implies the Axiom of Choice; but we surely don't need such a big hammer here.  We are simply using the version that applies to subsets of natural numbers, which is constructively provable (in fact, it is logically equivalent to induction).  The answer seems to be that the <fr:link href="https://unimath.github.io/agda-unimath/elementary-number-theory.well-ordering-principle-natural-numbers.html" type="external">constructive well-ordering principle for the natural numbers requires membership of the set to be decidable</fr:link>, and deciding whether there exist integers <fr:tex display="inline"><![CDATA[a]]></fr:tex> and <fr:tex display="inline"><![CDATA[b]]></fr:tex> such that <fr:tex display="inline"><![CDATA[ax + by = n]]></fr:tex> for a particular <fr:tex display="inline"><![CDATA[n]]></fr:tex> is nontrivial.  If you just throw LEM at it, you get the nonconstructive proof.  Or if you work harder, you can actually decide this via the Extended Euclidean Algorithm.</html:li></html:ul></html:li></html:ul>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>3</fr:month>
                  <fr:day>13</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W10/</fr:uri>
                <fr:display-uri>2026-W10</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W10/</fr:route>
                <fr:title text="Weeknotes for 13 March 2026 (week 10)">Weeknotes for 13 March 2026 (week 10)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>13</fr:day>
                    </fr:date>
                    <fr:title text="AI vegetarian">AI vegetarian</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've been thinking for a while about publishing an official statement regarding my stance on LLMs (and other generative AI systems), but it always felt too daunting to express what I wanted to express.  But I recently found several things other people had written that captured my position pretty well, so I <fr:link href="/~yorgey/forest/009L/" title="Statement on LLMs" uri="http://ozark.hendrix.edu/~yorgey/forest/009L/" display-uri="009L" type="local">finally published a statement</fr:link>.  I still want to write something for my students in particular, but I'm still thinking about that.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>13</fr:day>
                    </fr:date>
                    <fr:title text="Blog post series on constructive logic">Blog post series on constructive logic</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Following last week's discussion on <fr:link href="/~yorgey/forest/00BM/" title="Theorems with both constructive and non-constructive proofs" uri="http://ozark.hendrix.edu/~yorgey/forest/00BM/" display-uri="00BM" type="local">Theorems with both constructive and non-constructive proofs</fr:link>, I realized that there is something of a gap in the pedagogical materials available on constructive logic, and the difference between classical and constructive logic. There are many hand-wavy, intuitive explanations of constructive vs non-constructive proofs in, say, slide decks used for teaching undergraduate Discrete Math courses.  There is also lots of advanced material, such as Andrej Bauer's paper <fr:link href="https://math.andrej.com/2016/10/10/five-stages-of-accepting-constructive-mathematics/" type="external">Five Stages of Accepting Constructive Mathematics</fr:link>, the <fr:link href="https://homotopytypetheory.org/book/" type="external">HoTT book</fr:link>, and others.  However, there does not seem to be much intermediate-level material.  So I plan to write a series of blog posts aimed at people who are familiar with typed functional programming, and perhaps have even heard of the Curry-Howard correspondence, and perhaps have even played with a theorem prover such as Agda or Lean, but who don't know the actual formal details of classical vs constructive logic.</html:p>
                    <html:p>Earlier this week I started drafting some ideas on paper; I hope this week or next to find some time to start writing it up more formally.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>28</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00CG/</fr:uri>
                    <fr:display-uri>00CG</fr:display-uri>
                    <fr:route>/~yorgey/forest/00CG/</fr:route>
                    <fr:title text="Disco: exhaustiveness checking for arithmetic patterns">Disco: exhaustiveness checking for arithmetic patterns</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A couple summers ago, my student <fr:link href="/~yorgey/forest/colin-phillips/" title="Colin Phillips" uri="http://ozark.hendrix.edu/~yorgey/forest/colin-phillips/" display-uri="colin-phillips" type="local">Colin Phillips</fr:link> implemented exhaustiveness checking for <fr:link href="/~yorgey/forest/000N/" title="Disco" uri="http://ozark.hendrix.edu/~yorgey/forest/000N/" display-uri="000N" type="local">Disco</fr:link>, following <fr:link href="https://al.radbox.org/doi/10.1145/3408989" type="external">Lower your guards: a compositional pattern-match coverage checker</fr:link> by Graf, Peyton Jones, and Scott.  So it can now do things like
<html:pre><![CDATA[Disco> f : Unit + (Bool * Nat) -> Int
Disco> f(right(False, n)) = 3
Warning: the function f is undefined for some inputs. For example:
f(left(■)) = ...
f(right(true, 0)) = ...
f(right(true, 1)) = ...]]></html:pre>
  However, Disco also has <html:em>arithmetic patterns</html:em>, like
<html:pre><![CDATA[f : N -> N
f(2n) = n + 1
f(2n+1) = 3]]></html:pre>
but doing coverage checking for these is tricky in general. Quick, for what values (if any) is the below (partial) function undefined?
<html:pre><![CDATA[f : N -> N
f(3n) = 0
f(1+5n) = 1
f(2n+2) = 2
f(n+12) = 3]]></html:pre>
My student <fr:link href="/~yorgey/forest/katherine-reid/" title="Katherine Reid" uri="http://ozark.hendrix.edu/~yorgey/forest/katherine-reid/" display-uri="katherine-reid" type="local">Katherine Reid</fr:link> was working on a library for solving this problem, via the theory of <fr:link href="https://en.wikipedia.org/wiki/Generalized_arithmetic_progressionSemilinear_sets" type="external">semilinear sets</fr:link>, but we never quite finished incorporating it into the Disco coverage checker.  Since I'm using Disco to teach again this semester, I've started working on this again.  This week, I mostly just spent some time understanding the existing code and writing down a list of the reamining tasks.  I'm optimistic I can get it polished up and merged before the end of the semester.
  </html:p>
                    <html:p>(<html:em>Answer: the function is undefined for <fr:tex display="inline"><![CDATA[5]]></fr:tex> and <fr:tex display="inline"><![CDATA[7]]></fr:tex>.</html:em>)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>13</fr:day>
                    </fr:date>
                    <fr:title text="Swarm export and arrays">Swarm export and arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Finally, over in <fr:link href="/~yorgey/forest/000O/" title="Swarm" uri="http://ozark.hendrix.edu/~yorgey/forest/000O/" display-uri="000O" type="local">Swarm</fr:link> land, I've continued polishing up <fr:link href="/~yorgey/forest/00BN/" title="Swarm module export" uri="http://ozark.hendrix.edu/~yorgey/forest/00BN/" display-uri="00BN" type="local">Swarm module export</fr:link>.  I've also started working on adding an <fr:link href="https://github.com/swarm-game/swarm/issues/98" type="external">immutable array type</fr:link> to the language—not difficult, but enjoyable.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>3</fr:month>
                  <fr:day>20</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W11/</fr:uri>
                <fr:display-uri>2026-W11</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W11/</fr:route>
                <fr:title text="Weeknotes for 20 March 2026 (week 11)">Weeknotes for 20 March 2026 (week 11)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Really didn't have time to do much of anything this week besides grading, course prep, meeting with students in office hours, and administrative tasks as the chair of my department.  The only interesting things I did were to work a bit more on <fr:link href="https://github.com/swarm-game/swarm/issues/98" type="external">immutable arrays in Swarm</fr:link>, and record an interview for the <fr:link href="https://haskell.foundation/podcast/" type="external">Haskell Interlude</fr:link> with <fr:link href="/~yorgey/forest/sam-frohlich/" title="Sam Frohlich" uri="http://ozark.hendrix.edu/~yorgey/forest/sam-frohlich/" display-uri="sam-frohlich" type="local">Sam Frohlich</fr:link> and <fr:link href="/~yorgey/forest/farhad-mehta/" title="Farhad Mehta" uri="http://ozark.hendrix.edu/~yorgey/forest/farhad-mehta/" display-uri="farhad-mehta" type="local">Farhad Mehta</fr:link>, which was fun.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>3</fr:month>
                  <fr:day>27</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W12/</fr:uri>
                <fr:display-uri>2026-W12</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W12/</fr:route>
                <fr:title text="Weeknotes for 27 March 2026 (week 12)">Weeknotes for 27 March 2026 (week 12)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Weeknotes, Spring Break edition! (For non-US readers: Spring Break is (typically) one week off from classes, approximately in the middle of the spring semester.)  This has been a relaxing and productive week with no classes to teach.</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Immutable arrays in Swarm">Immutable arrays in Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>3</fr:month>
                          <fr:day>27</fr:day>
                        </fr:date>
                        <fr:title text="Challenge scenarios requring arrays">Challenge scenarios requring arrays</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Continuing my work on <fr:link href="https://github.com/swarm-game/swarm/issues/98" type="external">immutable arrays in Swarm</fr:link>, this week I was playing around with creating some challenge scenarios that require the use of arrays. This is actually somewhat tricky, since you can always simulate arrays with functions—it's just less efficient.  So the general idea is to construct scenarios with a time limit, where you need the efficiency of an array to be able to get a solution that is fast enough. But even this is tricky!</html:p>
                        <html:p>My first attempt just involved a row of randomly generated capital letters that you are supposed to sort alphabetically.  I thought you could read them all into an array and pick them up at the same time, sort the array, then lay them out in sorted order.  However, I realized that you can just pick them all up, then iterate through the capital letters one at a time in order, and place any that you happen to have of each.</html:p>
                        <html:p>I constructed another scenario that I thought would work: there is a "key" row of randomly permuted capital letters, and another row of randomly generated capital letters.  You must sort the second row, but in the order specified by the permutation in the first row.  However, I realized there's a clever way to accomplish this in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time without using an array: (1) pick up all the items to be sorted; (2) scan through the key permutation, going one recursive call deeper with each item, so the recursion stack ends up storing the entire sequence; (3) unwind the recursion stack while walking along the destination row in reverse; for each item of the permutation, place all the copies of it you have in your inventory.</html:p>
                        <html:p>Having written this, I think I should go back to my original idea, but use randomly generated strings instead of individual capital letters.  That way, the range of possible values is huge, so there's no way to simply iterate through them in order and place any that you happen to have.  (Currently, there's no way to iterate through items in your inventory...)</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>3</fr:month>
                          <fr:day>27</fr:day>
                        </fr:date>
                        <fr:title text="Minimal API for immutable arrays">Minimal API for immutable arrays</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>It's also been interesting to think about a good minimal API for immutable arrays.  Elimination forms are easy: we just need <html:code>index : Array a -&gt; Int -&gt; a</html:code> and <html:code>size : Array a -&gt; Int</html:code>.  But what about introduction forms? At this point I've implemented <html:code>unfold : b -&gt; (b -&gt; Unit + (a * b)) -&gt; Array a</html:code> (as well as an effectful variant), but I'm starting to think that's not good enough: it assumes that you can generate the array elements in order, all at once.  Instead, I think we really want something like:
<html:pre><![CDATA[accum : a -> (a -> a -> a) -> b -> (b -> Unit + (Int * a * b)) -> Array a]]></html:pre>
  which unfolds (index, value) pairs starting from a seed value, starting with the default value and using the combining function for multiple values at the same index.  In Haskell you would write this as <html:code>Monoid a =&gt; [(Int, a)] -&gt; Array a</html:code> but Swarm has no type classes and we don't want arrays to depend on lists, so we encode the monoid constraint via the first two arguments, and encode the list via an unfold.
  </html:p>
                        <html:p>Is there a simpler way to do this?</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Applicative inference">Applicative inference</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I had a nice meeting with <fr:link href="/~yorgey/forest/andrey-mokhov/" title="Andrey Mokhov" uri="http://ozark.hendrix.edu/~yorgey/forest/andrey-mokhov/" display-uri="andrey-mokhov" type="local">Andrey Mokhov</fr:link> to see if we might collaborate on my <fr:link href="/~yorgey/forest/000P/" title="Applicative inference" uri="http://ozark.hendrix.edu/~yorgey/forest/000P/" display-uri="000P" type="local">Applicative inference</fr:link> research project.  Not sure yet where it will go, but neither of us is under any particular pressure to publish, so I'm content to just let it play out at whatever pace makes sense.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Exhaustiveness checking for arithmetic patterns in Disco">Exhaustiveness checking for arithmetic patterns in Disco</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I continued working on <fr:link href="/~yorgey/forest/00CG/" title="Disco: exhaustiveness checking for arithmetic patterns" uri="http://ozark.hendrix.edu/~yorgey/forest/00CG/" display-uri="00CG" type="local">this project from a couple weeks ago</fr:link>.  I made some progress with typechecking and desugaring of arithmetic patterns.  All that's left is to actually plug them into the exhaustiveness checker itself, and make it call out to the semilinear set solver appropriately... but after staring at it for a while, I realized I have no idea how the exhaustiveness checker works!  I suspect some refactoring will be needed, since there doesn't seem to be an obvious place to just stick in some extra code for arithmetic patterns.  Thankfully, the student who wrote it is still around; I hope we can meet about it soon and figure it out together.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>3</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Kattis">Kattis</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I had fun this week solving a few <fr:link href="https://open.kattis.com/" type="external">Kattis</fr:link> problems in Haskell.  One particularly interesting problem was <fr:link href="https://open.kattis.com/problems/metrolines" type="external">Metro Lines</fr:link>: there is a line of stops numbered <fr:tex display="inline"><![CDATA[0]]></fr:tex> to <fr:tex display="inline"><![CDATA[N]]></fr:tex>, and we are given a bunch (up to <fr:tex display="inline"><![CDATA[2 \times  10^5]]></fr:tex>) of subway lines, each of which has a cost <fr:tex display="inline"><![CDATA[c]]></fr:tex> and visits all the stops between <fr:tex display="inline"><![CDATA[l]]></fr:tex> and <fr:tex display="inline"><![CDATA[r]]></fr:tex> inclusive.  You can get on and off of any line anywhere you want; it costs <fr:tex display="inline"><![CDATA[c \cdot  |x-y|]]></fr:tex> to ride from <fr:tex display="inline"><![CDATA[x]]></fr:tex> to <fr:tex display="inline"><![CDATA[y]]></fr:tex>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is the cost of the line.  We're supposed to print out the cheapest fare to get from station <fr:tex display="inline"><![CDATA[0]]></fr:tex> to each station from <fr:tex display="inline"><![CDATA[1]]></fr:tex> through <fr:tex display="inline"><![CDATA[N]]></fr:tex>.</html:p>
                    <html:p>Try solving it yourself, or click to expand my solution sketch below!</html:p>
                    <fr:tree show-metadata="false" expanded="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>3</fr:month>
                          <fr:day>27</fr:day>
                        </fr:date>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>3</fr:month>
                          <fr:day>28</fr:day>
                        </fr:date>
                        <fr:title text="Solution sketch for Metro Lines (spoiler)">Solution sketch for <fr:link href="https://open.kattis.com/problems/metrolines" type="external">Metro Lines</fr:link> (spoiler)</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>The solution is to sort all the line endpoints, then scan through from left to right, keeping track of a set of active lines, sorted by cost (I just used a <html:code>Set</html:code> of <fr:tex display="inline"><![CDATA[(\mathit {cost}, \mathit {line ID})]]></fr:tex> pairs).  For each segment <fr:tex display="inline"><![CDATA[(k,k+1)]]></fr:tex>, we then know the cost <fr:tex display="inline"><![CDATA[c]]></fr:tex> of the cheapest line which operates on that segment. The key insight is that since we can get on and off whenever we want, we can independently choose the cheapest line for each one-unit segment; since the cost is linear in the length of the ride, we can just independently add up the cost <fr:tex display="inline"><![CDATA[c]]></fr:tex> of each one-unit segment to get the total cost.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>4</fr:month>
                  <fr:day>4</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W13/</fr:uri>
                <fr:display-uri>2026-W13</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W13/</fr:route>
                <fr:title text="Weeknotes for 3 April 2026 (week 13)">Weeknotes for 3 April 2026 (week 13)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>3</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00GM/</fr:uri>
                    <fr:display-uri>00GM</fr:display-uri>
                    <fr:route>/~yorgey/forest/00GM/</fr:route>
                    <fr:title text="Introduction forms for immutable arrays">Introduction forms for immutable arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>After mentioning it in last week's weeknotes, I <fr:link href="https://mathstodon.xyz/@monoidmusician@tech.lgbt/116309751306965503" type="external">got some great feedback</fr:link> from <fr:link href="https://mathstodon.xyz/@monoidmusician@tech.lgbt" type="external">Verity</fr:link> on an introduction form for immutable arrays.  (Again, the biggest constraint here is that we don't want to use lists: Swarm <html:em>does</html:em> have lists, but not built-in in a primitive way.  Using lists requires you to first unlock algebraic data types as well as recursive types, and you should be able to unlock and use arrays independently.)</html:p>
                    <html:p>After a bit of back and forth, the current best idea is
<html:pre><![CDATA[(Int -> a) -> b -> (b -> Unit + Int * (a -> (a * b))) -> Array a]]></html:pre>
  <html:ul><html:li>The first argument specifies the starting value at any index.</html:li>
    <html:li>The second argument is a seed value for the unfold.</html:li>
    <html:li>I like to think of the third argument as a protocol for communication between the array constructor and the user, specifying the process for a sort of imperative unfold.
      <html:ul><html:li>The array constructor begins by announcing the current seed value of type <html:code>b</html:code>.</html:li>
        <html:li>The user gets to choose whether to stop, or to continue by specifying an index.</html:li>
        <html:li>The array constructor provides the value of type <html:code>a</html:code> currently at that index.</html:li>
        <html:li>The user then gets to provide a new value of type <html:code>a</html:code>, and a new seed.</html:li></html:ul></html:li></html:ul>
  This is trickier to implement than what I had before (<html:em>e.g.</html:em> it requires several new types of CESK machine continuation frames instead of just one, and in practice, we want to wait until we see which indices are requested before deciding on the final size of the array and filling in any missing values), but ultimately should be fine.  I need to finish up the implementation and play around with it: implement some other simpler introduction forms in terms of it, and try using it for things that were inefficient before.
  </html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>4</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Draft blog post on zero/empty set/void type/monoids etc.">Draft blog post on zero/empty set/void type/monoids etc.</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Inspired by <fr:link href="https://mathstodon.xyz/@cxandru@types.pl/116261508892427847" type="external">a conversation on Mastodon</fr:link>, I've <fr:link href="/~yorgey/forest/00CI/" title="Draft blog post: Dr. How I Learned to Stop Worrying and Love Zero" uri="http://ozark.hendrix.edu/~yorgey/forest/00CI/" display-uri="00CI" type="local">started drafting a blog post</fr:link> on the connections between things like <fr:tex display="inline"><![CDATA[\forall ]]></fr:tex> with an empty domain, functions out of empty types, sum/product/and/or of an empty list, <html:em>etc.</html:em>.  None of this will be at all surprising to experienced Haskell programmers or type theorists, but I hope it may be interesting for some who are just learning.</html:p>
                    <html:p>As these things always happen, when I started expanding my outline into prose, I found that the very first bullet point in the outline expanded into enough material for an entire blog post.  So it may just be very long, or I may split it up into multiple posts... we'll see!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>4</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Teaching induction">Teaching induction</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I had a lot of fun this week teaching my <fr:link href="/~yorgey/forest/0020/" title="MATH 240, Discrete Mathematics" uri="http://ozark.hendrix.edu/~yorgey/forest/0020/" display-uri="0020" type="local">Discrete Math</fr:link> students about <fr:link href="/~yorgey/forest/00CA/" title="Induction" uri="http://ozark.hendrix.edu/~yorgey/forest/00CA/" display-uri="00CA" type="local">induction principles for natural numbers</fr:link>.</html:p>
                    <html:p>On Wednesday I went over a strong induction principle.  When I teach them, I usually state it like
   <fr:tex display="block"><![CDATA[P(0) \land  (\forall  k. (\forall  j \leq  k. P(j)) \to  P(k+1)) \to  \forall  n. P(n)]]></fr:tex>
  I find a formulation without an explicit base case more elegant, but I don't think I am brave enough to teach it this way:
  <fr:tex display="block"><![CDATA[(\forall  k. (\forall  j < k. P(j)) \to  P(k)) \to  \forall  n. P(n)]]></fr:tex>
  I think they would be completely confused by the apparent lack of a base case.  Of course, the base case is still there, in the sense that you have to at the very least prove <fr:tex display="inline"><![CDATA[P(0)]]></fr:tex> with no assumptions, since <fr:tex display="inline"><![CDATA[\forall  j < 0. P(j)]]></fr:tex> is trivial.  But you would essentially have to almost always start by doing a case split on whether <fr:tex display="inline"><![CDATA[n]]></fr:tex> is 0 anyway, so I feel like I might as well present it in a form with <fr:tex display="inline"><![CDATA[P(0)]]></fr:tex> already split out separately.  But I would be interested to hear about how others teach this.  Of course, in some sense it doesn't matter since the two principles are logically equivalent, but I think it matters in a pedagogical sense.</html:p>
                    <html:p>As the <fr:link href="/~yorgey/forest/00CX/" title="Binary expansions" uri="http://ozark.hendrix.edu/~yorgey/forest/00CX/" display-uri="00CX" type="local">crowning example</fr:link>, I proved that every natural number can be written as a sum of distinct powers of two... and then showed them that our induction proof is actually a recursive program for calculating the binary expansion of any natural number, by coding it in Disco:
<html:pre><![CDATA[binary : N -> Set(N)
binary(0) = {}
binary(2k) = {e+1 | e in binary(k)}
binary(2k+1) = {0} union {e+1 | e in binary(k)}]]></html:pre>
I definitely enjoyed seeing several of them get head-exploding expressions on their faces when they realized the correspondence between invoking the induction hypothesis and making a recursive function call.
</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>4</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="A polynomial testing principle">A polynomial testing principle</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've had Conor McBride's paper <fr:link href="https://personal.cis.strath.ac.uk/conor.mcbride/PolyTest.pdf" type="external">A polynomial testing principle</fr:link> on my reading list for a while, and this week I finally got around to reading through it carefully, typing up all the Agda code myself and trying to fill in as much of it as I could before peeking.  I now have some much better ideas about how to encode things nicely in Agda. The topic of the paper was also really fun: I was definitely familiar with the idea that two degree-<fr:tex display="inline"><![CDATA[n]]></fr:tex> polynomials must be equal if they agree at <fr:tex display="inline"><![CDATA[n+1]]></fr:tex> points, but I would not have guessed that this can be proved in a few hundred lines of Agda.  I also enjoyed how it hinged on the forward difference and summation operators, old friends of mine from reading Concrete Mathematics when I was in undergrad.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>4</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>For the past few weeks I have been working on Chopin's 1st piano concerto. This is not the first time I've worked on it, but I haven't in a while.  I have long dreamed of performing it someday.  I always figured this was essentially a pipe dream, but after recently seeing <fr:link href="https://www.youtube.com/watch?v=2bFo65szAP0" type="external">a video of Olga Scheps playing it with a small chamber orchestra</fr:link>, I have a bit more hope that it might be possible! I didn't even realize there was an arrangement for chamber orchestra.  Of course there are arrangements for two pianos as well, though that idea doesn't excite me as much.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>4</fr:month>
                  <fr:day>12</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W14/</fr:uri>
                <fr:display-uri>2026-W14</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W14/</fr:route>
                <fr:title text="Weeknotes for 10 April 2026 (week 14)">Weeknotes for 10 April 2026 (week 14)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Not much to report this week... came down with a nasty cold Monday night and have spent the rest of the week doing not much beyond the bare minimum.</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>4</fr:month>
                      <fr:day>12</fr:day>
                    </fr:date>
                    <fr:title text="Equivalence relations which are the kernel of a (nice) function">Equivalence relations which are the kernel of a (nice) function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I did continue to teach my classes (while masked up) and had a
  nice epiphany while <fr:link href="/~yorgey/forest/00DR/" title="Modular Equivalence" uri="http://ozark.hendrix.edu/~yorgey/forest/00DR/" display-uri="00DR" type="local">teaching about modular equivalence</fr:link>: I used to
  present separate detailed proofs showing that the modular
  equivalence relation is reflexive, symmetric, and transitive... but
  I realized that we can first prove the alternative characterization
  <fr:tex display="inline"><![CDATA[(a \equiv _m b) \leftrightarrow  (a \mathbin {\mathbf {mod}} m = b \mathbin {\mathbf {mod}} m)]]></fr:tex>, and then it
  automatically inherits all the properties of an equivalence relation
  from equality!  Any time we have a relation <fr:tex display="inline"><![CDATA[R]]></fr:tex> such that <fr:tex display="inline"><![CDATA[(x \mathbin {R} y)
  \leftrightarrow  (f(x) = f(y))]]></fr:tex> for some function <fr:tex display="inline"><![CDATA[f]]></fr:tex>, the relation <fr:tex display="inline"><![CDATA[R]]></fr:tex> is
  automatically an equivalence, and if the equality is decidable we also get
  a nice way to decide our relation.  This situation comes up
  all the time in computing (convert strings to lowercase in order to
  decide case-insensitive equality; sort lists in order to compare up
  to permutation; and so on).</html:p>
                    <html:p>I <fr:link href="https://mathstodon.xyz/@byorgey/116388560162882132" type="external">posted about this on Mastodon, which led to a nice discussion</fr:link>. It turns out that given a function <fr:tex display="inline"><![CDATA[f : A \to  B]]></fr:tex>, the equivalence relation on <fr:tex display="inline"><![CDATA[A]]></fr:tex> induced by <fr:tex display="inline"><![CDATA[f]]></fr:tex> (putting each fiber in its own equivalence class) is called the <html:em>kernel</html:em> of <fr:tex display="inline"><![CDATA[f]]></fr:tex>.  Previously, I only knew that term in the sense of the set of elements sent to zero by a group or ring homomorphism, but I guess it's related: in the case of a group or ring homomorphism, there's enough structure to allow us to recover the entire kernel relation on the domain from just the set of elements related to zero, so we might as well use the same term "kernel" for both.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>4</fr:month>
                  <fr:day>18</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W15/</fr:uri>
                <fr:display-uri>2026-W15</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W15/</fr:route>
                <fr:title text="Weeknotes for 17 April 2026 (week 15)">Weeknotes for 17 April 2026 (week 15)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00FY/</fr:uri>
                    <fr:display-uri>00FY</fr:display-uri>
                    <fr:route>/~yorgey/forest/00FY/</fr:route>
                    <fr:title text="Agda proof of the Fundamental Theorem of Arithmetic">Agda proof of the Fundamental Theorem of Arithmetic</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>On Monday, I was idly brainstorming potential final projects for my <fr:link href="https://hendrix-cs.github.io/csci365/" type="external">Functional Programming</fr:link> students.  Having just <fr:link href="/~yorgey/forest/00EG/" title="Fundamental Theorem of Arithmetic" uri="http://ozark.hendrix.edu/~yorgey/forest/00EG/" display-uri="00EG" type="local">taught my Discrete Math students the Fundamental Theorem of Arithmetic</fr:link>, I wondered whether formalizing it in Agda could make a nice project.  (I mean formalizing it <html:em>from scratch</html:em>: of course, the FTA must already in the Agda standard library.)  Then I... kind of fell down the rabbit hole.  Several hours and 560 lines of Agda later, I'm very close: all I have left is to <fr:link href="/~yorgey/forest/00DL/" title="Proof of Division Algorithm" uri="http://ozark.hendrix.edu/~yorgey/forest/00DL/" display-uri="00DL" type="local">prove that the result of the division algorithm is unique</fr:link> (which is actually kinda tricky).  Well... actually, I've only formalized half of the FTA so far, namely, the part that says any number can be factored into a product of primes.  I haven't yet attempted to formalize the claim that the resulting factorization is unique up to permutation.  We'll see if I decide to add that.</html:p>
                    <html:p>In any case, this has been a fun and pleasant exercise, requiring a bunch of facts about addition, multiplication, and inequality; well-founded induction; encoding loops from a start value up to an end value; and various other things.  I've been doing everything completely from scratch/memory, without peeking at any Agda stdlib code. Once I finish it I might clean it up and turn it into a blog post.</html:p>
                    <html:p>Formalizing the proof has led me to rethink a few of the wys I present things in Discrete Math.  For example, I had been defining a number <fr:tex display="inline"><![CDATA[p]]></fr:tex> to be prime if "all divisors of <fr:tex display="inline"><![CDATA[p]]></fr:tex> are trivial", that is, formally, <fr:tex display="block"><![CDATA[\mathrm {Prime}(p) \equiv  \forall  {d}: {\mathbb {N}}.\;{(d \mid  p) \to  (d = 1 \lor  d = p)}.]]></fr:tex>  But now I actually think it is better to define it as "<fr:tex display="inline"><![CDATA[p]]></fr:tex> has no nontrivial divisors", that is, <fr:tex display="block"><![CDATA[\mathrm {Prime}(p) \equiv  \forall  {d}: {(1 < d < n) \to  (d \nmid  p)}.\;.]]></fr:tex>  Since primality is decidable, these are constructively equivalent, but... I like the second definition better now, for reasons I can't quite put my finger on.
  </html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>4</fr:month>
                  <fr:day>25</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W16/</fr:uri>
                <fr:display-uri>2026-W16</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W16/</fr:route>
                <fr:title text="Weeknotes for 24 April 2026 (week 16)">Weeknotes for 24 April 2026 (week 16)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Not much of interest to report this week—a lot of my time has been spent on various administrative responsibilities, as both the chair of my department and the chair of the Committee on Academic Integrity. Next week is the last week of classes, so over the next few weeks I should start to have more time to work on interesting projects.</html:p>
                <html:p>I did complete my <fr:link href="/~yorgey/forest/00FY/" title="Agda proof of the Fundamental Theorem of Arithmetic" uri="http://ozark.hendrix.edu/~yorgey/forest/00FY/" display-uri="00FY" type="local">Agda proof of the Fundamental Theorem of Arithmetic</fr:link>, and I'd like to turn it into a blog post.  I fancy there might be an audience of people who know the basics of Agda but would benefit from seeing a slightly larger development with lots of careful explanation.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>5</fr:month>
                  <fr:day>3</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W17/</fr:uri>
                <fr:display-uri>2026-W17</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W17/</fr:route>
                <fr:title text="Weeknotes for 1 May 2026 (week 17)">Weeknotes for 1 May 2026 (week 17)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>3</fr:day>
                    </fr:date>
                    <fr:title text="Wrapping up the semester">Wrapping up the semester</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Friday, May 1 was the last day of classes for the semester.  There is still plenty of work to do over the next two weeks (final exams / final project presentations, grading, dealing with cases of academic misconduct, <html:em>etc.</html:em>) but the pace will be much more relaxed. I'm looking forward to slowly ramping up some summer projects.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>3</fr:day>
                    </fr:date>
                    <fr:title text="Thoughts on Forester for lecture notes">Thoughts on Forester for lecture notes</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Using Forester to write up <fr:link href="/~yorgey/forest/0021/" title="Discrete Mathematics Spring 2026 lecture notes" uri="http://ozark.hendrix.edu/~yorgey/forest/0021/" display-uri="0021" type="local">lecture notes for my Discrete Mathematics course</fr:link> has been a resounding success. Writing them in this medium forced me to think much more carefully about how things are organized and presented, which in many cases led me to make substantive changes for the better, despite having taught this course many times before.  I think the students also found it helpful to have the notes available in an easily searchable and hyperlinked format.  One of the things I want to do over the next few weeks is to go through the notes to clean some things up, add more hyperlinks, and add some extended/optional material in cases where I didn't have time during the semester, possibly put together a simple preprocessor that will allow me to embed <fr:link href="/~yorgey/forest/000S/" title="Diagrams" uri="http://ozark.hendrix.edu/~yorgey/forest/000S/" display-uri="000S" type="local">Diagrams</fr:link> code—but overall I think the notes are in really great shape.  I definitely plan to do something similar for other courses in the future.  Next up will be my <fr:link href="https://hendrix-cs.github.io/csci382/" type="external">Algorithms</fr:link> course in the fall, I think.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>3</fr:day>
                    </fr:date>
                    <fr:title text="&quot;To my students&quot;">"To my students"</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>On Monday, I published a piece I had been working on for a while, unimaginatively titled <fr:link href="/~yorgey/forest/00FD/" title="To my students" uri="http://ozark.hendrix.edu/~yorgey/forest/00FD/" display-uri="00FD" type="local">To my students</fr:link>. This year in particular, it felt increasingly disingenuous to say nothing about the current political and technological climate—but I am not good at speaking extemporaneously about such weighty topics, so I decided to write something instead. When it was finished, I emailed a link to my students, and posted a link on Mastodon.  I was not expecting the magnitude of the response.</html:p>
                    <html:p>I heard from many current students who were appreciative, and had interesting conversations with several of them.  My piece apparently got posted to a much wider student community via social media.  My Mastodon post got much more traction than my posts usually do (though 120 boosts hardly counts as "going viral").  It was also posted to Hacker News, and I made the mistake of reading some of the comments. I heard from a few random strangers for whom the piece resonated particularly strongly. I also heard from someone who was my student when I taught high school math 20 years ago.</html:p>
                    <html:p>With the exception of the Hacker News comments, overall the experience was very positive and encouraging.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>3</fr:day>
                    </fr:date>
                    <fr:title text="Mutable and immutable arrays and CESK machines">Mutable and immutable arrays and CESK machines</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I have continued working on immutable arrays in Swarm, but have been stymied by the complexity of implementing a <fr:link href="/~yorgey/forest/00GM/" title="Introduction forms for immutable arrays" uri="http://ozark.hendrix.edu/~yorgey/forest/00GM/" display-uri="00GM" type="local">fully general introduction form</fr:link> via a CESK machine. Trying to implement it from scratch was breaking my brain, so I tried implementing it in pure Haskell, then doing a manual CPS transformation followed by manual defunctionalization, to try to more mechanically derive the required CESK implementation, but even that was breaking my brain.</html:p>
                    <html:p>I finally realized this morning that perhaps I have been thinking about this all wrong.  I started out implementing only <html:em>immutable</html:em> arrays because I thought it would be <html:em>simpler</html:em>—and I figured I would introduce mutable arrays later.  But the need for such complicated introduction forms could be circumvented entirely with mutable arrays. That is, I think I will stick with a simple yet impoverished introduction form for immutable arrays for now (<html:code>unfoldArray : b -&gt; (b -&gt; (Unit + a*b)) -&gt; Array a</html:code>), and then later introduce mutable arrays along with a copying <html:code>freezeArray : MArray a -&gt; Array a</html:code>.  Although thinking about general introduction forms for immutable arrays has been interesting, I think this will be a lot simpler and more robust.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>3</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've continued working on the Chopin 1st concerto.  I'm close to being able to play the entire first movement—only the coda still needs significant work.  Over the summer I want to continue working on the concerto while also being more systematic about practicing other things in my repertoire and possibly learning some other, shorter, new pieces as well.</html:p>
                    <html:p>Through an unlikely series of events, it looks like I may have an opportunity to acquire a free (!!) 2002 <fr:link href="https://www.alamomusic.com/blogs/whats-new/the-studio-standard-yamaha-c7-grand-piano-review-and-demo" type="external">Yamaha C7 grand piano</fr:link> for my church.  This is one of the absolute best pianos on the market, and typically costs something like $20k-30k used; a brand-new Yamaha C7X, the successor model, costs about $90k. Getting one for free still seems too good to be true, but I am warily optimistic.  I will certainly write about it (with pictures) if it does indeed come together!  In that case I will almost certainly be spending more time at my church just to play it... I love my Yamaha T118 upright, but it can't compare with a 7'6" Yamaha grand.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>5</fr:month>
                  <fr:day>10</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W18/</fr:uri>
                <fr:display-uri>2026-W18</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W18/</fr:route>
                <fr:title text="Weeknotes for 8 May 2026 (week 18)">Weeknotes for 8 May 2026 (week 18)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>10</fr:day>
                    </fr:date>
                    <fr:title text="Still wrapping up the semester...">Still wrapping up the semester...</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Last week I wrote "There is still plenty of work to do... but the pace will be much more relaxed."  I always forget that this is completely false.  Last week was <html:em>not</html:em> more relaxed, it was a zoo.  I can only assume this coming week will be the same (in particular, my department is trying to hire a 1-year visitor at the last minute, and I am the chair of the department and hence the chair of the hiring committee); but there is light at the end of the tunnel.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>10</fr:day>
                    </fr:date>
                    <fr:title text="Pride goeth before the fall">Pride goeth before the fall</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>In last week's piano corner, I said "Through an unlikely series of events, it looks like I may have an opportunity to acquire a free... piano".  I am extremely ashamed to have to write this, but it turns out to have been a scam. (The "piano" was free, but of course the shipping was not...)  Fortunately, I did not end up giving the scammers any money—but only very narrowly.  I actually got as far as attempting to send them money via Venmo, but Venmo stopped the payment because it suspected a scam. This, coupled with a friend's skepticism, finally got me to dig more deeply and uncover incontrovertible proof that the whole thing was a scam all along.</html:p>
                    <html:p>This has been a very humbling and sobering experience.  I like to think of myself as sophisticated, educated, intelligent—just as, I assume, many of us do—and therefore immune to scams or misinformation.  But that seems to have actually made it worse.  I wanted so badly for it to be true that I used my sophisticated, educated intelligence to spin all sorts of justifications for why it was not actually a scam despite the (many!) red flags.</html:p>
                    <html:p>In the end, I am really thankful that I only lost some pride, not money, and I hope that this experience will help me be more careful and less trusting of my own judgment in the future.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>10</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00GN/</fr:uri>
                    <fr:display-uri>00GN</fr:display-uri>
                    <fr:route>/~yorgey/forest/00GN/</fr:route>
                    <fr:title text="Deriving an efficient partition conjugation function">Deriving an efficient partition conjugation function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>On Saturday I was solving a <fr:link href="https://open.kattis.com/problems/keppni" type="external">Kattis problem</fr:link> for which I realized that I needed some Haskell code to efficiently compute the <html:em>conjugate</html:em> of an <fr:link href="https://en.wikipedia.org/wiki/Integer_partition" type="external">integer partition</fr:link>.  That is, if we think of a partition as a <fr:link href="https://en.wikipedia.org/wiki/Integer_partitionFerrers_diagram" type="external">Ferrers diagram</fr:link>, the conjugate is the partition we get by flipping the diagram along the main diagonal.</html:p>
                    <html:p>I managed to write an efficient implementation, and solve the Kattis problem, simply by thinking hard; but it made me wonder whether one could <html:em>derive</html:em> an efficient implementation starting from an obviously-correct yet inefficient specification (via the <fr:link href="https://en.wikipedia.org/wiki/Bird%E2%80%93Meertens_formalism" type="external">Bird-Meertens formalism</fr:link>, <html:em>aka</html:em> Squiggol).  I spent a very pleasant Sunday afternoon trying to work this out and <fr:link href="https://mathstodon.xyz/@byorgey/116546141253551553" type="external">discussing it on Mastodon</fr:link>.  I think I'm quite close to having a completely formal derivation; I hope to turn it all into a proper blog post next week.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>5</fr:month>
                  <fr:day>16</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W19/</fr:uri>
                <fr:display-uri>2026-W19</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W19/</fr:route>
                <fr:title text="Weeknotes for 15 May 2026 (week 19)">Weeknotes for 15 May 2026 (week 19)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>16</fr:day>
                    </fr:date>
                    <fr:title text="Still still wrapping up the semester...">Still still wrapping up the semester...</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This week was even worse than last week: students turning in last-minute assignments at the start of the week, submitting final course grades, dealing with lots of academic integrity (aka cheating) cases (I am the chair of my college's academic integrity committee), conducting a last-minute search for a one-year visiting position (I'm the chair of my department and hence the <html:em>de facto</html:em> chair of the search committee), participating in a half-day workshop for a new first-year course I will be teaching in the fall... and on top of all that, my church has hired a new pastor who will be arriving soon, and there has been a lot of work getting ready for his arrival and organizing his ordination service.  Basically, I find myself in several leadership positions, all of which required more work than usual over the past few weeks in particular!  I definitely didn't have time to write the blog post I promised last week. Fortunately, in all cases there is light at the end of the tunnel: academic integrity stuff is finished; the search is proceeding well after the initial flurry of reading lots of applications; and almost everything is arranged for our new pastor's arrival.  I always hesitate to say "next week will be better", because I am frequently wrong.  But I really do think next week I will be able to start easing into some summer projects.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>5</fr:month>
                  <fr:day>23</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W20/</fr:uri>
                <fr:display-uri>2026-W20</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W20/</fr:route>
                <fr:title text="Weeknotes for 22 May 2026 (week 20)">Weeknotes for 22 May 2026 (week 20)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>This week was indeed much better than <fr:link href="/~yorgey/forest/2026-W19/" title="Weeknotes for 15 May 2026 (week 19)" uri="http://ozark.hendrix.edu/~yorgey/forest/2026-W19/" display-uri="2026-W19" type="local">last week</fr:link>!  There was still a good deal of administrative work, but I actually had time to work on some projects.</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>23</fr:day>
                    </fr:date>
                    <fr:title text="Deriving an efficient conjugate function for integer partitions">Deriving an efficient conjugate function for integer partitions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I finally had more time to work on <fr:link href="/~yorgey/forest/00GN/" title="Deriving an efficient partition conjugation function" uri="http://ozark.hendrix.edu/~yorgey/forest/00GN/" display-uri="00GN" type="local">deriving an efficient integer partition conjugation function</fr:link>.  My optimism of two weeks ago was unfounded—I worked on it a good deal this week but haven't cracked it yet.  But I feel like I have made some good progress, and it's been fun refreshing my memory on stuff from <fr:link href="https://www.librarything.com/work/195696/t/The-Algebra-of-Programming" type="external">The Algebra of Programming</fr:link> and <fr:link href="https://www.cambridge.org/core/books/algorithm-design-with-haskell/824BE0319E3762CE8BA5B1D91EEA3F52" type="external">Algorithm Design with Haskell</fr:link>.  If anyone would be interested in collaborating on this, I'd be happy to jump in a video call.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>23</fr:day>
                    </fr:date>
                    <fr:title text="Open-source maintenance">Open-source maintenance</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The <fr:link href="https://hackage.haskell.org/package/diagrams-solve" type="external">diagrams-solve</fr:link> and <fr:link href="https://hackage.haskell.org/package/diagrams-lib" type="external">diagrams-lib</fr:link> packages are full of uses of partial functions such as <html:code>head</html:code> and <html:code>tail</html:code>, having been written before <fr:link href="https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-List-NonEmpty.html" type="external">Data.List.NonEmpty</fr:link> really existed.  But they generate tons of warnings, and I finally decided to bite the bullet and eliminate the use of partial functions as much as possible.  This has involved some tricky analyses of which lists can be statically known to be nonempty, especially in <html:em>e.g.</html:em> list-heavy code used to compute <fr:link href="https://hackage-content.haskell.org/package/diagrams-lib-1.5.1/docs/Diagrams-TwoD-Segment-Bernstein.html" type="external">operations on Bernstein polynomials</fr:link>, but I made some very good progress this week and the conversion is almost complete.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>23</fr:day>
                    </fr:date>
                    <fr:title text="Swarm">Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>5</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:title text="Immutable arrays">Immutable arrays</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>I have finally finished my <fr:link href="https://github.com/swarm-game/swarm/pull/2701/" type="external">pull request adding immutable arrays to the language</fr:link>!</html:p>
                        <html:p>In the end I was able to come up with a scenario that requires the use of arrays to solve in a reasonable amount of time, but only needs immutable arrays constructed with an <html:code>unfold</html:code> operation: you first "read" a random permutation from a row of letters laid out on the ground, then iterate the permutation a certain number of times and lay the letters back down in the resulting order.  If anyone can think of an efficient way to solve this without the use of an array, I'd love to hear about it!</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>5</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:title text="New contributors, and import bugs">New contributors, and import bugs</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>Swarm has had several new contributors pop up this week, which is fun. <fr:link href="/~yorgey/forest/tom-scheper/" title="Tom Scheper" uri="http://ozark.hendrix.edu/~yorgey/forest/tom-scheper/" display-uri="tom-scheper" type="local">Tom Scheper</fr:link> found a <fr:link href="https://github.com/swarm-game/swarm/issues/2725" type="external">bug which is rather obvious in retrospect</fr:link>—when encountering a module import, we only check the file itself for changes, but not any of its transitive imports.  But this means that if <html:code>A</html:code> imports <html:code>B</html:code>, and you modify <html:code>B</html:code> then re-import <html:code>A</html:code>, you will not actually pick up the changes to <html:code>B</html:code> unless you touch <html:code>A</html:code> as well.  Fixing this is a bit finicky.  We can't just transitively check all imports every time, since we would end up re-checking the same modules repeatedly.  Instead, I think the right idea is to do two passes when processing some top-level source code: first, transitively check its imports looking for any in the module cache that are outdated, and flag them for a reload.  Then, do a second pass where we actually recursively load and check all the modules that need to be loaded, either because they have not been loaded yet or because they are flagged.  I started working on the fix for this a couple days ago and hope to finish soon.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>23</fr:day>
                    </fr:date>
                    <fr:title text="Math search">Math search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>As I briefly mentioned in some previous weeknotes, my department is hiring a Visiting Assistant Professor of Mathematics for next year (kind of at the last minute), and we did a bunch of work on our search this week.  We held virtual interviews with several candidates on Wednesday and Thursday afternoons; the committee then met Friday and decided on one to invite for an on-campus interview; the rest of my afternoon consisted of writing a formal request to the provost and setting up phone conversations with some references.  I'm hopeful we can wrap up the search in the next few weeks.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>23</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This week I pulled out my book of Chopin waltzes and have enjoyed playing through and refreshing them. It turns out there are actually only a few left that I don't know, and they all seem lovely.  I think I might make a side quest for the summer to learn them all; this week I learned No. 13 in D flat major.  Next week I'm going to make an intentional plan for what I want to work on over the summer.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>5</fr:month>
                  <fr:day>29</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W21/</fr:uri>
                <fr:display-uri>2026-W21</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W21/</fr:route>
                <fr:title text="Weeknotes for 29 May 2026 (week 21)">Weeknotes for 29 May 2026 (week 21)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>This week I spent a lot of time helping friends move, fixing Swarm bugs, and working on our search for a 1-year visiting professor.  There's never as much time during the summer to work on big projects as I think there will be, or would like there to be!   But I'm excited to be participating in a "Community of Practice" with other faculty around the book <html:em>Stolen Focus</html:em> by Johann Hari.  I'm also excited to take a quiet creative retreat this coming Tuesday-Thursday—I've booked an AirBnB at a place in the country about 20 minutes away for a couple nights!  Expect a full report in next week's weeknotes.</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>29</fr:day>
                    </fr:date>
                    <fr:title text="Swarm">Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>5</fr:month>
                          <fr:day>29</fr:day>
                        </fr:date>
                        <fr:title text="Fixing transitive import bug">Fixing transitive import bug</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>I fixed the <fr:link href="https://github.com/swarm-game/swarm/issues/2725" type="external">import bug</fr:link> from last week.  Doing two passes was the right general idea, but I didn't have the details right.  My son actually helped me figure out the right way to do it: first do a DFS through the module cache, evicting everything that is outdated or depends on something outdated.  After that, the actual loading code does not need to change!  Any module which depends on something that has changed will have been evicted from the cache, so we are forced to reload and recheck it.  Simple and robust.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" numbered="false">
                      <fr:frontmatter>
                        <fr:authors>
                          <fr:author>
                            <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                          </fr:author>
                        </fr:authors>
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>5</fr:month>
                          <fr:day>29</fr:day>
                        </fr:date>
                        <fr:title text="Exponential import blowup">Exponential import blowup</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p><fr:link href="/~yorgey/forest/ondrejweis/" title="Ondřej Weis" uri="http://ozark.hendrix.edu/~yorgey/forest/ondrejweis/" display-uri="ondrejweis" type="local">Ondřej Weis</fr:link> tried testing the import system and, to my simultaneous shame and joy, easily made it completely fall over.  Shame because I worked really hard on that code and thought it was really clean, elegant, and well-thought out.  Joy, because it's wonderful to have someone point out flaws so they can get fixed.</html:p>
                        <html:p>In particular, if you created a linear chain of modules <fr:tex display="inline"><![CDATA[A \to  B \to  C \to  D \to  \dots ]]></fr:tex> where each imports the next, the amount of time it took to load them from disk was <html:em>exponential</html:em> in the number of modules!  This completely flummoxed me—I was looking for places where a recursive function accidentally called itself twice on the same AST, or something like that.  But once again Ondřej came to the rescue and figured out that it was because of the way we dynamically built up a stack of unresolved effects as we recursed (every level gets its own new, local, <html:code>Accum</html:code> effect to record the imports for each module).  Apparently <html:code>fused-effects</html:code>, the effects library we use, does not deal with this situation well at all (though I still don't understand how it leads to <html:em>exponential</html:em> time complexity)!  In any case, Ondřej fixed it by handling the accumulation effect explicitly.</html:p>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>5</fr:month>
                      <fr:day>29</fr:day>
                    </fr:date>
                    <fr:title text="Math search">Math search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This week was a lot of "hurry up and wait" as I waited through the holiday weekend for people to be able to work on scheduling a candidate visit, then waiting to hear back from various people we needed to schedule a meeting with, waiting to hear back from some students we would like them to meet with...  We finally have the in-person interview all scheduled for this Monday!</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>6</fr:month>
                  <fr:day>6</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W22/</fr:uri>
                <fr:display-uri>2026-W22</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W22/</fr:route>
                <fr:title text="Weeknotes for 5 June 2026 (week 22)">Weeknotes for 5 June 2026 (week 22)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>This week has <html:em>finally</html:em> felt like the start of summer!</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>6</fr:day>
                    </fr:date>
                    <fr:title text="Concluding the Visiting Assistant Professor search!">Concluding the Visiting Assistant Professor search!</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>On Monday of this week, we brought a candidate for an on-campus interview for our 1-year visiting position in mathematics.  We made them an offer on Wednesday, and by Friday they had officially accepted!  I'm looking forward to have a new colleague joining us for next year, and also very glad that the search is over—being the chair of a search committee was a lot of work!</html:p>
                    <html:p>Even though it's official and thus presumably public information, out of an abundance of caution I won't yet mention who it is; I'll probably mention them at some point in the future.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>6</fr:day>
                    </fr:date>
                    <fr:title text="Personal creative retreat">Personal creative retreat</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter><html:p>From Tuesday evening to Thursday morning of this week, I took a
  personal creative retreat. I stayed at an AirBnB out in the country
  about 20 minutes away from my house, in a one-room bungalow located
  on the grounds of a ranch/event/wedding venue.  It was spacious and
  quiet, with plenty of natural light but a lot of big old shade
  trees, so it stayed cool without having to run the A/C unit.  Pretty
  much perfect for working and thinking deeply, and the timing could
  not have been more perfect—right after finally wrapping up our search.</html:p>
  
  <html:img src="/~yorgey/forest/bafkrmig27hzu6q4e4mtbvbdlxn4l2u6ureyhepjevphitncrtfradurnju.jpg" />

<html:p>Over the course of my 36-hour stay I got plenty of sleep, ate
some good food, read part of Martha Wells' <html:em>Queen Demon</html:em>, and also
did about 11 hours worth of focused, deep work, on three main projects.</html:p><fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2026</fr:year><fr:month>6</fr:month><fr:day>27</fr:day></fr:date><fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00H5/</fr:uri><fr:display-uri>00H5</fr:display-uri><fr:route>/~yorgey/forest/00H5/</fr:route><fr:title text="Embedding diagrams in Forester">Embedding diagrams in Forester</fr:title></fr:frontmatter><fr:mainmatter><html:p>I would really like to be able to use <fr:link href="/~yorgey/forest/000S/" title="Diagrams" uri="http://ozark.hendrix.edu/~yorgey/forest/000S/" display-uri="000S" type="local">Diagrams</fr:link> from within
Forester, so I spent a bit of time working on a
<html:code>diagrams-forester</html:code> preprocessor tool.  The idea is that it will look for special sentinel blocks that look like
<html:pre><![CDATA[\diagram{w}{h}{\verb<<<|
  ...
<<<}]]></html:pre>
Then it would run the diagrams code in the <html:code>...</html:code>, and replace the entire <html:code>diagram</html:code> block with an image link.  <html:code>diagram</html:code> would also be defined to produce some kind of dummy placeholder, so the code would be valid Forester code both before and after the preprocessor runs.
</html:p><html:p>I don't want to spend a lot of time on this, but it's definitely worth spending a few hours on this summer, so I wanted to get it off the ground.  So far it can identify and parse the <html:code>diagram</html:code> blocks; I still need to hook it up to the <fr:link href="https://hackage.haskell.org/package/diagrams-builder" type="external"><html:code>diagrams-builder</html:code> package</fr:link> and deal with things like input and output directories and so on.</html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link></fr:author></fr:authors><fr:date><fr:year>2026</fr:year><fr:month>6</fr:month><fr:day>6</fr:day></fr:date><fr:title text="Fixing Swarm code metrics to work with imports">Fixing Swarm code metrics to work with imports</fr:title></fr:frontmatter><fr:mainmatter><html:p>When you complete a <fr:link href="/~yorgey/forest/000O/" title="Swarm" uri="http://ozark.hendrix.edu/~yorgey/forest/000O/" display-uri="000O" type="local">Swarm</fr:link> scenario, in addition to recording your time (both wall-clock and in-game time), it can also record the <html:em>size</html:em> of your code, both in terms of the number of characters and the size of the AST, and it records your best (smallest) scores.  This makes it easy to play code golf (competing with yourself, or with others).</html:p><html:p>However, when I added <html:code>import</html:code> to the language, I completely forgot about this mechanism, and a user recently reported that the game was not counting imports toward the code size, making it possible to game the system by shoving all your code into an import.  Whoops!</html:p><html:p>Fixing this was conceptually straightforward, but nontrivial from an engineering point of view.  First, I decided that I didn't want to do a DFS through the import graph every time we want to measure code size—we already do a DFS through the import graph when loading modules in the first place, so why not just cache some relevant information at that point?  So, I added a field to each module record to store a cached set of *all* its transitive dependencies.  Making sure that field was filled in properly involved a number of interesting bugs that I won't go into—including an infuiriating one where a test got the correct result, and then later got an incorrect result when rerunning the exact same test! (it had to do with, you guessed it, caching)—but I <fr:link href="https://github.com/swarm-game/swarm/pull/2738" type="external">finally got everything working</fr:link> with an elegant framework for easily adding more code metrics in the future.</html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2026</fr:year><fr:month>6</fr:month><fr:day>13</fr:day></fr:date><fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00H4/</fr:uri><fr:display-uri>00H4</fr:display-uri><fr:route>/~yorgey/forest/00H4/</fr:route><fr:title text="Blog post on proof of Fundamental Theorem of Arithmetic in Agda">Blog post on proof of Fundamental Theorem of Arithmetic in Agda</fr:title></fr:frontmatter><fr:mainmatter><html:p>A couple months ago I reported that I had, just for fun, completed a completely-from-scratch proof of the Fundamental Theorem of Arithmetic in Agda, and I've decided to turn it into a blog post/tutorial.  It's not an Agda tutorial—I'm assuming the reader already knows the basics of Agda and the Curry-Howard correspondence—but I'm not assuming much beyond that.  There's lots of introductory material out there, but I feel like it might be helpful to have a fully explained medium-size proof, for people who have learned the basics and played around with proof assistants, but would find it helpful to see a more fully worked example.  Along with the blog post I plan to publish a version with holes, so someone wanting to learn could try to fill in the holes while reading along with the explanations.</html:p><html:p>I spent a bunch of time (about 5 hours) working on the writeup.  A lot of fun stuff in there, including well-founded induction. I would say it's about... 2/3 finished.  At 11K words so far, it is not going to be short!</html:p></fr:mainmatter></fr:tree></fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>6</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>For some reason this week I dug out my old copies of <fr:link href="https://en.wikipedia.org/wiki/The_Virtuoso_Pianist_in_60_Exercises" type="external">Hanon</fr:link> and Czerny's "School of Velocity".  Kinda boring but a good way to spend 10 minutes warming up.</html:p>
                    <html:p>I've continued working through all of Chopin's waltzes—I've played many of them before, but they're somewhat rusty, so I'm systematically going through and polishing them up.  So far I'm up to number 4.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>6</fr:month>
                  <fr:day>12</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W23/</fr:uri>
                <fr:display-uri>2026-W23</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W23/</fr:route>
                <fr:title text="Weeknotes for 12 June 2026 (week 23)">Weeknotes for 12 June 2026 (week 23)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>12</fr:day>
                    </fr:date>
                    <fr:title text="Family">Family</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter><html:p>We enjoyed time with visiting family this week. On Thursday, I hiked up <fr:link href="https://en.wikipedia.org/wiki/Pinnacle_Mountain_(Arkansas)" type="external">Pinnacle Mountain</fr:link> with my sister-in law and 6 of our kids (2 of mine and 4 of hers).  It's a strenuous hike (about 220 meters elevation gain over a 1.8km trail) with a lot of fun scrambling over rocks that pays off with a lovely view at the top.</html:p>
  
  <html:img src="/~yorgey/forest/bafkrmih36ug3kmgmprs6t4zkos5jsrgbii5zu5oprpwytv3mvwgwghzj7e.jpg" />


  
  <html:img src="/~yorgey/forest/bafkrmiez4fktrxdu3cuzqq7466mebdmr3y6a7zpyhc6fg34u4z4xtsgofq.jpg" />


  
  <html:img src="/~yorgey/forest/bafkrmifegot74vpanye635ro6hqfqheowsmzcpl6dkupi5wyof3pq3tb7y.jpg" />


  
  <html:img src="/~yorgey/forest/bafkrmibdli6s5hclwjzfqlb5gil3lqf2tj65ds7ai6wjdqckaxrydzx45e.jpg" />

</fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>12</fr:day>
                    </fr:date>
                    <fr:title text="Blog post on FTA proof in Agda">Blog post on FTA proof in Agda</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I worked a bunch more on this <fr:link href="/~yorgey/forest/00H4/" title="Blog post on proof of Fundamental Theorem of Arithmetic in Agda" uri="http://ozark.hendrix.edu/~yorgey/forest/00H4/" display-uri="00H4" type="local">blog post/tutorial I mentioned last week</fr:link>.  I'm very close to completing a first pass through the entire proof: cleaning up, reorganizing, and writing prose to explain everything.  Next week I'll make a second pass through editing and polishing; then I'll go through and create a version with holes for people to download and play along.  The plan is to have it published in the next week or two.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>12</fr:day>
                    </fr:date>
                    <fr:title text="Swarm type + requirements system">Swarm type + requirements system</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>One of the most interesting things about <fr:link href="/~yorgey/forest/000O/" title="Swarm" uri="http://ozark.hendrix.edu/~yorgey/forest/000O/" display-uri="000O" type="local">Swarm</fr:link> is the core mechanic where you must obtain and craft devices that allow you to unlock programming language features.  So we have to be sure robots are able to run their code.  We can (and do) use dynamic runtime checks, but it would be very annoying and tedious if this were the only safeguard.  When you build a robot to run a program, you don't want to manually install all the required devices (there could be dozens, if you are using many language features); you also don't want robots to get halfway through running their programs only to crash because they are missing some required device.  So there is a <html:em>requirements analysis</html:em> which figures out what capabilities a program requires, and which devices could provide them; when building a robot, those devices are automatically installed (or, if you do not possess the necessary devices, the build fails).  However, this requirements analysis is an ad-hoc step bolted on after typechecking. At the time I wrote it, I didn't really understand what I was doing.</html:p>
                    <html:p>Over the years, however, this ad-hoc bolted-on requirements analysis has led to <fr:link href="https://github.com/swarm-game/swarm/issues/231" type="external">all sorts of bugs</fr:link>.  I've come to realize that the requirements for a program should really be <html:em>part of its type</html:em>, with requirements analysis integrated into the type system, similar to other existing work on type-and-effect style systems.  The twist is the distinction between required <html:em>capabilities</html:em> and required <html:em>inventory</html:em>; the <fr:tex display="inline"><![CDATA[\mathsf {build}]]></fr:tex> command turns the former into the latter, since in order to execute <fr:tex display="inline"><![CDATA[\mathsf {build}]]></fr:tex> you must have the correct devices in your inventory in order to equip them on the newly constructed robot.</html:p>
                    <html:p>I've spent some time this week working on a formal <fr:link href="/~yorgey/forest/000U/" title="Notes on redesign of the Swarm type system" uri="http://ozark.hendrix.edu/~yorgey/forest/000U/" display-uri="000U" type="local">writeup</fr:link> of a system that I think will fit the bill. The interesting part is that we really need requirements polymorphism, which means that instead of just keeping track of sets of requirements, we need to keep track of <fr:link href="https://mathstodon.xyz/@byorgey/116738220877346860" type="external">expressions involving requirement variables</fr:link>, and then solve equations over these expressions after generating them during type inference.  I am hopeful that this will work out nicely, but there are always unforeseen wrinkles.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>12</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I have <fr:link href="https://en.wikipedia.org/wiki/Waltzes_(Chopin)" type="external">Chopin's waltzes</fr:link> polished up through number 7.  Number 4 in F major is one I've never played before, but it's a lot of fun; most of my time this week has been spent learning it.  Number 8 is another one I've never played, so next week I will be learning that one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>6</fr:month>
                  <fr:day>22</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W24/</fr:uri>
                <fr:display-uri>2026-W24</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W24/</fr:route>
                <fr:title text="Weeknotes for 19 June 2026 (week 24)">Weeknotes for 19 June 2026 (week 24)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="Markdown processing and layout in Swarm">Markdown processing and layout in Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>As part of my work on <fr:link href="https://github.com/swarm-game/swarm/issues/2504" type="external">adding a help system to Swarm</fr:link>, I realized that I needed to better understand our code for processing Markdown (used for in-game item descriptions, scenario descriptions, and the like).  Of course, what started out as innocently reading through the code and adding some extra comments ended with me rewriting a bunch of code from scratch, which I ended up working on obsessively all week.  However, I'm quite pleased with <fr:link href="https://github.com/swarm-game/swarm/pull/2744" type="external">the result</fr:link>, which not only fixes several issues we had with spacing and code layout, but also paves the way for easily adding features like <fr:link href="https://github.com/swarm-game/swarm/issues/2746" type="external">hyphenation</fr:link> and <fr:link href="https://github.com/swarm-game/swarm/issues/574" type="external">syntax highlighting</fr:link>, in addition to expanding the range of Markdown we support to include links and lists.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="Hanabi">Hanabi</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><fr:link href="https://en.wikipedia.org/wiki/Hanabi_(card_game)" type="external">Hanabi</fr:link> is a fascinating cooperative game of logical deduction (if you don't know it I recommend checking it out).  My family has had it for a while, and played it occasionally, but within the past week we have been getting into it a bit more, occasioned by my 8-year-old requesting to be taught how to play.  I played a game with him, and he and my older son have both played games with my wife.  I re-read the <fr:link href="https://hanabi.github.io/" type="external">introductory conventions from the H-group</fr:link>, and my older son and I tried playing an online game using some of those conventions. Hopefully soon we can play some larger games with more of us all together (2-player games are a bit odd).</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I continued working on <fr:link href="https://en.wikipedia.org/wiki/Waltzes_(Chopin)" type="external">Chopin's waltzes</fr:link>, spending the majority of my time learning <fr:link href="/~yorgey/forest/00H6/" title="[CW08] Waltz in A♭ major, Op. 64 No. 3" uri="http://ozark.hendrix.edu/~yorgey/forest/00H6/" display-uri="00H6" type="local">Number 8 in A♭ major</fr:link> this week.  It still needs a bit more polishing, but it's largely done.  I also continued polishing a few others, notably No. 12 in F minor/A♭ major.</html:p>
                    <html:p>In putting together these weeknotes, I've also realized that what exactly counts as a Chopin waltz is somewhat up for debate! There are some pieces that have been attributed to him but probably aren't authentic; some pieces that are definitely by Chopin but may or may not count as a waltz; some authentic waltzes that we know existed but whose manuscripts have been lost; and some authentic waltzes that were published after his death that he may or may not have wanted to be published.  The Dover edition I have contains 17 waltzes (of which I currently know 14).  After consulting <fr:link href="https://en.wikipedia.org/wiki/Waltzes_(Chopin)" type="external">the Wikipedia page</fr:link>, it seems like there are two more that I want to include in my project: both posthumous waltzes in A minor, the first published in 1955 and the second discovered two years ago at the Morgan Library (which I already learned shortly after it was discovered).</html:p>
                    <html:p>I really ought to start creating pages in this forest for pieces in my repertoire...</html:p>
                    <html:p>Only a week and a half left until we leave for our yearly month-long pilgrimage to Maine, where I do not have access to a piano.  I was really hoping to finish learning all the waltzes before we leave, but it's looking unlikely that I will have time (I still have approximately four more of them to learn).  Oh well, I can finish the project when we get back.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>6</fr:month>
                  <fr:day>27</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W25/</fr:uri>
                <fr:display-uri>2026-W25</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W25/</fr:route>
                <fr:title text="Weeknotes for 26 June 2026 (week 25)">Weeknotes for 26 June 2026 (week 25)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Blog post on FTA proof in Agda">Blog post on FTA proof in Agda</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I finally made a last big push and finished up my <fr:link href="https://byorgey.github.io/blog/posts/2026/06/26/FTA.lagda.html" type="external">blog post/tutorial on an Agda proof of the Fundamental Theorem of Arithmetic</fr:link> (see <fr:link href="/~yorgey/forest/00H4/" title="Blog post on proof of Fundamental Theorem of Arithmetic in Agda" uri="http://ozark.hendrix.edu/~yorgey/forest/00H4/" display-uri="00H4" type="local">here</fr:link> for a previous discussion), which ended up being about 13K words (including both prose and code).  Somehow this always happens to me—I set out to write a "short note" about something and then end up with a book, or a 19-part blog post series, or whatever.  I don't think it's a bad thing.  I just ought to know by now what's going to happen at the outset.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Forester hacking">Forester hacking</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've gotten a bit stuck on my tool for <fr:link href="/~yorgey/forest/00H5/" title="Embedding diagrams in Forester" uri="http://ozark.hendrix.edu/~yorgey/forest/00H5/" display-uri="00H5" type="local">Embedding diagrams in Forester</fr:link>. The surrounding infrastructure is not hard, but the core mechanic of extracting code to a temporary Haskell file and then calling out to another GHC process to interpret the code, via the <fr:link href="https://hackage.haskell.org/package/hint" type="external"><html:code>hint</html:code> package</fr:link>, is very fiddly; I haven't yet been able to get versions/package databases/planets/mystic sigils etc. to line up properly.</html:p>
                    <html:p>I've also been idly wondering about embedding music notation within forests via <fr:link href="https://lilypond.org/" type="external">lilypond</fr:link>.  I will have to look into how <fr:link href="https://liamoc.net/forest/index/index.xml" type="external">Liam O'Connor</fr:link> includes chant notation in his forest (<html:em>e.g.</html:em> <fr:link href="https://liamoc.net/forest/loc-0031/index.xml" type="external">here</fr:link>).</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Hanabi">Hanabi</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I have continued playing some Hanabi, especially with my 14-year old.  We've played a couple games with strictly no verbal communication. The first time we did terribly, scoring 18/25; the second was much better, 24/25.  In both cases we learned a lot from our mistakes.  I'm looking forward to playing more on vacation and introducing some family members to the game and/or strategies.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>6</fr:month>
                      <fr:day>27</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Worked more on Chopin waltzes; I also practiced several of the movements of <fr:link href="/~yorgey/forest/rutter/" title="John Rutter" uri="http://ozark.hendrix.edu/~yorgey/forest/rutter/" display-uri="rutter" type="local">John Rutter</fr:link>'s <fr:link href="/~yorgey/forest/00H8/" title="Suite Antique" uri="http://ozark.hendrix.edu/~yorgey/forest/00H8/" display-uri="00H8" type="local">Suite Antique</fr:link> for flute and piano.  My wife and I played the whole suite together over 20 years ago, when we were dating, but we haven't had many chances to play together since then (first, we didn't have a piano; then, when we did have a piano, we had small kids, which made it hard to find the time to play together).  It was my wife's idea to pull it out, and I'm looking forward to playing with her again!  More generally, I hope we can find more opportunity to play together now that our kids are not quite so little (our youngest is 5, and we're not likely to have any more).  We can start by reviving the Rutter as well as <fr:link href="https://en.wikipedia.org/wiki/Flute_Sonata_(Poulenc)" type="external">Poulenc's flute sonata</fr:link>, which we also played together a long time ago. Eventually I'd also love to play the <fr:link href="https://en.wikipedia.org/wiki/Flute_Sonata_(Prokofiev)" type="external">Prokofiev flute sonata</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>7</fr:month>
                  <fr:day>5</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W26/</fr:uri>
                <fr:display-uri>2026-W26</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W26/</fr:route>
                <fr:title text="Weeknotes for 3 July 2026 (week 26)">Weeknotes for 3 July 2026 (week 26)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>5</fr:day>
                    </fr:date>
                    <fr:title text="Maine road trip 2026, part 1">Maine road trip 2026, part 1</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>My family makes an annual summer pilgrimage from Conway, Arkansas to <fr:link href="https://en.wikipedia.org/wiki/Peru,_Maine" type="external">Peru, Maine</fr:link>, where my family owns a cabin.  Getting there involves a week-long road trip in either direction, with plenty of stops along the way to see sights, friends, and family, with a different route every year—the road trip is not just a means to an end but an integral part of the vacation!</html:p>
                    <html:p>This year, we first drove to <fr:link href="https://www.nps.gov/maca/index.htm" type="external">Mammoth Cave National Park</fr:link> in Kentucky.  <fr:link href="https://en.wikipedia.org/wiki/Mammoth_Cave_National_Park" type="external">Mammoth Cave</fr:link> is the longest known cave system in the world, with over 685 km of known passageways.  We took a guided tour of (one tiny part of!) the cave, which was quite impressive.</html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmibti3cjmmcvns2jmf6evgi3vmkacyqq7er5esqs46jk4snljna5ku.jpg" />
                    </html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmic7mbow3x22kcm7wrlvbda6ul4zwjtpy6adnfsrustizg4c4oepnu.jpg" />
                    </html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmig22ynrafvwji5k3qhppin6y2fqttkwh3xoi74c75dg5zfiuk3etu.jpg" />
                    </html:p>
                    <html:p>Next we drove to <fr:link href="https://en.wikipedia.org/wiki/Pittsburgh" type="external">Pittsburgh, Pennsylvania</fr:link> to stay with friends for a few nights.  Activities included a visit to the <fr:link href="https://kaminsciencecenter.org/" type="external">Kamin Science Center</fr:link> (including, of course, a photo op on the space toilet), dinner with other friends, 4th of July fireworks on the campus of Carnegie Mellon, and attending a Sunday morning service at <fr:link href="https://cityreformed.org/" type="external">City Reformed Presbyterian Church</fr:link>.  I also went for a mountain bike ride in <fr:link href="https://pittsburghparks.org/explore-your-parks/regional-parks/frick-park/" type="external">Frick Park</fr:link>, which was fun but exhausting.</html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmihaj4t7jmu7lw6tdeyxth6vzeumfas7mumwpkn57bzxdrkags3ddu.jpg" />
                    </html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmieft4jeebrjznl5hq67dqry4se2ed2a3wgnbgbnkbo52wh2hjj7o4.jpg" />
                    </html:p>
                    <html:p>Tomorrow we head to <fr:link href="https://en.wikipedia.org/wiki/Williamstown,_Massachusetts" type="external">Williamstown, Massachusetts</fr:link> for the last stop on our journey.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>5</fr:day>
                    </fr:date>
                    <fr:title text="Including diagrams and lilypond snippets in Forester">Including diagrams and lilypond snippets in Forester</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've been thinking more about how to embed <fr:link href="https://diagrams.github.io/" type="external">diagrams</fr:link> and <fr:link href="https://lilypond.org/" type="external">lilypond</fr:link> output in Forester trees.  Last week I reported feeling stuck on the diagrams preprocessor I was building, but I recently realized I've been overthinking it: rather than call a diagrams interpreter programmatically (which runs into issues with package databases, mismatched GHC versions, <html:em>etc.</html:em>), I should just use it as an external executable.  The other benefit of this approach is that it should work similarly for lilypond, which also works as an external tool that compiles source code to an image, so I hope I can reuse a lot of the same infrastructure in my preprocessing tool.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>5</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Since we've been on our trip, I haven't been able to play the piano, but I did create a <fr:link href="/~yorgey/forest/00H7/" title="Piano repertoire" uri="http://ozark.hendrix.edu/~yorgey/forest/00H7/" display-uri="00H7" type="local">page for my piano repertoire</fr:link>.  There are only a couple pieces listed so far, but I plan to add new pieces incrementally.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>7</fr:month>
                  <fr:day>10</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W27/</fr:uri>
                <fr:display-uri>2026-W27</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W27/</fr:route>
                <fr:title text="Weeknotes for 10 July 2026 (week 27)">Weeknotes for 10 July 2026 (week 27)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>10</fr:day>
                    </fr:date>
                    <fr:title text="Maine">Maine</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We made it to Maine!  It's delightful here. I've already read two whole books, done a lot of swimming, and baked some <fr:link href="https://mathstodon.xyz/@byorgey/112769699589949345" type="external">traditional Abie cake</fr:link>. Here's a picture I took of a <fr:link href="https://en.wikipedia.org/wiki/Loon" type="external">common loon</fr:link> swimming right by our dock:</html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmigavkvsez2prk22wvoa3re62oxlz3j7tzykxy727vcyiiripdikp4.jpg" />
                    </html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>10</fr:day>
                    </fr:date>
                    <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/00IO/</fr:uri>
                    <fr:display-uri>00IO</fr:display-uri>
                    <fr:route>/~yorgey/forest/00IO/</fr:route>
                    <fr:title text="Lilypond snippets in Forester">Lilypond snippets in Forester</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter><html:p>I built a simple preprocessor that can extract arbitrary blocks from Forester source and run them through an external tool, replacing the block with an image. I then put the whole thing together into a <fr:link href="https://hackage.haskell.org/package/shake" type="external">Shake</fr:link> <fr:link href="https://github.com/byorgey/forest/blob/main/Shake.hs" type="external">build system for my forest</fr:link>.  Now I can include musical snippets using <fr:link href="https://lilypond.org/" type="external">lilypond</fr:link> syntax, like this:</html:p>
 <html:p><html:div class="forester-block"><html:a href="/~yorgey/forest/d4401b29fcf4da45">
  <html:img src="/~yorgey/forest/bafkrmihpy2dx3ya3246gbttree3fxcpw3x2syzv7sc2axlsvoesa6zyd44.png" />
</html:a></html:div></html:p>
<html:p>I've been slowly adding musical snippets to identify the first few bars of pieces in my <fr:link href="/~yorgey/forest/00H7/" title="Piano repertoire" uri="http://ozark.hendrix.edu/~yorgey/forest/00H7/" display-uri="00H7" type="local">piano repertoire</fr:link>.  For example, check out <fr:link href="/~yorgey/forest/00HA/" title="[CW02] Waltz in A♭ major, Op. 34 No. 1" uri="http://ozark.hendrix.edu/~yorgey/forest/00HA/" display-uri="00HA" type="local">[CW02] Waltz in A♭ major, Op. 34 No. 1</fr:link>.</html:p><html:p>Next I'll extend the preprocessor to work with <fr:link href="https://diagrams.github.io/" type="external">diagrams</fr:link> as well.</html:p></fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>7</fr:month>
                  <fr:day>18</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W28/</fr:uri>
                <fr:display-uri>2026-W28</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W28/</fr:route>
                <fr:title text="Weeknotes for 17 July 2026 (week 28)">Weeknotes for 17 July 2026 (week 28)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>18</fr:day>
                    </fr:date>
                    <fr:title text="Diagrams in Forester!">Diagrams in Forester!</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Shortly after adding the ability to <fr:link href="/~yorgey/forest/00IO/" title="Lilypond snippets in Forester" uri="http://ozark.hendrix.edu/~yorgey/forest/00IO/" display-uri="00IO" type="local">embed lilypond snippets</fr:link> in my forest, I <fr:link href="/~yorgey/forest/00H5/" title="Embedding diagrams in Forester" uri="http://ozark.hendrix.edu/~yorgey/forest/00H5/" display-uri="00H5" type="local">finished adding support</fr:link> for embedded <fr:link href="https://diagrams.github.io/" type="external">diagrams</fr:link> code as well:


 <html:p><html:div class="forester-block"><html:a href="/~yorgey/forest/96d4e31e14e129a4">
  <html:img src="/~yorgey/forest/bafkrmidhe2a6xn5qrd3wz7kdswcgk5dplb25fdmbpl45mdv7m5tevjustu.png" />
</html:a></html:div></html:p></html:p>
                    <html:p>I'm super excited that I finally got this to work.  I've already used it to add some diagrams to my <fr:link href="/~yorgey/forest/0021/" title="Discrete Mathematics Spring 2026 lecture notes" uri="http://ozark.hendrix.edu/~yorgey/forest/0021/" display-uri="0021" type="local">Discrete math lecture notes</fr:link>, for example, <fr:link href="/~yorgey/forest/00I3/" title="Warm-up" uri="http://ozark.hendrix.edu/~yorgey/forest/00I3/" display-uri="00I3" type="local">here</fr:link>.  If you're curious to see how this works, check out the <fr:link href="https://github.com/byorgey/forest/blob/main/Shake.hs" type="external">Shake file here</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>7</fr:month>
                      <fr:day>18</fr:day>
                    </fr:date>
                    <fr:title text="Maine">Maine</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Continuing to hang out in Maine.  I've eaten a lot of ice cream, played a <html:em>lot</html:em> of Hanabi, spent part of a day riding again at <fr:link href="https://www.mtabram.com/" type="external">Mt. Abram Bike Park</fr:link> (I only almost died twice), <html:em>etc.</html:em></html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>8</fr:month>
                  <fr:day>8</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W31/</fr:uri>
                <fr:display-uri>2026-W31</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W31/</fr:route>
                <fr:title text="Weeknotes for 7 August 2026 (week 31)">Weeknotes for 7 August 2026 (week 31)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>8</fr:day>
                    </fr:date>
                    <fr:title text="Maine">Maine</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We finally returned earlier this week from our annual trek to
  Maine. We saw a lot of
  <fr:link href="https://en.wikipedia.org/wiki/Common_loon" type="external">loons</fr:link>, including seven
  at once, which I had never seen before—they tend to be rather
  solitary—but <fr:link href="https://loonproject.org/2020/09/27/understanding-social-gatherings-the-basics/" type="external">apparently this is a
  thing</fr:link>.</html:p>
                    <html:p>While there, in addition to a bunch of reading and swimming, I
  made an elaborate DnD-style campaign for my 8-year-old, and played a
  lot more Hanabi.</html:p>
                    <html:p>On our way home, we saw The Odyssey (not in IMAX, just a regular
big theater screen) and enjoyed it. Geeked out with my percussionist
band nerd son about <fr:link href="https://en.wikipedia.org/wiki/Ludwig_G%C3%B6ransson" type="external">Ludwig Göransson</fr:link>'s use of a <fr:link href="https://www.youtube.com/watch?v=Z-VjDxckkg8" type="external">rhythmic Shepard tone</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>8</fr:day>
                    </fr:date>
                    <fr:title text="Swarm">Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>My work on Swarm has inched along slowly—still working on Markdown processing in preparation for building an integrated help system.  In other news, however, Patrick Estrada did a bunch of work switching out <fr:link href="https://hackage.haskell.org/package/fused-effects" type="external">fused-effects</fr:link> for <fr:link href="https://github.com/haskell-effectful/effectful" type="external">effectful</fr:link>—leading to some <html:em>significant</html:em> speedups!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>8</fr:day>
                    </fr:date>
                    <fr:title text="Semester prep">Semester prep</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This past week I've just started working on preparations for the fall semester. (The first few years I taught at Hendrix, I would tell myself that I would work on fall preparations a little bit each week over the summer, in order to spread out the work; then I would spend the whole summer <html:em>not</html:em> working on fall course prep and feeling guilty about it; then at the end of the summer I would do everything at the last minute in an anxiety-fueled and still guilt-ridden panic.  After a few years of this I finally realized that I should just <html:em>give myself permission</html:em> to not work on fall prep over the summer.)</html:p>
                    <html:p>I've started with <fr:link href="/~yorgey/forest/00JE/" title="CSCI 382, Algorithms" uri="http://ozark.hendrix.edu/~yorgey/forest/00JE/" display-uri="00JE" type="local">Algorithms</fr:link>.  I've taught this course many times before, so for the most part I won't be making any big changes; but I do plan to <fr:link href="/~yorgey/forest/00JF/" title="Algorithms Fall 2026 lecture notes" uri="http://ozark.hendrix.edu/~yorgey/forest/00JF/" display-uri="00JF" type="local">write up my lecture notes in Forester</fr:link> this year, just like I <fr:link href="/~yorgey/forest/0021/" title="Discrete Mathematics Spring 2026 lecture notes" uri="http://ozark.hendrix.edu/~yorgey/forest/0021/" display-uri="0021" type="local">did for Discrete Math last spring</fr:link>.  I've also been making a few changes to the course design in light of what I strongly suspect was too much use of generative AI by students in the course last year.  In particular I plan to add one more in-class exam, and require students to come into office hours some number of times for some kind of formally assessed conversation/quiz/oral exam thing.  I'm still not quite sure of the details.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>8</fr:month>
                  <fr:day>15</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W32/</fr:uri>
                <fr:display-uri>2026-W32</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W32/</fr:route>
                <fr:title text="Weeknotes for 14 August 2026 (week 32)">Weeknotes for 14 August 2026 (week 32)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>15</fr:day>
                    </fr:date>
                    <fr:title text="Swarm integrated help system">Swarm integrated help system</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've started actually putting together the Swarm integrated help system in earnest—the idea is to have a collection of interlinked documents, stored as a bunch of Markdown files, which can be displayed and explored interactively from within the game (and which can also be compiled into a static HTML form).  There's nothing technically challenging about this at all, just a bunch of engineering.  But as the semester ramps up that's exactly what I need—something on which I can make consistent progress in bits of time here and there, without needing big blocks of time to think deeply.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>15</fr:day>
                    </fr:date>
                    <fr:title text="Semester prep">Semester prep</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This week was full of meetings and workshops (department chairs workshop on Monday; meeting with my colleage about our co-taught course on Wednesday; an all-day workshop on new student advising on Thursday; a workshop on the new first-year course on Friday).  After getting back from vacation a couple weeks ago, my todo list is already extremely long.  I'm looking forward to the semester for the most part, but as usual I wish I could spend my time working deeply on a few things rather than having a million tiny administrative tasks.  I am most definitely looking forward to my next sabbatical in a year or two.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>8</fr:month>
                  <fr:day>22</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W33/</fr:uri>
                <fr:display-uri>2026-W33</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W33/</fr:route>
                <fr:title text="Weeknotes for 21 August 2026 (week 33)">Weeknotes for 21 August 2026 (week 33)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="Swarm">Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This week was the 5-year anniversary of my <fr:link href="https://github.com/swarm-game/swarm/commit/479b10e98685cdc4c7c7f1935b679b6b83819dcf" type="external">first commit to the
  Swarm repo</fr:link>—back in August of 2021, at the start of my sabbatical.  It's been a wonderful, wild ride.  The project has gone much farther than I could have imagined, and been more professionally fruitful than I would have thought possible!  And a big part of the reason it's remained fun for so long is the cool community of other contributors the project has attracted.</html:p>
                    <html:p>There's been a flurry of activity this week from several other contributors, so I've spent a decent bit of time reviewing PRs.  Among other cool things, there have been some fantastic improvements to memory usage and performance.</html:p>
                    <html:p>I've also continued working on an integrated help system this week.  It's coming along nicely.  One of the few things still missing is the ability to specify a table of contents for a given page, from which we can automatically display next/previous/up links.  I basically plan to steal the way Sphinx does this with the <html:code>toctree</html:code> directive.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="First-year student advising">First-year student advising</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I spent a substantial amount of time this week meeting with my cohort of 14 first-year student advisees—first as a group, and then individually.  In past years, they have come to campus with blank slates and we would spend the first week frantically building their schedules, resolving conflicts, finding alternate classes when the class they wanted is too full, and so on.  It didn't leave much time for anything besides putting out fires.  Starting last year, we have a new system in place where they meet with someone virtually over the summer to put together an initial course schedule.  By the time they arrive on campus they already have a mostly-solid schedule, and I just have to help fill it out with an extra class or two.  It is much more civilized and leaves plenty of time for chatting and getting to know them and what they are interested in.  Talking to people all day is a lot, but aside from that it was quite enjoyable; they all seem like lovely human beings with a wide variety of interests.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="Semester prep">Semester prep</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The fall semester is almost upon us.  When I haven't been doing advising stuff I have been working hard on preparing for my fall courses.  I'll be co-teaching our introductory programming course with my colleague, and we don't plan to change much about the course, which by this point is a well-oiled machine.  On the other hand, I am making a few more changes to Algorithms this semester.  In order to reduce incentives for LLM use, I'm adding an extra midterm exam and having some required office hour visits.  But the extra exam makes it more awkward to fit in weekly problem sets at reasonable times, which suddenly made me wonder today whether I could do something more flexible, like assigning individual problems every day and having them choose a portfolio of problems to solve. I still need to work out a lot of details.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~yorgey/forest/brentyorgey/" title="Brent A. Yorgey" uri="http://ozark.hendrix.edu/~yorgey/forest/brentyorgey/" display-uri="brentyorgey" type="local">Brent A. Yorgey</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>8</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:title text="Hanabi">Hanabi</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I have continued to enjoy <fr:link href="https://hanabi.github.io/" type="external">Hanabi</fr:link> a lot—playing sometimes with my 14yo and sometimes with strangers on <fr:link href="https://hanab.live/lobby" type="external">Hanab Live</fr:link>.  I think I enjoy it for many of the same reasons that I enjoy bridge—it is collaborative rather than competitive (I'm super competitive and it's easy for me to get stressed out about winning and losing), and involves teamwork, communication, and logical deduction.  I'm always happy to teach others, so if you're intrigued and would like to learn how to play, let me know!</html:p>
                    <html:p>
                      <html:img src="/~yorgey/forest/bafkrmiavv3meudblpszzjrxqoxl2cz7prgz5wf5dxawjsf3cu5zy5bb2ia.png" />
                    </html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2026</fr:year>
                  <fr:month>9</fr:month>
                  <fr:day>4</fr:day>
                </fr:date>
                <fr:uri>http://ozark.hendrix.edu/~yorgey/forest/2026-W35/</fr:uri>
                <fr:display-uri>2026-W35</fr:display-uri>
                <fr:route>/~yorgey/forest/2026-W35/</fr:route>
                <fr:title text="Weeknotes for 4 September 2026 (week 35)">Weeknotes for 4 September 2026 (week 35)</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Missed last week's weeknotes since there is a whole lot going on at
the start of the semester!</html:p>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>9</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Haskell Interlude">Haskell Interlude</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I was on the <fr:link href="https://haskell.foundation/podcast/" type="external">Haskell Interlude podcast</fr:link>!  I recorded the actual interview last spring, with <fr:link href="/~yorgey/forest/farhad-mehta/" title="Farhad Mehta" uri="http://ozark.hendrix.edu/~yorgey/forest/farhad-mehta/" display-uri="farhad-mehta" type="local">Farhad Mehta</fr:link> and <fr:link href="/~yorgey/forest/sam-frohlich/" title="Sam Frohlich" uri="http://ozark.hendrix.edu/~yorgey/forest/sam-frohlich/" display-uri="sam-frohlich" type="local">Sam Frohlich</fr:link>; the whole process was a lot of fun.  I listened to the episode before it was released and I am not too embarrassed about anything I said, so <fr:link href="https://haskell.foundation/podcast/85/" type="external">give it a listen</fr:link>!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>9</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Semester start">Semester start</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Because of all administrative responsibilities, I had very little time to prepare for my actual classes, and the first few days of classes hit like a ton of bricks—I did not get very much sleep as I prepared syllabi and assignments at the very last minute.  I do feel I'm in a better place now, though.  Much of it was one-time overhead that need not be repeated.</html:p>
                    <html:p>Getting to know my students has been fun.  I am teaching one upper-level course (<fr:link href="/~yorgey/forest/00JE/" title="CSCI 382, Algorithms" uri="http://ozark.hendrix.edu/~yorgey/forest/00JE/" display-uri="00JE" type="local">CSCI 382, Algorithms</fr:link>) in which I already knew most of the students; one introductory computing course (<fr:link href="https://hendrix-cs.github.io/csci150/" type="external">CSCI 150, Foundations of Computer Science</fr:link>); and one general education first-year seminar.  For the most part, the students seem thoughtful and engaged.</html:p>
                    <html:p>I am trying something a bit different with <fr:link href="/~yorgey/forest/00JE/" title="CSCI 382, Algorithms" uri="http://ozark.hendrix.edu/~yorgey/forest/00JE/" display-uri="00JE" type="local">CSCI 382, Algorithms</fr:link> this semester (besides <fr:link href="/~yorgey/forest/00JF/" title="Algorithms Fall 2026 lecture notes" uri="http://ozark.hendrix.edu/~yorgey/forest/00JF/" display-uri="00JF" type="local">typing up my lecture notes in Forester</fr:link>). I used to assign weekly problem sets, consisting of a bunch of problems in a PDF that they would have one week to solve and submit.  But scheduling the problem sets around exams and breaks, and making sure they contained appropriate material, was always tricky.  They also didn't adapt well to students who were either very advanced or struggling.  This semester, I am simply publishing a <fr:link href="/~yorgey/forest/00JL/" title="Algorithms problems" uri="http://ozark.hendrix.edu/~yorgey/forest/00JL/" display-uri="00JL" type="local">collection of problems</fr:link>, and the students are responsible for selecting which problems they want to solve.  To help ensure they are making consistent progress, they still have weekly "problem sets" due, but the problem sets do not specify which problems they must solve, but only a required number of problems instead.  This allows me to publish a wider variety of problems, as well as helping students who fall a bit behind continue to make consistent progress without penalizing them for being behind.</html:p>
                    <html:p>We'll see how it goes!  I am cautiously optimistic, though of course I'm sure there are things I will learn and change about the system next time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>9</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Missing ICFP">Missing ICFP</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>ICFP was relatively close to me this year (Indianapolis would be about a 9 hour drive, or a short plane flight or two, away), but unfortunately, it happened during the first week of classes.  Since I am the department chair and an advisor for first-year students, that sadly made ICFP a no-go.  Spent the week watching the occasional livestream, reading friends post about ICFP on Mastodon, and just generally feeling like I was missing out.  I am already plotting how I can make it to Nijmegen next year...</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>9</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Admin corner">Admin corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A bunch of my extra time is taken up right now with two major administrative tasks: completing a self-evaluation, and putting together a hiring request for next year.  Both are due early next week.  I will be very glad when they are both done!
  </html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>9</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Swarm">Swarm</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Only a tiny bit of incremental progress on the integrated help system this week; looking forward to having the above admin stuff done so I can get back to working on this more regularly!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>9</fr:month>
                      <fr:day>4</fr:day>
                    </fr:date>
                    <fr:title text="Piano corner">Piano corner</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>I've continued to work on my Chopin waltz project.  I'm also slowly <fr:link href="/~yorgey/forest/00H7/" title="Piano repertoire" uri="http://ozark.hendrix.edu/~yorgey/forest/00H7/" display-uri="00H7" type="local">adding repertoire to my forest</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Backlinks">Backlinks</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Related">Related</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Contributions">Contributions</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
  </fr:backmatter>
</fr:tree>
