<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" >

  <title>Erik L. Arneson — Writer and Software Developer</title>
  <subtitle>Erik L. Arneson is a freelance writer and software developer with WordPress experience. He is located in Portland, Oregon.</subtitle>
  <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator>
  <link href="https://arnesonium.com/feeds/programming.xml" rel="self" type="application/atom+xml" />
  <link href="https://arnesonium.com/" rel="alternate" type="text/html" />
  <updated>2026-06-18T15:03:10+00:00</updated>
  <id>https://arnesonium.com/feeds/programming.xml</id>
  <author>
    <name>Erik L. Arneson</name>
  </author>
      <entry>
        
        <title>Process Automation for an Oregon Charitable Foundation</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2026/05/process-automation-oregon-charitable-foundation" rel="alternate" type="text/html" title="Process Automation for an Oregon Charitable Foundation" />
        <updated>2026-05-22T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2026/05/sref</id>
          <category term="cloud" />
        
          <category term="cloud-computing" />
        
          <category term="golang" />
        
          <category term="svelte" />
        
          <category term="typescript" />
        
          <category term="automation" />
        
          <category term="case-study" />
        
          <category term="google-cloud" />
        
          <category term="programming" />
        
          <category term="testing" />
        
          <category term="web-development" />
        
          <category term="software-development" />
        <content type="html" xml:base="https://arnesonium.com/2026/05/process-automation-oregon-charitable-foundation">&lt;p&gt;The &lt;a href=&quot;https://orsrscholarships.com/&quot;&gt;Oregon Scottish Rite Education Foundation&lt;/a&gt; awards scholarships annually to students across Oregon
who are entering into college or trade schools. Over the past few years, their foundation has grown,
requiring them to distribute more scholarships than ever. However, since the foundation board is
small and composed entirely of volunteers, they were looking for some way to automate their application process to
reduce the number of manual steps required.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;initial-approach&quot;&gt;Initial Approach&lt;/h2&gt;

&lt;p&gt;Members of the board approached me with a wish list of features and requirements. They wanted a
system to integrate seamlessly with their website, while incoming applications should be
automatically checked, sorted, and categorized by county. They already had a spreadsheet system for
tracking applicants as well as a cloud storage system for storing supporting documents; they wanted
the automation system to integrate with these existing components.&lt;/p&gt;

&lt;p&gt;Since the board was already utilizing Google Business products for cloud documents and storage, I
decided that the best approach would be to lean into Google Cloud services. Following their list of
requirements, I implemented a &lt;a href=&quot;https://cloud.google.com/run&quot;&gt;Google Cloud Run&lt;/a&gt; service in &lt;a href=&quot;https://go.dev/&quot;&gt;Go&lt;/a&gt; that processed incoming applications
from their website, then updated the spreadsheet while preparing their cloud storage system for each
application’s supporting documents. The spreadsheet now contained all the application data,
including a link to an automatically generated PDF version of the application and a link to the
cloud storage location.&lt;/p&gt;

&lt;p&gt;This initial approach cut out an enormous amount of manual work. Previously, applications were
submitted via the website and emailed to a board member, who then manually sorted them by county and
generated PDFs for storage and later distribution.&lt;/p&gt;

&lt;h2 id=&quot;implementation-challenges&quot;&gt;Implementation Challenges&lt;/h2&gt;

&lt;p&gt;The application submission window for the Oregon Scottish Rite Education Foundation runs from
December through March of each year, which gave us a limited amount of time to observe incoming live
data and how the automation was performing.&lt;/p&gt;

&lt;p&gt;My initial approach worked fairly well, and handled 94% of incoming applications properly. However,
the last 6% ran into various problems that prevented correct processing. One error arose from a
misspelling in a county name, which was caught early and corrected. Another series of errors arose
from processing errors with the Google Sheets API, which has both rate limiting and more mysterious,
inexplicable errors. I added additional error correction and error checking, but there was still
some additional manual work to enter data from a handful of applications.&lt;/p&gt;

&lt;p&gt;By the end of the application period, we had managed to reduce the amount of manual data entry and
processing by a large percentage, maybe as much as 60%. After discussing the current process
automation with the board, we began to see opportunities for further automation and improvement.&lt;/p&gt;

&lt;h2 id=&quot;additional-development&quot;&gt;Additional Development&lt;/h2&gt;

&lt;p&gt;After the first year’s application submission window, I began working with one of the board members
to plan out how the process could be improved even more. My list of improvements were primarily on
the backend, and involved robuster error detection and reporting, as well as a backup data store
that would allow the automation to recover from the Google Sheets API errors more elegantly.&lt;/p&gt;

&lt;p&gt;The board proposed an additional feature set that would further reduce manual data processing, by
allowing applicants to upload supporting documents such as letters of recommendation and high school
transcripts. These uploaded documents would then be processed and stored in the proper cloud storage
location, thus reducing the amount of manual file management required by volunteers.&lt;/p&gt;

&lt;p&gt;Implementing these two new features went very smoothly. It required the development of a new
frontend, using &lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;Typescript&lt;/a&gt; and &lt;a href=&quot;https://svelte.dev/&quot;&gt;Svelte&lt;/a&gt;. This frontend allowed applicants to upload their supporting
documents via a unique link given to each of them by automated email. It used both &lt;a href=&quot;https://cloud.google.com/storage&quot;&gt;Google Cloud
Storage&lt;/a&gt; and the Google Drive API to store these files.&lt;/p&gt;

&lt;p&gt;The improvements on the backend used &lt;a href=&quot;https://cloud.google.com/products/datastore&quot;&gt;Google Cloud Datastore&lt;/a&gt; and a more robust error recovery system.
It now backed up all incoming scholarship applications until they could reliably and more slowly be
added to the spreadsheet with the Google Sheets API, thus nearly eliminating all rate limiting
errors. In addition, progress reports and error output could now be viewed using a new frontend
administrative interface.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;This round of improvements produced significant results. Over the entire span of the second year of
application submissions, error rates dropped from 6% to &lt;em&gt;just one unrecoverable error.&lt;/em&gt; While I had
been hoping for improvement, even I was surprised by how much of an improvement we achieved!&lt;/p&gt;

&lt;p&gt;The board reported that the amount of manual processing was reduced by another 80-90%, with only a
few applicants resorting to email for sending in their supporting documents. While we have discussed
further improvements to the process automation for the next application submission window, the board
is satisfied with the improvements provided by the level of automation implemented so far.&lt;/p&gt;

&lt;h2 id=&quot;lessons&quot;&gt;Lessons&lt;/h2&gt;

&lt;p&gt;This project benefited a lot by reviewing requirements and expectations frequently with the client.
They were great at providing me with very clear goals from the beginning, and as we progressed and
it became clear where the most volunteer time was being spent, we were able to identify more tasks
for automation.&lt;/p&gt;

&lt;p&gt;On the development side of things, three things were clear. First, cloud services really make the
development and deployment of process automation tools like this a breeze. Costs can be kept low
while still providing robust infrastructure for hosting.&lt;/p&gt;

&lt;p&gt;Second, I learned once more the importance of unit tests. I wrote unit tests for most elements of
the automation software, which allowed me to catch breaking changes and test features very quickly.
&lt;a href=&quot;https://www.ibm.com/think/topics/test-driven-development&quot;&gt;Test-driven development&lt;/a&gt; can be a great way to run a project, and though I did not follow all of its
parameters strictly, that particular philosophy did guide my decision.&lt;/p&gt;

&lt;p&gt;Third, once more I was reminded of how the best-planned software runs into difficulties when it
collides with the real world. I failed to anticipate the Google Sheets API issues and did not
implement enough comprehensive error correction early on. That is not an error I shall repeat again!&lt;/p&gt;

&lt;p&gt;Finally, I learned that even with a project that seems as straightforward as this one, it is
important to control expectations early. This turned into a multiyear project because we saw room
for improvement. I think it is important for a business or organization looking for process
automation to understand that it can be an ongoing series of improvements; not everything will be
accomplished or perfected after one pass.&lt;/p&gt;

&lt;p&gt;Overall, I found this to be a rewarding project. I enjoyed working on software that was aiding a
good cause: helping high school graduates fund their education. It was also very nice to work for a
charitable foundation instead of a for-profit business; it made all of my programming feel a lot
better. I hope to work for more charitable foundations in the future.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Emacs as the Freelancer&apos;s Command Center</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2026/04/emacs-freelance-command-center" rel="alternate" type="text/html" title="Emacs as the Freelancer's Command Center" />
        <updated>2026-04-10T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2026/04/emacs-freelance-command-center</id>
          <category term="emacs" />
        
          <category term="org-mode" />
        
          <category term="programming" />
        
          <category term="writing" />
        
          <category term="music" />
        
          <category term="wordpress" />
        
          <category term="emacs-lisp" />
        
          <category term="email" />
        
          <category term="git" />
        
          <category term="tools" />
        <content type="html" xml:base="https://arnesonium.com/2026/04/emacs-freelance-command-center">&lt;p&gt;Freelancing for small businesses and organizations leads to a position where you are juggling a
number of projects for multiple clients. You need to keep track of a number of tasks ranging from
software development to sending emails to project management. This is a lot easier when you have a
system that can do a bunch of the work for you, which is why I use Emacs as my freelancer command
center.&lt;/p&gt;

&lt;p&gt;I would like to share some of the tools and workflows I use in Emacs to help me keep on top of
multiple clients’ needs and expectations.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;organization-with-org-mode&quot;&gt;Organization with org-mode&lt;/h2&gt;

&lt;p&gt;It should be no surprise that at the center of my Emacs command center is &lt;a href=&quot;https://orgmode.org/&quot;&gt;org-mode&lt;/a&gt;. I have already
&lt;a href=&quot;/tags/org-mode/&quot;&gt;written about it a lot&lt;/a&gt;. Every org-mode user seems to have their own way of keeping track of things,
so please don’t take my organizational scheme as some kind of gospel. A couple of years ago, I wrote
about &lt;a href=&quot;/2024/10/todo-lists-in-org-mode&quot;&gt;how I handle to-do lists in org-mode&lt;/a&gt;, and I am still using that method for to-do keywords.
However, file structure is also important. I have a number of core files.&lt;/p&gt;

&lt;h3 id=&quot;freelanceorg&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Freelance.org&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This top-level file contains all of my ongoing business tasks, such as tracking potential new
clients, recurring tasks like website maintenance and checking my &lt;a href=&quot;https://mainwp.com/&quot;&gt;MainWP dashboard&lt;/a&gt;. I also have
recurring tasks for invoicing, tracking expenses, and other important business things.&lt;/p&gt;

&lt;p&gt;This file is also where I have my primary time tracking and reporting. Org-mode already supports
this pretty nicely, I just use the built-in &lt;a href=&quot;https://orgmode.org/manual/The-clock-table.html&quot;&gt;clocktable feature&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;clientsorg&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Clients/*.org&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Clients that have large projects or ongoing business get their own file. This makes organization a
lot easier. All tasks associated with a client and their various projects end up in these individual
files. The important part is making sure that these files are included in the time-tracking
clock table &lt;em&gt;and&lt;/em&gt; your org-mode agenda, so you can see what is going on every week.&lt;/p&gt;

&lt;h3 id=&quot;references-and-linking&quot;&gt;References and Linking&lt;/h3&gt;

&lt;p&gt;I have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C-c l&lt;/code&gt; bound to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org-store-link&lt;/code&gt; and use it all the time to link to various files,
directories, URLs, and even emails. I can then use those links in my client notes, various tasks in
my to-do list, and so on. This helps me keep my agenda organized even when my filesystem and
browser bookmarks are a bit of a mess.&lt;/p&gt;

&lt;h2 id=&quot;email-with-mu4e&quot;&gt;Email with mu4e&lt;/h2&gt;

&lt;p&gt;I have been reading and managing my email in Emacs for over 25 years. There have been a few breaks
here and there where I have tried out other software or even web mail clients, but it has always been
a headache. I return to Emacs! Long ago, I used &lt;a href=&quot;https://gitlab.com/emacs-vm/vm&quot;&gt;VM&lt;/a&gt; (which seems to have taken on new life!), but
currently I use &lt;a href=&quot;https://djcbsoftware.nl/code/mu/mu4e/index.html&quot;&gt;mu4e&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This gives me a ton of power and flexibility when dealing with email. I have custom functions to
help me compose and organize my email, and I can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org-store-link&lt;/code&gt; to keep track of individual
emails from clients as they relate to agenda items. I even have a function to convert emails that I
have written in Markdown into HTML email, and one that searches for questions in a client email to
make sure I haven’t missed anything.&lt;/p&gt;

&lt;p&gt;The ability to write custom code to both process and create email is extremely powerful and a great
time saver.&lt;/p&gt;

&lt;h2 id=&quot;writing-code&quot;&gt;Writing Code&lt;/h2&gt;

&lt;p&gt;I don’t know what else to say about this, I use Emacs for doing all of my software development. I
make sure to use &lt;a href=&quot;https://github.com/joaotavora/eglot&quot;&gt;Eglot&lt;/a&gt; whenever there is a language server available, and I try to leverage all the
fancy features offered by Emacs whenever possible. The vast majority of projects for clients are PHP
(thanks &lt;a href=&quot;/wordpress/&quot;&gt;WordPress&lt;/a&gt;), Go, JavaScript, and TypeScript.&lt;/p&gt;

&lt;h2 id=&quot;writing-words&quot;&gt;Writing Words&lt;/h2&gt;

&lt;p&gt;Previously, I have shared quite a bit about &lt;a href=&quot;/tags/writing/&quot;&gt;writing in Emacs&lt;/a&gt;. I like to start everything in
org-mode, but I also write quite a bit in Markdown. Emacs has become a powerful tool for writing. I
use the &lt;a href=&quot;https://writewithharper.com/&quot;&gt;Harper language server&lt;/a&gt; along with Eglot to check grammar and spelling.&lt;/p&gt;

&lt;h2 id=&quot;track-all-changes-with-magit&quot;&gt;Track All Changes with Magit&lt;/h2&gt;

&lt;p&gt;Version control is essential, a lesson I have learned over 30+ years of software development. While
&lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt; is not part of Emacs, the software I use to interface with Git is. &lt;a href=&quot;https://magit.vc/&quot;&gt;Magit&lt;/a&gt; is a Git user interface
that runs entirely in Emacs. I use it to track my writing, my source code, and even all of my
org-mode files. Using version control is so essential that I have a weekly repeating agenda task
reminding me to check all of my everyday files to make sure I have checked-in my changes for the
week.&lt;/p&gt;

&lt;h2 id=&quot;thinking-music-with-emms&quot;&gt;Thinking Music with EMMS&lt;/h2&gt;

&lt;p&gt;I like to have some soothing background music when I am programming, writing, or otherwise working
on my computer. However, if that background music has lyrics, it can be really distracting. It is
easy to make a playlist for various suitable &lt;a href=&quot;https://somafm.com/&quot;&gt;SomaFM&lt;/a&gt; channels to load into &lt;a href=&quot;https://www.gnu.org/software/emms/&quot;&gt;EMMS (the Emacs Multimedia
System)&lt;/a&gt; using the command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x emms-play-playlist&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Try saving the following into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;playlist.el&lt;/code&gt; somewhere, and using it the next time you are writing:&lt;/p&gt;

&lt;div class=&quot;language-emacs-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;c1&quot;&gt;;;; This is an EMMS playlist file Play it with M-x emms-play-playlist&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;*track*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://somafm.com/synphaera.pls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;*track*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://somafm.com/gsclassic.pls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;*track*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://somafm.com/sonicuniverse.pls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;*track*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://somafm.com/groovesalad.pls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And make sure to check out SomaFM’s selection to find some good background music that suits your
tastes!&lt;/p&gt;

&lt;h2 id=&quot;and-the-tools-i-have-missed&quot;&gt;And the tools I have missed&lt;/h2&gt;

&lt;p&gt;There are undoubtedly Emacs tools that I have missed in this brief overview. I have been wracking my
brain as I write, trying to see what I have forgotten or overlooked. Frankly, Emacs has become such
a central part of the organization for my freelancing that there are probably many tools, packages,
and processes that I use every day without thinking about it too much.&lt;/p&gt;

&lt;p&gt;Emacs makes it possible for me to freelance for multiple clients and small businesses without losing
my mind with organization and task management. The tools it provides allow me to stay on top of
multiple projects, handle client relationships, and keep track of years worth of tasks,
communications, and projects. Without it, I’d be sunk!&lt;/p&gt;

&lt;p&gt;What Emacs tools are you using to manage your freelance business? I am always looking for ways to
improve or streamline my process.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The featured image for this post comes from Agostino Ramelli’s&lt;/em&gt; Le diverse et artificiose machine &lt;em&gt;(1588). &lt;a href=&quot;https://publicdomainreview.org/collection/agostino-ramelli-theatre-of-machines/&quot;&gt;Read more about it on the Public Domain Review.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>An Emacs Application Launcher for Regolith</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2025/11/regolith-emacs-launcher" rel="alternate" type="text/html" title="An Emacs Application Launcher for Regolith" />
        <updated>2025-11-19T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2025/11/regolith-emacs-launcher</id>
          <category term="emacs" />
        
          <category term="shell" />
        
          <category term="bash" />
        
          <category term="lisp" />
        
          <category term="programming" />
        
          <category term="ubuntu" />
        <content type="html" xml:base="https://arnesonium.com/2025/11/regolith-emacs-launcher">&lt;p&gt;I run the &lt;a href=&quot;https://regolith-desktop.com/&quot;&gt;Regolith Desktop Environment&lt;/a&gt; on my laptop, which I love because it provides a convenient GNOME wrapper and interface for the &lt;a href=&quot;https://i3wm.org/&quot;&gt;i3 tiling window manager&lt;/a&gt;. Regolith relies on a program called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt; for application launching, and sometimes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt; gets caught in some kind of CPU-churning state that locks up my whole system. I have not been able to figure out what is causing it, so I (of course) turned to Emacs for a solution.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;turning-to-consult-omni&quot;&gt;Turning to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consult-omni&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Armin Darvish has created a powerful Emacs package called &lt;a href=&quot;https://github.com/armindarvish/consult-omni&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consult-omni&lt;/code&gt;&lt;/a&gt;, which provides a wrapper around &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consult&lt;/code&gt; for searching through any number of information sources. I believe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consult-omni&lt;/code&gt; was originally intended to query web search engines and document databases, but Darvish has also provided a search mode for your local desktop applications, and can act as an application launcher.&lt;/p&gt;

&lt;p&gt;Darvish provides an example application launcher in his &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consult-omni&lt;/code&gt; YouTube tutorial. The source code is straightforward, but I wanted to tweak it just a little. You can view &lt;a href=&quot;https://github.com/armindarvish/consult-omni/wiki/YouTube-Tutorial#create-a-launcher&quot;&gt;his original on the project’s wiki on GitHub&lt;/a&gt;. You can watch him explain his technique below.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/wNH2E7iT__c?start=8595&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;After a few tweaks, here is what I came up with.&lt;/p&gt;

&lt;div class=&quot;language-emacs-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;consult-launcher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;A launcher suitable for use from a window manager.&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;floor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.6&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;display-pixel-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;floor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.6&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;display-pixel-height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;floor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;display-pixel-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;floor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;display-pixel-height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;omni-launcher&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;text-pixels&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;text-pixels&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;minibuffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;only&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;make-frame&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-selected-frame&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;select-frame-set-input-focus&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;;; If i3 is running and there is a control socket, let&apos;s tell&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;;; it we are a floating frame.&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;getenv&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;I3SOCK&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;call-process&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;i3-msg&quot;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[id=%s] floating enable&quot;&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;s-trim&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;shell-command-to-string&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;xdotool getactivewindow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;unwind-protect&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;progn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;consult-omni-apps-static&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.*&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;propertize&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;gt; &quot;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;face&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;consult-omni-path-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                 &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;progn&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;frame-live-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;delete-frame&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I made two changes to get this to work nicely with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i3&lt;/code&gt;. First, I removed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yequake&lt;/code&gt; dependency. Second, I added a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i3-msg&lt;/code&gt; that sets the launcher frame as floating, which makes it much nicer to use. Like Darvish’s version, you can run this from the command line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;emacsclient -e &apos;(consult-launcher)&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;adding-an-ilia-fallback&quot;&gt;Adding an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt; fallback&lt;/h2&gt;

&lt;p&gt;Don’t tell all the other Emacs users, but I don’t have Emacs set up to launch automatically when I start my computer and log into X11. I probably should, huh? Also, there are times when I (gasp!) shut down Emacs, usually to restart it or fix something that I have broken. When those times happen, I want to be able to launch applications, so I need a failsafe in case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consult-launcher&lt;/code&gt; isn’t available!&lt;/p&gt;

&lt;p&gt;To solve this, I created a simple shell wrapper script, which looks like this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Check if Emacs server is running by looking for the server socket&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Default server name is &quot;server&quot;, but you can change this if needed&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SERVER_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;EMACS_SERVER_NAME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SERVER_FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;XDG_RUNTIME_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/tmp&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/emacs/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SERVER_NAME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SERVER_FILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Emacs is running, use emacsclient to launch your application&lt;/span&gt;
    emacsclient &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;(consult-launcher)&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Emacs is not running, fall back to ilia&lt;/span&gt;
    ilia &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; apps
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to use this, the important part is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SERVER_FILE&lt;/code&gt; points to the socket that your Emacs server uses. Make sure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emacsclient&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt; are both in a reasonable location so your shell can find them, then bind this command to whatever you usually use to launch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By the way, if you are using Regolith’s normal method of launching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt;, you can add your shell script to your Regolith configuration pretty easily. Open &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$HOME/.config/regolith3/Xresources&lt;/code&gt; in your text editor, and add the line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wm.program.launcher.app: /path/to/your/launcher.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xrdb -override $HOME/.config/regolith3/Xresources&lt;/code&gt; and it should work! Good luck.&lt;/p&gt;

&lt;h2 id=&quot;drawbacks&quot;&gt;Drawbacks&lt;/h2&gt;

&lt;p&gt;One of the nice things about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt; is that it keeps track of applications your run frequently, so they tend to bubble up to the top of its application listing. The Emacs method doesn’t do that. I don’t mind so much, I always end up typing in application names. It is fun to use Emacs as an application launcher, and I hope that it helps me avoid the CPU-churn problem that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilia&lt;/code&gt; has been experiencing far too often.&lt;/p&gt;

&lt;p&gt;Have I come up with a clever solution, or a lazy workaround? I’m looking forward to hearing your thoughts.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Interviewed on &quot;Prot Speaks&quot;</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2025/08/interviewed-on-prot-speaks" rel="alternate" type="text/html" title="Interviewed on "Prot Speaks"" />
        <updated>2025-08-18T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2025/08/prot-speaks-interview</id>
          <category term="emacs" />
        
          <category term="podcast" />
        
          <category term="programming" />
        
          <category term="org-mode" />
        
          <category term="lisp" />
        
          <category term="golang" />
        
          <category term="portland" />
        <content type="html" xml:base="https://arnesonium.com/2025/08/interviewed-on-prot-speaks">&lt;p&gt;Well-known Emacs package creator Protesilaos Stavrou interviewed me for his video podcast series, “Prot Asks.” We talked about a wide variety of topics, from Emacs to podcasting to Portland to public transit. I thought it was a great time, and perhaps you will like it, too!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;You can read and view the video &lt;a href=&quot;https://protesilaos.com/codelog/2025-08-17-prot-asks-erik-emacs-1990s-portland-oregon-podcasting/&quot;&gt;on Prot’s website and blog&lt;/a&gt;, or you can go &lt;a href=&quot;https://www.youtube.com/watch?v=6wkfFdiwpyU&quot;&gt;straight to YouTube&lt;/a&gt;, or you can watch it embedded here below.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/6wkfFdiwpyU?si=ocNz3f6ehqEYYC2G&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Note that Prot is looking for people to talk to on this series! You can join in by &lt;a href=&quot;https://protesilaos.com/prot-asks/&quot;&gt;signing up on his website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;P.S. In the video, I promised that I would do another Emacs Carnival blog post, and I will, I swear! It is in my org-mode to-do file.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>maybe: A command-line tool that succeeds sometimes</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2025/02/maybe-succeeds-sometimes" rel="alternate" type="text/html" title="maybe: A command-line tool that succeeds sometimes" />
        <updated>2025-02-13T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2025/02/maybe-succeeds-sometimes</id>
          <category term="programming" />
        
          <category term="golang" />
        
          <category term="github" />
        <content type="html" xml:base="https://arnesonium.com/2025/02/maybe-succeeds-sometimes">&lt;p&gt;I just released &lt;a href=&quot;https://github.com/pymander/maybe/releases/tag/v1.0.0&quot;&gt;version 1.0.0 of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt;&lt;/a&gt;, a command-line utility that succeeds some of the time. It
is written in Go and is not very many lines of code, but I do hope that it can be useful for people.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;some-history&quot;&gt;Some History&lt;/h2&gt;

&lt;p&gt;I recently got a &lt;a href=&quot;https://amzn.to/3CYb9he&quot;&gt;Korg Volca Drums&lt;/a&gt; drum synthesizer. It has a sequencer that allows you to program
the probability of a particular instrument playing on a particular step, and I thought that was a
really cool feature. This inspired me to think about cron jobs that happen only some of the time.
Maybe the cron job would run, maybe it wouldn’t.&lt;/p&gt;

&lt;p&gt;This inspired me to write &lt;a href=&quot;https://github.com/pymander/maybe&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt;&lt;/a&gt;, a command-line utility that returns either success or failure,
based on flags you pass it. It defaults to succeeding 50 percent of the time, but you can change
that. This means you could make a cron job like this, which would run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do-something.sh&lt;/code&gt; 40 percent
of the time.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# At midnight every Sunday, do something sometimes.&lt;/span&gt;
0 0 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; 0     maybe &lt;span class=&quot;nt&quot;&gt;-chance&lt;/span&gt; 40 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-something&lt;/span&gt;.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-future-of-maybe&quot;&gt;The Future of maybe&lt;/h2&gt;

&lt;p&gt;I don’t think I will stop at version 1.0.0. I have already considered what may happen to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt; in
the future. Here are some things that I would like to do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add cryptographically secure randomness. There is no reason to use Go’s default random library.
Let us try to be as random as possible.&lt;/li&gt;
  &lt;li&gt;More granularity to the randomness. What if you want to run something 40.5 percent of the time?&lt;/li&gt;
  &lt;li&gt;Experiment with GitHub actions, such as building binaries for every operating system that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt;
should support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, the opportunities for improvement are many. And maybe (ha ha!) you will see
improvements soon!&lt;/p&gt;

&lt;p&gt;Perhaps this is a good time to visit &lt;a href=&quot;https://github.com/pymander/maybe&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt; on GitHub&lt;/a&gt; and star the repo so others can find it?&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Many Posts of Interest for January 2024</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2024/01/18-many-posts-of-interest.html" rel="alternate" type="text/html" title="Many Posts of Interest for January 2024" />
        <updated>2024-01-18T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2024/01/export</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="security" />
        
          <category term="portland" />
        
          <category term="history" />
        <content type="html" xml:base="https://arnesonium.com/2024/01/18-many-posts-of-interest.html">&lt;p&gt;Once again, I have collected far too many links over far too long a period of time. Anyhow, here is a collection of blog posts and links from around the web that I found to be good reading over the past couple of months. Is it too late in January to say Happy New Year?
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;2024 has been a pretty weird year for me so far. I spent the first couple weeks of the year in isolation, and then Portland got hit with a Snowpocalypse (I love how that’s a regular thing now), followed by freezing rain. This is the third day in a row that the sidewalk outside my front door is basically an ice skating rink. That means it’s a great time to do some reading!&lt;/p&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://signal.org/blog/signal-is-expensive/&quot;&gt;Privacy is Priceless, but Signal is Expensive&lt;/a&gt; &lt;strong&gt;[Security]&lt;/strong&gt;
I really appreciate this incredible breakdown of Signal’s costs and how they use donations. Signal
is cool. You should be using it. For real.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.schneier.com/blog/archives/2023/11/breaking-laptop-fingerprint-sensors.html&quot;&gt;Breaking Laptop Fingerprint Sensors&lt;/a&gt; (Bruce Schneier) &lt;strong&gt;[Security]&lt;/strong&gt;
Do people actually use their laptop fingerprint sensors? I hate mine. I just disable the dang
things and use a password.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.schneier.com/blog/archives/2023/12/surveillance-by-the-us-postal-service.html&quot;&gt;Surveillance by the US Postal Service&lt;/a&gt; (Bruce Schneier) &lt;strong&gt;[Security]&lt;/strong&gt;
To Catch a Thief, starring Cliff from Cheers.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://siliconflorist.com/2023/12/06/senator-ron-wyden-of-oregon-opens-discussion-of-push-notification-surveillance-by-apple-and-google/&quot;&gt;Senator Ron Wyden of Oregon opens discussion of push notification surveillance by Apple and Google&lt;/a&gt; (Rick Turoczy) &lt;strong&gt;[Security]&lt;/strong&gt;
There is some interesting legal stuff going on around the ability of tech companies like Apple and Google to use push
notifications to capture user data that could be used for nefarious purposes. Definitely a story to
keep your eye on!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://irreal.org/blog/?p=11863&quot;&gt;Holding NSA’s Feet To The Fire&lt;/a&gt; (jcs) &lt;strong&gt;[Security]&lt;/strong&gt;
Here is a second post about Senator Ron Wyden. He appears to be fighting the good fight! Go Senator Wyden!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;emacs&quot;&gt;Emacs&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://tech.toryanderson.com/2023/11/29/transient-for-convenience-with-emms/&quot;&gt;Transient for convenience with emms&lt;/a&gt; &lt;strong&gt;[Emacs]&lt;/strong&gt;
Tory Anderson shares a really convenient EMMS control panel that uses the new version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transient&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arrayfire.com/blog/talk-to-emacs-with-a-gpt4-co-worker/&quot;&gt;Talk to Emacs with a GPT4 Co-Worker&lt;/a&gt; &lt;strong&gt;[Emacs]&lt;/strong&gt; Gallagher Pryor shares a method he has for speaking to Emacs using ChatGPT-4. This is from back in November, so perhaps he has a package now!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://takeonrules.com/2023/12/03/mentoring-vs-coders-as-an-emacsian/&quot;&gt;Jeremy Friesen: Mentoring VS-Coders as an Emacsian&lt;/a&gt; (Jeremy Friesen) &lt;strong&gt;[Emacs]&lt;/strong&gt;
I really enjoyed this talk about moving people away from VS Code and toward Emacs. The big takeaway
for this talk seemed to be that demonstrating what Emacs could do was going to be more effective
than just arguing. Let Emacs win just by letting it do what it does.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://takeonrules.com/2023/12/09/test-driving-a-campaign-status-document/&quot;&gt;Jeremy Friesen: Test Driving a Campaign Status Document&lt;/a&gt; (Jeremy Friesen) &lt;strong&gt;[Emacs]&lt;/strong&gt;
This post has some superb ideas for running a TTRPG campaign from Emacs. I’ve been doing this
for a while, but my documents get really messy. I need something a bit more structured.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://sachachua.com/blog/2023/12/emacsconf-backstage-using-spookfox-to-publish-youtube-and-toobnix-video-drafts/&quot;&gt;EmacsConf backstage: Using Spookfox to publish YouTube and Toobnix video drafts&lt;/a&gt; (Sacha Chua) &lt;strong&gt;[Emacs]&lt;/strong&gt;
I love how crazy this is: using &lt;a href=&quot;https://bitspook.in/projects/spookfox/&quot;&gt;spookyfox&lt;/a&gt; to work with YouTube’s crappy interface to do things to
videos. Go Sacha!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://yummymelon.com/devnull/improving-emacs-isearch-usability-with-transient.html&quot;&gt;Charles Choi: Improving Emacs isearch Usability with Transient&lt;/a&gt; (Charles Choi) &lt;strong&gt;[Emacs]&lt;/strong&gt;
This is pretty cool. I recently learned about how rich the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isearch&lt;/code&gt; feature set is, but I haven’t
played around with it a ton yet. Another thing to add to my Emacs to-do list!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.miskatonic.org/2024/01/08/org-citations-basic/&quot;&gt;William Denton: Basic citations in Org (Part 1)&lt;/a&gt; (William Denton) &lt;strong&gt;[Emacs]&lt;/strong&gt;
This is an excellent introduction to how citations work in org-mode. There are four parts in the series so far, so keep reading!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;programming&quot;&gt;Programming&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://irreal.org/blog/?p=11796&quot;&gt;Pike’s Rules Of Programming&lt;/a&gt; (jcs) &lt;strong&gt;[Programming]&lt;/strong&gt;
These are some good rules, even if they can make some parts of programming a little less exciting.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.brycewray.com/posts/2023/11/variations-styling-variables-ssgs/?utm_campaign=RSS&amp;amp;utm_source=RSS&amp;amp;utm_medium=RSS&quot;&gt;Variations on styling variables in SSGs&lt;/a&gt; (Bryce Wray) &lt;strong&gt;[Programming]&lt;/strong&gt;
I am still using Sass a lot more than the vanilla CSS stuff that should be replacing it. Also, I am
starting to see that this is a change I’ll need to take in my future WebDev adventures.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.brycewray.com/posts/2023/11/firefox-brink/?utm_campaign=RSS&amp;amp;utm_source=RSS&amp;amp;utm_medium=RSS&quot;&gt;Firefox on the brink?&lt;/a&gt; (Bryce Wray) &lt;strong&gt;[Programming]&lt;/strong&gt;
Bryce Wray is warning (or predicting?) that Firefox may be in a very dangerous spot in its loss of
user share. This is really disappointing, given how evil Chrome continues to be. And it’s only going to
get more evil. Convince your friends to run Firefox!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zck.org/numberdle&quot;&gt;Zachary Kanfer: Numberdle!&lt;/a&gt; (Zachary Kanfer) &lt;strong&gt;[Programming]&lt;/strong&gt;
This is a really fun browser game for people who enjoy numbers more than words. Move over, Wordle!!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;history&quot;&gt;History&lt;/h2&gt;

&lt;p&gt;Finally, here’s something fun to share with the kids.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.smithsonianmag.com/history/history-teddy-bear-once-seen-dangerous-influence-young-children-180983234/&quot;&gt;The Teddy Bear Was Once Seen as a Dangerous Influence on Young Children&lt;/a&gt;
Before gifting stuffed animals to the wee ones in your life, consider that &lt;em&gt;bears are dangerous!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
      </entry>
    
      <entry>
        
        <title>EmacsConf 2023 Retrospective</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/12/emacsconf-retrospective" rel="alternate" type="text/html" title="EmacsConf 2023 Retrospective" />
        <updated>2023-12-04T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/12/emacsconf</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="conference" />
        
          <category term="writing" />
        <content type="html" xml:base="https://arnesonium.com/2023/12/emacsconf-retrospective">&lt;p&gt;This past weekend was &lt;a href=&quot;https://emacsconf.org/2023/&quot;&gt;EmacsConf 2023&lt;/a&gt;. It was held entirely online, which was great because I could attend in my pyjamas! Since it happened on Eastern Standard Time and I live on the Pacific coast, I found the pyjama-enablement to be quite conducive to an excellent conference experience. Here are some things I learned by waking up at 5:30 in the morning this weekend!
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Before getting into the good stuff, I should add that I did not spend a lot of time taking notes during the conference. Instead, I usually jumped straight into my Emacs configuration and started tinkering and fooling around. This means that I’ve probably left out some great stuff.&lt;/p&gt;

&lt;h2 id=&quot;emacs-advocacy&quot;&gt;Emacs Advocacy&lt;/h2&gt;

&lt;p&gt;There were a couple of talks about Emacs advocacy, but the one that I paid the most attention to was &lt;a href=&quot;https://emacsconf.org/2023/talks/mentor/&quot;&gt;Mentoring VS-Coders as an Emacsian&lt;/a&gt; by &lt;a href=&quot;https://takeonrules.com&quot;&gt;Jeremy Friesen&lt;/a&gt;. I think the big takeaway was that he got more mileage out of showing the power of Emacs than he did by trying to argue with users of other editors. Emacs users tend to already understand the power and flexibility of the tool they are using; just show it off, let it do the work.&lt;/p&gt;

&lt;p&gt;However, another topic that was brought up in a number of talks was that having all of your projects available in the same tool seems to enable a better, richer type of thinking. Being able to both write effectively and program efficiently in Emacs helps generate more complete thoughts. It also seems to spur creativity and help people conceptualize projects better. This may be a big part of advocacy, as very few other programming editors are also good at writing and note-taking, which leads me to …&lt;/p&gt;

&lt;h2 id=&quot;writing&quot;&gt;Writing&lt;/h2&gt;

&lt;p&gt;I do &lt;a href=&quot;/tags/writing&quot;&gt;a lot of writing in Emacs&lt;/a&gt;, and I’m not the only one. &lt;a href=&quot;https://emacs.ch/@jameshowell&quot;&gt;James Howell&lt;/a&gt; gave a talk about &lt;a href=&quot;https://emacsconf.org/2023/talks/uni/&quot;&gt;authoring and presenting university courses with Emacs&lt;/a&gt;. I have also written and presented lectures and classes using just Emacs. It has the power to create slides, lecture notes, and even handouts from the same source. There were a few more great talks about writing, including another one by Jeremy Friesen (he seems to do a lot of cool stuff).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.howardism.org/&quot;&gt;Howard Abrams&lt;/a&gt; talked about &lt;a href=&quot;https://emacsconf.org/2023/talks/solo/&quot;&gt;playing table-top role playing games (TTRPGs) in Emacs&lt;/a&gt;. He focused on how the pandemic had encouraged him to look into solo TTRPGs, which led him to &lt;a href=&quot;https://www.ironswornrpg.com/&quot;&gt;Ironsworn&lt;/a&gt;. Howard then created a full Ironsworn system in Emacs that allows him to play the game on its own. I am including this under the “Writing” section because solo TTRPG play is a lot like writing fiction, it’s just that you use rules and randomness to help you figure out where the story goes. One of the best things about this talk is that the pre-recorded video was produced by &lt;a href=&quot;https://youtu.be/6s1xF-Mya98?si=jbmzgUX9Mx5byV-n&quot;&gt;his son&lt;/a&gt;. It looks great!&lt;/p&gt;

&lt;h2 id=&quot;hyper-things-hyperbole-and-hyperdrive&quot;&gt;Hyper Things (Hyperbole and Hyperdrive)&lt;/h2&gt;

&lt;p&gt;I watched a talk about &lt;a href=&quot;https://www.gnu.org/software/hyperbole/&quot;&gt;Hyperbole&lt;/a&gt; again this year. This is an Emacs package that I would really love to figure out how to use, but it just doesn’t integrate cleanly into my configuration nor my workflow. I tried it last year and got kind of annoyed at it. I gave it another try during &lt;a href=&quot;https://emacsconf.org/2023/talks/hyperamp/&quot;&gt;Rob Weiner’s talk&lt;/a&gt;, but this time I couldn’t even get Hyperbole to properly set itself up. Anyhow, I gave up on it again. Until next year, Hyperbole!&lt;/p&gt;

&lt;p&gt;Now &lt;a href=&quot;https://ushin.org/hyperdrive/hyperdrive-manual.html&quot;&gt;Hyperdrive&lt;/a&gt;, on the other hand, was something new and interesting. Joseph Turner and Protesilaos Stavrou gave a talk on &lt;a href=&quot;https://emacsconf.org/2023/talks/hyperdrive/&quot;&gt;hyperdrive.el: Peer-to-peer filesystem in Emacs&lt;/a&gt;. Set up was extremely simple; &lt;em&gt;it just worked.&lt;/em&gt; I was quickly able to share hyperdrive files and links with others. It remains to be seen what my use-case for Hyperdrive will be, but I look forward to watching this project develop.&lt;/p&gt;

&lt;h2 id=&quot;emms&quot;&gt;EMMS&lt;/h2&gt;

&lt;p&gt;Yoni Rabkin gave &lt;a href=&quot;https://emacsconf.org/2023/talks/emms/&quot;&gt;a talk on the Emacs Multi-Media System (EMMS)&lt;/a&gt;. I like EMMS, but I don’t use it as regularly as I should. However, Rabkin’s talk encouraged me to give it another chance. I am currently listening to Information Society in EMMS while I write this blog post. I suspect that like most people, I don’t really dig into my old MP3 collection as much as I should. This is a good excuse! Rabkin was also happy to remind the audience that EMMS can handle streaming online music sources and playing pretty much every kind of media. It’s worth exploring EMMS again!&lt;/p&gt;

&lt;h2 id=&quot;overall-impression&quot;&gt;Overall Impression&lt;/h2&gt;

&lt;p&gt;I loved EmacsConf this year. I also loved it last year. The organizers and moderators did such a great job running this conference, and it seemed to have a lot of attendees. I followed along on IRC and on Mastodon, and there was a ton of great talk happening. In addition, the Q&amp;amp;A sessions that I saw were filled with enriching conversation. I’m really looking forward to next year. Maybe I’ll find something on which to present!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Posts of Interest for November 2023</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/11/16-posts-of-interest.html" rel="alternate" type="text/html" title="Posts of Interest for November 2023" />
        <updated>2023-11-16T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/11/export</id>
          <category term="emacs" />
        
          <category term="games" />
        
          <category term="programming" />
        
          <category term="security" />
        <content type="html" xml:base="https://arnesonium.com/2023/11/16-posts-of-interest.html">&lt;p&gt;I was planning to make posts like this more regularly, but I entered into a period where I was thinking, huh, I am not collecting very many links. But I was wrong, I was collecting links. I collected too many. And now look at everything you have to read! I am sure these links will keep you occupied for a while.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://krebsonsecurity.com/2023/10/tech-ceo-sentenced-to-5-years-in-ip-address-scheme/&quot;&gt;Tech CEO Sentenced to 5 Years in IP Address Scheme&lt;/a&gt; (BrianKrebs) &lt;strong&gt;[Security]&lt;/strong&gt;
This is an interesting story: five years in prison for stealing IP addresses! I guess you shouldn’t
do that.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://securityintelligence.com/articles/defense-in-depth-layering-your-security-coverage/&quot;&gt;Defense in depth: Layering your security coverage&lt;/a&gt; (Sue Poremba) &lt;strong&gt;[Security]&lt;/strong&gt;
Security isn’t just at the edge. Layers are very important, as this article reminds us.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://irreal.org/blog/?p=11754&quot;&gt;How The Thompson Hack Worked&lt;/a&gt; (jcs) &lt;strong&gt;[Security]&lt;/strong&gt;
Aaaah! This is an amazing look at Ken Thompson’s 1983 Turing Award lecture. How can we trust
software? Do we trust software? You’ll enjoy this one and it will tickle your inner computer nerd.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://securityintelligence.com/articles/pentesting-vs-pentesting-as-a-service/&quot;&gt;Pentesting vs. Pentesting as a Service: Which is better?&lt;/a&gt; (Josh Nadeau) &lt;strong&gt;[Security]&lt;/strong&gt;
What is pentesting and how does it work? Well, now you can know.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;emacs&quot;&gt;Emacs&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://emacs.ch/@crmsnbleyd/111260721575616368&quot;&gt;Whatever happened to Guile-based Emacs?&lt;/a&gt; &lt;strong&gt;[Emacs, Mastodon]&lt;/strong&gt;
This thread on Mastodon has some insights into what ever happened to a Guile-based Emacs.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://andreyor.st/posts/2023-10-27-you-dont-need-a-terminal-emulator/&quot;&gt;Andrey Listopadov: You don’t need a terminal emulator&lt;/a&gt; (Andrey Listopadov) &lt;strong&gt;[Emacs]&lt;/strong&gt;
Andrey Listopadov explains how he stopped using a terminal emulator because he’s all about that
Emacs. Nice!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://irreal.org/blog/?p=11742&quot;&gt;Emacs Line Wrapping&lt;/a&gt; (jcs) &lt;strong&gt;[Emacs]&lt;/strong&gt;
For several years, I have been dealing with a line-wrapping annoyance in Emacs that I just couldn’t
figure out. It turns out it was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filladapt&lt;/code&gt;, a package that apparently isn’t used often anymore, but
I hadn’t noticed. I disabled the package and everything just works the way I want it to. &lt;em&gt;Arrrgh!&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://irreal.org/blog/?p=11751&quot;&gt;Does Working From Home Damage Productivity?&lt;/a&gt; (jcs) &lt;strong&gt;[Emacs]&lt;/strong&gt;
I have mostly worked from wherever-I-want for the last 14 years, and I’d have it no other way.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;games&quot;&gt;Games&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://kmalexander.com/2023/07/13/kensett-a-free-19th-century-urban-cartography-brush-set-for-fantasy-maps/&quot;&gt;Kensett: A Free 19th Century Urban Cartography Brush Set for Fantasy Maps&lt;/a&gt; (K. M. Alexander)
K.M. Alexander shares a lot of cool brush sets for creating maps for fantasy games. I have been
trying to figure out how to use them, and this one really caught my eye. Check out all of their
brush sets!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://kmalexander.com/2023/11/02/lovats-genesis-city-of-darkness/&quot;&gt;Lovat’s Genesis: City of Darkness&lt;/a&gt; (K. M. Alexander)
I am once again running a D&amp;amp;D game, with a homebrewed campaign, so I think it will be fun to include
a few RPG-related posts every once in a while. Seeing how others get their inspiration is really
helpful when I need to find some of my own.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;history&quot;&gt;History&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://publicdomainreview.org/essay/silent-treatment&quot;&gt;The Silent Treatment: Solitary Confinement’s Unlikely Origins&lt;/a&gt; &lt;strong&gt;[Pub 20231101]&lt;/strong&gt;
A very curious history of solitary confinement and its origins, presented by the Public Domain
Review. This is worth a read.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.smithsonianmag.com/history/what-emojis-tell-us-about-the-history-of-tea-180983128/&quot;&gt;What Emoji Tell Us About the History of Tea&lt;/a&gt;
I love the strange history of tea, and the Smithsonian has managed to tie this history to tea emoji.
So that’s cool.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://publicdomainreview.org/collection/unionization-of-central-europe&quot;&gt;Divide and Concur: A Radical Plan for Peace in Europe (1920)&lt;/a&gt; &lt;strong&gt;[History]&lt;/strong&gt;
This is an amazing and bizarre plan for bringing peace to Europe in the 1920s. It is worth looking
at and puzzling over.&lt;/li&gt;
&lt;/ul&gt;</content>
      </entry>
    
      <entry>
        
        <title>Posts of Interest for 13 October 2023</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/10/13-posts-of-interest" rel="alternate" type="text/html" title="Posts of Interest for 13 October 2023" />
        <updated>2023-10-13T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/10/of-interest</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="emacs-lisp" />
        
          <category term="security" />
        <content type="html" xml:base="https://arnesonium.com/2023/10/13-posts-of-interest">&lt;p&gt;This is the second of my “posts of interest” posts. This week, I have also included some interesting Mastodon posts, because the Emacs community on Mastodon is thriving like crazy. It is really a blast to see so much interest in Emacs and so much activity.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;If Mastodon interests you, &lt;a href=&quot;https://fosstodon.org/@pymander&quot;&gt;find me there&lt;/a&gt;!&lt;/p&gt;

&lt;h2 id=&quot;programming-1&quot;&gt;Programming (1)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://spritely.institute/news/scheme-wireworld-in-browser.html&quot;&gt;Scheme in the browser: A Hoot of a tale&lt;/a&gt; – Spritely Institute
Yes, SCHEME IN THE BROWSER. This is pretty cool, go check it out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;emacs-6&quot;&gt;Emacs (6)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://coredumped.dev/2023/08/09/text-showdown-gap-buffers-vs-ropes/&quot;&gt;Text showdown: Gap Buffers vs Ropes&lt;/a&gt; &lt;strong&gt;[Programming, Rust]&lt;/strong&gt;
Troy Hinckley has been working on building the core of Emacs in Rust. This sounds like a very
difficult project, and it is informative and interesting to follow along. The latest entry in his
saga involves various ways of storing and working with text buffers, along with many benchmarks.
This is an interesting read!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://amodernist.com/eaez/./sep23.html&quot;&gt;ELPA and Emacs Zine (September 2023)&lt;/a&gt;
The new ELPA and Emacs Zine has released its latest issue, with some pretty interesting stuff about
the current state of tree-sitter and how development is progressing.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://functional.cafe/@PaniczGodek/111187231582720915&quot;&gt;Emacs Macros&lt;/a&gt; &lt;strong&gt;[Mastodon]&lt;/strong&gt;
Emacs macros remain kind of a mystery to me, but they were presented in an interesting way recently:
these are ways to provide a high level of automation in Emacs without learning how to program Emacs
Lisp. Well, they are worth checking out, then!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://fosstodon.org/@chmouel/111203691941968313&quot;&gt;Taking advantage of tree-sitter&lt;/a&gt; &lt;strong&gt;[Mastodon]&lt;/strong&gt;
This is a really cool Emacs function that takes advantage of tree-sitter to copy the current
function. I think it might need something to detect if tree-sitter is active, and error out if not.
    &lt;div class=&quot;language-emacs-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;my-copy-function-name-with-ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;funcname&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;substring-no-properties&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;treesit-node-text&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;treesit-node-child-by-field-name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;treesit-defun-at-point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;kill-new&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;funcname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Copied name: %s&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;funcname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://octodon.social/@fabionatali/111210018767997686&quot;&gt;XMPP in Emacs&lt;/a&gt; &lt;strong&gt;[Mastodon]&lt;/strong&gt;
Fabio Natali on Mastodon reports that his XMPP usage would be more consistent if Emacs supported it
better. In particular, he misses E2E encryption support. I’ve also had a lot of difficulty with
moving to XMPP.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://alexschroeder.ch/view/2023-10-11-post-from-emacs&quot;&gt;Alex Schroeder: Posting to Oddµ from Emacs&lt;/a&gt; (Alex Schroeder)
Alex Schroeder provides a simple, straightforward way to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;url&lt;/code&gt; package in Emacs to post
stuff to another service. In this example, he uses Oddμ.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;security-4&quot;&gt;Security (4)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://securityintelligence.com/posts/c-suite-weighs-generative-ai-security/&quot;&gt;C-suite weighs in on generative AI and security&lt;/a&gt; (Chris McCurdy)
More on the adoption of generative AI and security risks. 96% of business leaders say adopting generative AI makes a security breach likely in their organization within the next three
years! That’s certainly something to think about.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://securityintelligence.com/articles/cost-of-a-data-breach-10-years-in-review/&quot;&gt;10 years in review: Cost of a Data Breach&lt;/a&gt; (Jonathan Reed)
Data breaches are dang expensive! We all know that. This piece explores some of the most important
factors in preventing and mitigating data breaches. There have been some changes in recent years,
some of which are caused by the rise of importance in AI. That means you should probably read the article.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://newsletter.mollywhite.net/p/the-fraud-was-in-the-code&quot;&gt;The fraud was in the code&lt;/a&gt; (Molly White)
In the SBF court case, they actually used a code review to show fraud.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.schneier.com/blog/archives/2023/10/bounty-to-recover-nists-elliptic-curve-seeds.html&quot;&gt;Bounty to Recover NIST’s Elliptic Curve Seeds&lt;/a&gt; (Bruce Schneier)
Here is a delightful story about the history of NIST elliptic curve cryptography and how things came
to be. Also, a cryptographic puzzle about where they may be going!&lt;/li&gt;
&lt;/ul&gt;</content>
      </entry>
    
      <entry>
        
        <title>Posts of Interest for 6 October 2023</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/10/6-posts-of-interest" rel="alternate" type="text/html" title="Posts of Interest for 6 October 2023" />
        <updated>2023-10-06T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/10/export</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="portland" />
        
          <category term="security" />
        
          <category term="pdx" />
        <content type="html" xml:base="https://arnesonium.com/2023/10/6-posts-of-interest">&lt;p&gt;This is my first attempt at using &lt;a href=&quot;https://github.com/rnadler/elfeed-curate&quot;&gt;elfeed-curate&lt;/a&gt; to collect interesting blog posts and share them. I have also attempted to subscribe to the RSS feed for the #Emacs hashtag on Mastodon, but that doesn’t seem to be working correctly yet. I’ve seen other blogs do similar things, but is this useful for my blog? I don’t know! Let me know what you think.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;computers-4&quot;&gt;Computers (4)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.brycewray.com/posts/2023/10/cloudflare-fonts/?utm_campaign=RSS&amp;amp;utm_source=RSS&amp;amp;utm_medium=RSS&quot;&gt;The intriguing announcement of Cloudflare Fonts&lt;/a&gt; (Bryce Wray) &lt;strong&gt;[Programming]&lt;/strong&gt;
Oooh, this is cool. Bryce Wray talks about the introduction of Cloudflare Fonts!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://securityintelligence.com/articles/what-to-know-about-new-generative-ai-tools-for-criminals/&quot;&gt;What to know about new generative AI tools for criminals&lt;/a&gt; (Mike Elgan) &lt;strong&gt;[Security]&lt;/strong&gt;
Generative AI is still a minor concern for security professionals, but the threat is rising! This is
an interesting look at the state of the art and current means for addressing the threat.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://alexschroeder.ch/view/2022-03-20_Torchbearers_and_bodyguards&quot;&gt;Alex Schroeder: 2022-03-20 Torchbearers and bodyguards&lt;/a&gt; (Alex Schroeder) &lt;strong&gt;[Emacs]&lt;/strong&gt;
Alex Schroeder continues his exploration of running tabletop RPGs using Emacs. Check out the other
blog posts in the series—they are a lot of fun. I have been playing with Emacs for running TTRPGs,
as well. Someday I’ll explain my methods.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://irreal.org/blog/?p=11683&quot;&gt;Elfeed-curate&lt;/a&gt; (jcs) &lt;strong&gt;[Emacs]&lt;/strong&gt;
Elfeed-curate sounds like a really neat package. This is my first annotation using that package,
which I will soon attempt to export.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;portland-1&quot;&gt;Portland (1)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.friendsoflonefircemetery.org/?p=943&quot;&gt;Tour of Untimely Departures – SOLD OUT!&lt;/a&gt; (lfadmin)
The Tour of Untimely Departures is an annual event at Lone Fir Cemetery in Portland. But guess what?
It’s already sold out! It sold out a while back, but I didn’t notice because my RSS feed for the
Friends of Lone Fir was broken.&lt;/li&gt;
&lt;/ul&gt;</content>
      </entry>
    
      <entry>
        
        <title>Configuring Emacs 29.1 for Go Development</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/08/configuring-emacs-29-1-for-golang" rel="alternate" type="text/html" title="Configuring Emacs 29.1 for Go Development" />
        <updated>2023-08-01T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/08/golang-emacs</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="golang" />
        
          <category term="lisp" />
        
          <category term="emacs-lisp" />
        <content type="html" xml:base="https://arnesonium.com/2023/08/configuring-emacs-29-1-for-golang">&lt;p&gt;Now that I have &lt;a href=&quot;https://arnesonium.com/2023/07/emacs-29-1-on-ubuntu-22-04-lts&quot;&gt;installed Emacs 29.1&lt;/a&gt;, I needed to get it set up for Go development for a project. I was interested in taking advantage of both the new Tree-Sitter integration, and the new Eglot language server client. However, they were mildly tricky to set up! Here is what I did.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;configuring-tree-sitter-for-go&quot;&gt;Configuring Tree-Sitter for Go&lt;/h2&gt;

&lt;p&gt;If you follow the excellent &lt;a href=&quot;https://www.masteringemacs.org/article/how-to-get-started-tree-sitter&quot;&gt;How to Get Started with Tree-Sitter&lt;/a&gt; instructions from Mickey Peterson, you will have a great head-start on getting Tree-Sitter working for most of your favorite languages (and probably Java, too). However, those instructions didn’t cover everything I needed for Go. When I tried running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x go-ts-mode&lt;/code&gt;, Emacs complained about a missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt; module. Baffling!&lt;/p&gt;

&lt;p&gt;I couldn’t find any information in the Emacs documentation about where to find this missing module. I looked around on the net and found &lt;a href=&quot;https://github.com/camdencheek/tree-sitter-go-mod&quot;&gt;Camden Cheek’s tree-sitter-go-mod&lt;/a&gt;, and added that to my list of recipes. My &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;treesit-language-source-alist&lt;/code&gt; then looked like this:&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;treesit-language-source-alist&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-bash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cmake&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/uyha/tree-sitter-cmake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;css&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-css&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;elisp&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/Wilfred/tree-sitter-elisp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-go&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gomod&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/camdencheek/tree-sitter-go-mod&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dockerfile&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/camdencheek/tree-sitter-dockerfile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;javascript&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-javascript&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;json&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/alemuller/tree-sitter-make&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;markdown&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/ikatyang/tree-sitter-markdown&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-python&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;toml&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-toml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tsx&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-typescript&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tsx/src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;typescript&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-typescript&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;typescript/src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/ikatyang/tree-sitter-yaml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that the package is named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-mod&lt;/code&gt; but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-ts-mode&lt;/code&gt; expects it to be named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt;. I wish this were documented somewhere! In any case, I was then able to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x treesit-install-language-grammar&lt;/code&gt; for both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt;. Finally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x go-ts-mode&lt;/code&gt; worked!&lt;/p&gt;

&lt;p&gt;After going through this process, I found &lt;a href=&quot;https://robbmann.io/posts/emacs-treesit-auto/&quot;&gt;Robert Enzmann’s post about automatically using Tree-Sitter&lt;/a&gt;. He has created the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;treesit-auto&lt;/code&gt; package, now available on MELPA, that does most of this work for you. It is a much faster way of solving the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt; mystery, so give it a shot!&lt;/p&gt;

&lt;h2 id=&quot;configuring-eglot-for-go&quot;&gt;Configuring Eglot for Go&lt;/h2&gt;

&lt;p&gt;I’d been using &lt;a href=&quot;https://github.com/emacs-lsp/lsp-mode&quot;&gt;lsp-mode&lt;/a&gt; for ages, but with Emacs 29.1 including &lt;a href=&quot;https://joaotavora.github.io/eglot/&quot;&gt;Eglot&lt;/a&gt;, I decided to make the switch.&lt;/p&gt;

&lt;p&gt;In my Go project, I ran &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x eglot&lt;/code&gt; and was immediately met with an error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[eglot] Server reports (type=1): Error loading workspace folders (expected 1, got 0)
failed to load view for file:///path/to/my/project: err: go command required, not found: exec: &quot;go&quot;: executable file not found in $PATH: stderr: 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve got Go installed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/go&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/go/bin&lt;/code&gt; is definitely in my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec-path&lt;/code&gt; variable in Emacs. It looked like Eglot wasn’t propagating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec-path&lt;/code&gt; down to its subprocesses. How annoying! I did a quick search through the list of Eglot-related variables and the Eglot documentation and no solution seemed immediately forthcoming.&lt;/p&gt;

&lt;p&gt;So I took the cheap way out and made a symlink. In my shell, I ran:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-sf&lt;/span&gt; /usr/local/go/bin/go /usr/local/bin/go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is a dumb trick, and I am sure there is a better way to solve it. Do you know of one? Please comment and let me know!&lt;/p&gt;

&lt;h2 id=&quot;what-else&quot;&gt;What Else?&lt;/h2&gt;

&lt;p&gt;My exploration has revealed that there’s a lot of work left to do in the Emacs Tree-Sitter world. There are plenty of languages major modes that don’t yet have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts-mode&lt;/code&gt; equivalent, and plenty of others that still need a lot of work.&lt;/p&gt;

&lt;p&gt;It’s too soon for me to say if this setup is preferrable to my previous configuration. But I am really looking forward to playing around with Eglot’s features and exploring the capabilities of Tree-Sitter.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>FOSSY 2023 was Excellent</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/07/fossy-2023-retrospective" rel="alternate" type="text/html" title="FOSSY 2023 was Excellent" />
        <updated>2023-07-18T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/07/fossy-retrospective</id>
          <category term="open-source" />
        
          <category term="programming" />
        
          <category term="conference" />
        
          <category term="devops" />
        
          <category term="kubernetes" />
        
          <category term="containers" />
        
          <category term="artificial-intelligence" />
        
          <category term="machine-learning" />
        
          <category term="writing" />
        <content type="html" xml:base="https://arnesonium.com/2023/07/fossy-2023-retrospective">&lt;p&gt;This past weekend, I had the pleasure of attending the inaugural &lt;a href=&quot;https://2023.fossy.us/&quot;&gt;FOSSY conference&lt;/a&gt; in my home town of Portland, Oregon. FOSSY focuses on free and open source software, and included tracks on community, containers, compliance, diversity, gaming, and education. I got a chance to connect with friends &lt;em&gt;and&lt;/em&gt; make new friends. It was an excellent event, and in this post I’ll just focus on some highlights.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;writing-and-machine-learning&quot;&gt;Writing and Machine Learning&lt;/h2&gt;

&lt;p&gt;Software developers may get a lot of attention in FOSS spaces, but a lot of different types of contributions are required to create a successful open source project. The most significant contributions I’ve made to a large open source project have been &lt;a href=&quot;https://www.kubernetes.dev/blog/2020/09/28/contributing-to-the-development-guide/&quot;&gt;writing for Kubernetes&lt;/a&gt;. Projects also need community leaders, software architects, web designers, publicity and marketing experts, and quality assurance technicians. There is plenty of space for additional contributions in almost every open source project.&lt;/p&gt;

&lt;p&gt;FOSSY had some excellent sessions on writing, both from the point of view of a contributor to open source projects, and in examining how various open source projects can help the writer. &lt;a href=&quot;https://derwen.ai/paco&quot;&gt;Paco Nathan&lt;/a&gt; gave a very informative talk about &lt;a href=&quot;https://derwen.ai/s/rhvg&quot;&gt;language tools available for creators&lt;/a&gt;, focusing on machine learning, graph technology, and natural language processing. I also really enjoyed Kyle Davis’s talk on writing for open source projects. He discussed issues of style guides, adjusting your writing voice, and differentiating between marketing copy and open source writing.&lt;/p&gt;

&lt;h2 id=&quot;containers-containers-containers&quot;&gt;Containers, Containers, Containers&lt;/h2&gt;

&lt;p&gt;The Container Days track was deeply technical and educational. I didn’t get to attend as much of this track as I would have liked, because there was too much to focus on across the conference. However, I did manage to catch &lt;a href=&quot;https://berkus.org/&quot;&gt;Josh Berkus’s&lt;/a&gt; excellent talk, “The Cloud Native Burrito.” In it, Josh explained the composition of a fully cloud-native application using a delicious metaphor. Kubernetes is the tortilla of your application, while other essential components such as your container runtime and virtual network are the rice and beans. The metaphor went on—and yes, it was before lunch—until eventually though your stomach rumbled, Kubernetes made more sense.&lt;/p&gt;

&lt;p&gt;There was also a talk on &lt;a href=&quot;https://containers.dev/&quot;&gt;Development Containers&lt;/a&gt; that I really wanted to attend, but there was just too much!&lt;/p&gt;

&lt;h2 id=&quot;open-source-philosophy&quot;&gt;Open Source Philosophy&lt;/h2&gt;

&lt;p&gt;The most thought-provoking talk I attended was “FOSS in World Affairs” by &lt;a href=&quot;https://mastodon.social/@delib&quot;&gt;Delib&lt;/a&gt;. This talk deconstructed the philosophy of open source until it could be applied more broadly to larger social issues such as abuses of capitalism and the breakdown of social contracts. It generated a ton of discussion, including talk about how a corporation could be completely open-sourced, in a way that would welcome both collaboration and competition. I came away from this talk with a lot to think about.&lt;/p&gt;

&lt;p&gt;I also attended a talk by Keith Bergelt on mitigating patent risks in open source projects. He introduced me to the &lt;a href=&quot;https://openinventionnetwork.com/&quot;&gt;Open Invention Network&lt;/a&gt;, which I feel I should have known about before. This organization seeks to cushion large open source projects from patent litigation through various means such as building a “patent non-aggression community”. Bergelt was careful to point out that there are plenty of companies out there who seek to stall open source by leveraging patents.&lt;/p&gt;

&lt;h2 id=&quot;conclusion-do-it-again&quot;&gt;Conclusion: Do it Again&lt;/h2&gt;

&lt;p&gt;FOSSY was great. I hadn’t attended an open source conference in years, and it was really enjoyable to be around so many like-minded nerds. I hope they do it again next year! I’ll endeavor to attend again.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Pattern Matching and Tail Recursion in Emacs Lisp</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2022/11/pattern-matching-tail-recursion-emacs-lisp" rel="alternate" type="text/html" title="Pattern Matching and Tail Recursion in Emacs Lisp" />
        <updated>2022-11-19T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2022/11/tco-pattern-emacs-lisp</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="emacs-lisp" />
        
          <category term="lisp" />
        <content type="html" xml:base="https://arnesonium.com/2022/11/pattern-matching-tail-recursion-emacs-lisp">&lt;p&gt;Functional programming offers a bunch of really cool programming patterns. Two that I really enjoy are &lt;a href=&quot;https://stackoverflow.com/questions/310974/what-is-tail-call-optimization&quot;&gt;tail recursion&lt;/a&gt; and &lt;a href=&quot;https://sodocumentation.net/ocaml/topic/2656/pattern-matching&quot;&gt;pattern matching&lt;/a&gt;, especially how they are implemented in OCaml. However, I spend a lot of time writing Emacs Lisp now, and I was wondering if I could find a way to use these patterns in that language.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;It turns out that it is possible, thanks to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;named-let&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt;. It isn’t as pretty and elegant as OCaml, but at least I get to keep excercising those parts of my programming brain. Maybe next I’ll try to figure out currying in Emacs Lisp.&lt;/p&gt;

&lt;p&gt;Note that this blog post includes some &lt;em&gt;really dumb&lt;/em&gt; examples, because that’s usually how I learn these things best.&lt;/p&gt;

&lt;h2 id=&quot;pattern-matching-with-pcase&quot;&gt;Pattern Matching with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Most programmers will be familiar with the granddaddy of pattern matching, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch/case&lt;/code&gt; construct. This is present in many, many programming languages, especially those in the ALGOL family.&lt;/p&gt;

&lt;p&gt;However, pattern matching can be so much more! Instead of simple equality checks, pattern matching extends the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switch/case&lt;/code&gt; concept to include testing for all kinds of patterns and conditionals.&lt;/p&gt;

&lt;p&gt;Lisp programmers will already be familiar with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cond&lt;/code&gt;, which can be used to sequentially test for conditionals. However, functional language programmers have probably fallen in love with a more mature and sophisticated form of pattern matching that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cond&lt;/code&gt; doesn’t totally satisfy.&lt;/p&gt;

&lt;p&gt;Fortunately, Emacs Lisp has &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/elisp/Pattern_002dMatching-Conditional.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt;, the pattern-matching conditional&lt;/a&gt;. Here is an example of its use to duplicate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;car&lt;/code&gt;, which is the dumbest possible example I could think of.&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ela/car&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pcase&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lst&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt;
     &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt; has a backquote syntax for matching various constructs, such as with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;`(,head . ,_)&lt;/code&gt; piece. This matches a cons cell and binds the CAR to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;head&lt;/code&gt; while ignoring the CDR.&lt;/p&gt;

&lt;p&gt;The next case is just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_&lt;/code&gt;, which is a catch-all matching operator.&lt;/p&gt;

&lt;p&gt;In the real world, you’d probably want some type checking and error correction, but I promised very simple examples. Check out the full range of &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html&quot;&gt;matching capabilities for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt;&lt;/a&gt;, and then &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/elisp/Backquote-Patterns.html&quot;&gt;read about all of the backquote patterns you can also use&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;tail-call-optimization-with-named-let&quot;&gt;Tail Call Optimization with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;named-let&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Tail call optimization (TCO) is the programming language feature that allows efficient tail recursion without overflowing your stack. It is increasingly common in languages today, though from what I’ve seen, it always involves caveats.&lt;/p&gt;

&lt;p&gt;In Emacs Lisp, the easiest way to use TCO that I’ve come across is the &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/elisp/Local-Variables.html#index-named_002dlet&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;named-let&lt;/code&gt; macro&lt;/a&gt;. With it, you define a function that can get “unrolled” inside another function. For example, here is a simple function that calculates a factorial using tail recursion.&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ela/fact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;in-num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;named-let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rec-fact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;accu&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;in-num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pcase&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;num&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rec-fact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;accu&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;accu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example, you will notice that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rec-fact&lt;/code&gt; is the locally named function that gets called at the end of the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt; pattern. This is a tail call! It will get optimized.&lt;/p&gt;

&lt;p&gt;You can check this out by running something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(ela/fact 5)&lt;/code&gt; and getting 120 as the result. Try using a ridiculously big number and see if you get a stack overflow! You shouldn’t.&lt;/p&gt;

&lt;h2 id=&quot;another-example-summing-a-list&quot;&gt;Another Example: Summing a List&lt;/h2&gt;

&lt;p&gt;This is just a nostalgic example, since it’s probably the first tail recursive pattern matching function I ever wrote when learning OCaml a zillion years ago. This function will take a list of numbers and then add them all together. There are much better ways to write this in Emacs Lisp, like with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ela/sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;named-let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sum-list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;accu&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lst&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pcase&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lst&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sum-list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;accu&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;accu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can then call it like this:&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ela/sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And you will end up with exactly the result you expect. I was amused to see that the documentation page for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;named-let&lt;/code&gt; has a different implementation of this function that doesn’t use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Oh heck, let’s get fancy and rewrite &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; using this approach.&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ela/apply&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;Apply FN to each element of ARGUMENTS and return the accumulated result.&quot;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;;; Set up accumulator to the right type.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arguments-flat&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;flatten-list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;initial-value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pcase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;arguments-flat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pred&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;integerp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pred&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;stringp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;named-let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;apply-rec&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;accumulator&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;input-list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;arguments-flat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pcase&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input-list&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;apply-rec&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;funcall&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;accumulator&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;_&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;accumulator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I am certain this version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; has bugs, but it works for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;concat&lt;/code&gt;, so that’s good enough for a simple example. And it uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcase&lt;/code&gt; twice!&lt;/p&gt;

&lt;p&gt;Hopefully this has been a useful blog post for somebody out there. Let me know in the comments if there are other fun things you have done with TCO and pattern matching in Emacs Lisp!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Arduino Planetary Hours library</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2017/05/arduino-planetary-hours-library/" rel="alternate" type="text/html" title="Arduino Planetary Hours library" />
        <updated>2017-05-01T18:30:35+00:00</updated>
        <id>https://arnesonium.com/2017/05/arduino-planetary-hours-library</id>
          <category term="arduino" />
        
          <category term="c" />
        
          <category term="planetary-hours" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2017/05/arduino-planetary-hours-library/">&lt;p&gt;I am finally announcing my &lt;a href=&quot;https://bitbucket.org/arnesonium/planetaryhours&quot;&gt;PlanetaryHours library for the Arduino&lt;/a&gt;. This library uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sun_rise()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sun_set()&lt;/code&gt; functions from the &lt;a href=&quot;http://www.nongnu.org/avr-libc/user-manual/group__avr__time.html&quot;&gt;avr-libc time.h&lt;/a&gt; library to calculate planetary hours.&lt;/p&gt;

&lt;p&gt;&lt;a class=&quot;button&quot; href=&quot;https://bitbucket.org/arnesonium/planetaryhours/get/v1.0.zip&quot;&gt;Download v1.0 Here&lt;/a&gt;
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Planetary hours are an old method of figuring out which planets are “in charge” at any moment. For more information on planetary hours, check out these resources:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.renaissanceastrology.com/planetaryhoursarticle.html&quot; target=&quot;_blank&quot;&gt;http://www.renaissanceastrology.com/planetaryhoursarticle.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.esotericarchives.com/agrippa/agripp2c.htm#chap34&quot; target=&quot;_blank&quot;&gt;http://www.esotericarchives.com/agrippa/agripp2c.htm#chap34&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can set up a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PlanetaryHour&lt;/code&gt; object by passing it a time zone offset in hours, a latitude, and a longitude. The following example might help.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define MYZONE -7
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;PlanetaryHour&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MYZONE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;45.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;122.7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, you can check the ruling planet of the current day and hour with an RTC or other time-keeping mechanism.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;time_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unixtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UNIX_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dayPlanet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dayPlanet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hourPlanet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hourPlanet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The return value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dayPlanet()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hourPlanet()&lt;/code&gt; is a number from 0 to 6, corresponding to the Chaldean planetary order.&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define SATURN 0
#define JUPITER 1
#define MARS 2
#define SUN 3
#define VENUS 4
#define MERCURY 5
#define MOON 6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ll be posting an article on &lt;a href=&quot;http://www.arnemancy.com/&quot; target=&quot;_blank&quot;&gt;the Arnemancy blog&lt;/a&gt; outlining a project I just installed using this library and some &lt;a href=&quot;https://www.adafruit.com/category/168&quot; target=&quot;_blank&quot;&gt;NeoPixels&lt;/a&gt;. I really look forward to seeing what others end up doing with this code!&lt;/p&gt;

&lt;p&gt;&lt;a class=&quot;button&quot; href=&quot;https://bitbucket.org/arnesonium/planetaryhours/get/v1.0.zip&quot;&gt;Download v1.0 Here&lt;/a&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Raspberry Pi GPIO with Erlang</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2017/04/raspberry-pi-gpio-with-erlang/" rel="alternate" type="text/html" title="Raspberry Pi GPIO with Erlang" />
        <updated>2017-04-10T17:23:14+00:00</updated>
        <id>https://arnesonium.com/2017/04/raspberry-pi-gpio-with-erlang</id>
          <category term="erlang" />
        
          <category term="programming" />
        
          <category term="raspberry-pi" />
        <content type="html" xml:base="https://arnesonium.com/2017/04/raspberry-pi-gpio-with-erlang/">&lt;p&gt;Raspberry Pis are super cool. One of the neat things about them is that they have a ton of general purpose input/output (GPIO) pins, so you can use them to control all sorts of external devices. Unfortunately, most of the examples and applications are written in Python. I know, a lot of people really love Python, but it’s just not my cup of tea.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Enter the &lt;a href=&quot;https://github.com/paoloo/gpio&quot; target=&quot;_blank&quot;&gt;Erlang πGPIO library&lt;/a&gt; by &lt;a href=&quot;https://paoloo.github.io/&quot; target=&quot;_blank&quot;&gt;Paolo Oliveira&lt;/a&gt;! This is a simple, straightforward library that implements the RPi GPIO stuff for Erlang. Using it, I have created an Erlang library to control a 28BYJ-48 5V stepper motor with a ULN2003 controller board.&lt;/p&gt;

&lt;p&gt;&lt;a class=&quot;button&quot; href=&quot;https://github.com/pymander/stepper&quot; target=&quot;_blank&quot;&gt;Check out the library here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;https://www.instagram.com/p/BSp2ZdSA0cg/?taken-by=pymander&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Using Amazon S3 as a Nette Service</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2016/10/using-amazon-s3-as-a-nette-service/" rel="alternate" type="text/html" title="Using Amazon S3 as a Nette Service" />
        <updated>2016-10-26T22:17:16+00:00</updated>
        <id>https://arnesonium.com/2016/10/using-amazon-s3-as-a-nette-service</id>
          <category term="aws" />
        
          <category term="nette" />
        
          <category term="php" />
        
          <category term="programming" />
        
          <category term="s3" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2016/10/using-amazon-s3-as-a-nette-service/">&lt;p&gt;&lt;a href=&quot;https://nette.org/&quot;&gt;Nette&lt;/a&gt; is a popular web application framework for PHP. It is mostly pretty well documented and easy to use. Recently, I needed to upload media from a Nette application to &lt;a href=&quot;https://aws.amazon.com/s3/&quot;&gt;Amazon S3&lt;/a&gt;. This is how I created an S3 service for my Nette application. You will need to be familiar with Nette and have an existing Nette application to follow along.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h1 id=&quot;installing-the-amazon-web-services-sdk&quot;&gt;Installing the Amazon Web Services SDK&lt;/h1&gt;

&lt;p&gt;Before anything will work, you will need to install the AWS SDK using Composer. Run the following command from your Nette project directory.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;php composer.phar require aws/aws-sdk-php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;the-s3uploader-service&quot;&gt;The S3Uploader Service&lt;/h1&gt;

&lt;p&gt;Next, create the file &lt;strong&gt;app/model/S3Uploader.php&lt;/strong&gt; and edit it to look like the following. You can also download my version &lt;a href=&quot;https://gist.github.com/pymander/a027523a7b9152660fac8e7bb4801c91&quot;&gt;from this link&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;App\Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Nette&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Aws\S3\S3Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;S3Uploader&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/** @var \Aws\S3\S3Client */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s3client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;cd&quot;&gt;/** @var string */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$bucket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$bucket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$accessKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$secretKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;putenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AWS_ACCESS_KEY_ID=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$accessKey&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;putenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AWS_SECRET_ACCESS_KEY=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$secretKey&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;\Aws\S3\S3Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;version&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;latest&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;region&apos;&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;us-west-2&apos;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bucket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$bucket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;cd&quot;&gt;/**
     * Upload a file to an S3 bucket
     *
     * @param string $key The key used for the uploaded object
     * @param string $file The filename to be uploaded
     * @param string $contentType The file&apos;s content type. This defaults to &quot;application/octet-stream&quot;
     *
     * @return string A URL to access the file publically.
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uploadPublic&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$contentType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;application/octet-stream&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;putObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;Bucket&apos;&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bucket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;Key&apos;&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;SourceFile&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;ContentType&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$contentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;ACL&apos;&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;public-read&apos;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getObjectUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bucket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getClient&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getBucket&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bucket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configuring-the-configurator&quot;&gt;Configuring the Configurator&lt;/h1&gt;

&lt;p&gt;Finally, the tricky part. You need to configure the &lt;a href=&quot;https://doc.nette.org/en/2.4/configuring&quot;&gt;Nette Configurator&lt;/a&gt; so it knows about your new service. Follow these directions.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Open &lt;strong&gt;app/config/config.neon&lt;/strong&gt; with your favorite text editor. At the end of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;services:&lt;/code&gt; section, add the following line.&lt;/p&gt;

    &lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;App&lt;/span&gt;\&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;\&lt;span class=&quot;n&quot;&gt;S3Uploader&lt;/span&gt;(%&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;bucket&lt;/span&gt;%, %&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;access_key&lt;/span&gt;%, %&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;secret_key&lt;/span&gt;%)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Open &lt;strong&gt;app/config/config.local.neon&lt;/strong&gt;. Find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters:&lt;/code&gt; section and add this block to it. Replace “ACCESS_KEY” with your AWS access key, and “SECRET_KEY” with your AWS secret key. Set “BUCKET_NAME” to the bucket you’ll be using for your uploads.&lt;/p&gt;

    &lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;s3client&lt;/span&gt;:
   &lt;span class=&quot;n&quot;&gt;access_key&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;ACCESS_KEY&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;secret_key&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;SECRET_KEY&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;bucket&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;BUCKET_NAME&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;using-s3uploader&quot;&gt;Using S3Uploader&lt;/h1&gt;

&lt;p&gt;Open up the presenter file that will be using the S3Uploader service. You just need to add a few new lines.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Near the top of the file where you’re loading libraries, add this line.&lt;/p&gt;

    &lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App\Model\S3Uploader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;You will need to change your constructor definition to include S3Uploader. Assuming you haven’t changed your constructor function too much, it will probably look like the following.&lt;/p&gt;

    &lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Nette&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;\Database\Context&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;S3Uploader&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Finally, you can call the S3Uploader with a simple method call.&lt;/p&gt;

    &lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$objectUrl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;uploadPublic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$objectKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$filePath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$contentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Good luck with S3Uploader. Please let me know in the comments how it is working for you. Note that this is an example and the finished product will probably be more sophisticated. However, this should get you started with using Amazon S3 in your Nette applications.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Alternate Ways to Call wp-cron</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2016/03/alternate-ways-to-call-wp-cron/" rel="alternate" type="text/html" title="Alternate Ways to Call wp-cron" />
        <updated>2016-03-05T17:09:28+00:00</updated>
        <id>https://arnesonium.com/2016/03/alternate-ways-to-call-wp-cron</id>
          <category term="best-practices" />
        
          <category term="php" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="web-performance" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2016/03/alternate-ways-to-call-wp-cron/">&lt;p&gt;WordPress includes a job scheduling system called wp-cron. The default method for scheduled jobs is for wp-cron to be checked on each page load, which has the potential to slow down your website while background jobs are run. Check out these other options that help maintain the user experience on your WordPress site while still running important tasks in the background.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;using-alternate_wp_cron&quot;&gt;Using ALTERNATE_WP_CRON&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALTERNATE_WP_CRON&lt;/code&gt; method uses a quick, nearly invisible redirect to direct an incoming user to a new request while the old one continues running, executing background jobs. This is an easy, effective method and it works really well if you don’t have access to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crontab&lt;/code&gt; on your hosting site. Even though this method adds some elements to the page URL, it’s only triggered when background jobs need to be run. To enable it, follow these instructions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Open your site’s &lt;strong&gt;wp-config.php&lt;/strong&gt; in your text editor.&lt;/li&gt;
  &lt;li&gt;After the lines containing your database credentials, add the following lines:
    &lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cd&quot;&gt;/** Use alternate WP_CRON method with redirects. */&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;ALTERNATE_WP_CRON&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;http://wordpress-hackers.1065353.n5.nabble.com/ALTERNATE-WP-CRON-Is-it-worth-it-td39843.html&quot; target=&quot;_blank&quot;&gt;Read more about the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALTERNATE_WP_CRON&lt;/code&gt; method here.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;using-crontab&quot;&gt;Using Crontab&lt;/h2&gt;

&lt;p&gt;If you have access to a shell on your web host and can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cron&lt;/code&gt; jobs, this method might be the best. It ensures that background jobs will get run, even when your website isn’t getting any visitors. It also runs background jobs without requiring a redirect or any additional delays that will be noticed by users. Here’s how you do it.&lt;/p&gt;

&lt;h3 id=&quot;add-a-crontab-entry&quot;&gt;Add a Crontab Entry&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crontab -e&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Add the following lines to the end of your crontab file:
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Call wp-cron regularly&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;/15 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; curl http://www.example.com/wp-cron.php &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make sure you replace “www.example.com” with your website’s hostname. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*/15&lt;/code&gt; specifies that &lt;strong&gt;wp-cron.php&lt;/strong&gt; will be called every 15 minutes. If you would like to change this, replace the 15 with a different number.&lt;/p&gt;

&lt;h3 id=&quot;disable-built-in-wp-cron&quot;&gt;Disable Built-in wp-cron&lt;/h3&gt;

&lt;p&gt;The next step is to disable the built-in call to wp-cron in WordPress.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Open your site’s &lt;strong&gt;wp-config.php&lt;/strong&gt; in your text editor.&lt;/li&gt;
  &lt;li&gt;After the lines containing your database credentials, add the following lines:
    &lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cd&quot;&gt;/** Disable built-in cron in favor of system crontab */&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;DISABLE_WP_CRON&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more details on this method, &lt;a href=&quot;https://easyengine.io/tutorials/wordpress/wp-cron-crontab/&quot; target=&quot;_blank&quot;&gt;check out this page on EasyEngine&lt;/a&gt;.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>OpenPGP for WordPress Now Supports Contact Form 7</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2016/01/openpgp-for-wordpress-now-supports-contact-form-7/" rel="alternate" type="text/html" title="OpenPGP for WordPress Now Supports Contact Form 7" />
        <updated>2016-01-20T16:54:43+00:00</updated>
        <id>https://arnesonium.com/2016/01/openpgp-for-wordpress-now-supports-contact-form-7</id>
          <category term="announcement" />
        
          <category term="cryptography" />
        
          <category term="encryption" />
        
          <category term="javascript" />
        
          <category term="openpgp" />
        
          <category term="php" />
        
          <category term="plugin" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2016/01/openpgp-for-wordpress-now-supports-contact-form-7/">&lt;p&gt;&lt;a href=&quot;https://arnesonium.com/wordpress-openpgp/&quot;&gt;OpenPGP Form Encryption for WordPress&lt;/a&gt; now supports &lt;a href=&quot;http://contactform7.com/&quot; target=&quot;_blank&quot;&gt;Contact Form 7&lt;/a&gt;. You can download version 1.4.0 at the &lt;a href=&quot;https://wordpress.org/plugins/openpgp-form-encryption/&quot; target=&quot;_blank&quot;&gt;WordPress plugin site&lt;/a&gt; and start using a safer contact form on your website today!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Pono Rez WordPress Plugin</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2016/01/pono-rez-wordpress-plugin/" rel="alternate" type="text/html" title="Pono Rez WordPress Plugin" />
        <updated>2016-01-18T17:52:32+00:00</updated>
        <id>https://arnesonium.com/2016/01/pono-rez-wordpress-plugin</id>
          <category term="javascript" />
        
          <category term="php" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2016/01/pono-rez-wordpress-plugin/">&lt;p&gt;Together with &lt;a href=&quot;http://www.commercecollective.com/&quot; target=&quot;_blank&quot;&gt;Commerce Collective&lt;/a&gt;, ((I started working with them last year, &lt;a href=&quot;https://arnesonium.com/2015/05/now-working-with-commercecollective/&quot;&gt;remember&lt;/a&gt;?)) we have built a WordPress plugin to allow &lt;a href=&quot;http://www.a3h.org/&quot; target=&quot;_blank&quot;&gt;Activities &amp;amp; Attractions Association of Hawaii&lt;/a&gt; (A3H) to quickly and easily integrate activity bookings and sales into their WordPress websites.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;We still have more features to add to the plugin, but it’s a solid start that will save A3H members a lot of time. It is written in PHP ((Like all WordPress plugins, of course.)) and JavaScript, and uses the Pono Rez SOAP interface to integrate activity data into a WordPress page.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://wordpress.org/plugins/a3h-pono-rez-activities-and-booking/&quot; target=&quot;_blank&quot;&gt;Check out the plugin page here!&lt;/a&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>CenturyLink AppFog Tutorial</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2016/01/centurylink-appfog-tutorial/" rel="alternate" type="text/html" title="CenturyLink AppFog Tutorial" />
        <updated>2016-01-15T17:26:41+00:00</updated>
        <id>https://arnesonium.com/2016/01/centurylink-appfog-tutorial</id>
          <category term="appfog" />
        
          <category term="centurylink-cloud" />
        
          <category term="cloud-computing" />
        
          <category term="cloudfoundry" />
        
          <category term="javascript" />
        
          <category term="node-js" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="writing" />
        <content type="html" xml:base="https://arnesonium.com/2016/01/centurylink-appfog-tutorial/">&lt;p&gt;Recently I wrote a tutorial with &lt;a href=&quot;http://wordlions.com/&quot; target=&quot;_blank&quot;&gt;Word Lions&lt;/a&gt; for &lt;a href=&quot;http://ctl.io/&quot; target=&quot;_blank&quot;&gt;CenturyLink Cloud&lt;/a&gt; that teaches how to build and deploy a Node.js application to CenturyLink AppFog. The tutorial and application were really fun to build and write. It was my first Node.js project, and my first experience with CloudFoundry. The tutorial uses the following CenturyLink Cloud products:
&lt;!--more--&gt;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/appfog/&quot;&gt;AppFog&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/orchestrate/&quot;&gt;Orchestrate&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/object-storage/&quot;&gt;Object Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AppFog is CenturyLink Cloud’s CloudFoundry system. It is really powerful, and it appears to be more flexible than &lt;a href=&quot;https://arnesonium.com/tag/google-cloud/&quot;&gt;Google App Engine&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Read the Tutorial&lt;/h2&gt;

&lt;p&gt;The tutorial walks you through building a document storage system with a built-in PDF reader and comment storage. It also includes user authentication and some other neat Node.js tricks. You can follow the tutorial from the following links, which will include all of the information needed to get you up and running on AppFog with Node.js. Enjoy!&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/developers/blog/post/deploy-app-user-login&quot;&gt;Deploy an App With User Login&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/developers/blog/post/appfog-object-storage&quot;&gt;Using CenturyLink Cloud for Object Storage&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/developers/blog/post/search-document-metadata&quot;&gt;Add Search Capabilities with Orchestrate&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.ctl.io/developers/blog/post/document-review-comment&quot;&gt;Building a PDF Viewer and Comment System&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content>
      </entry>
    
      <entry>
        
        <title>Send Secure Email with Entrypt.to Service</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/06/send-secure-email-with-entrypt-to-service/" rel="alternate" type="text/html" title="Send Secure Email with Entrypt.to Service" />
        <updated>2015-06-08T15:48:03+00:00</updated>
        <id>https://arnesonium.com/2015/06/send-secure-email-with-entrypt-to-service</id>
          <category term="cryptography" />
        
          <category term="email" />
        
          <category term="openpgp" />
        
          <category term="programming" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/06/send-secure-email-with-entrypt-to-service/">&lt;p&gt;While my &lt;a href=&quot;/wordpress-openpgp/&quot;&gt;OpenPGP plugin for WordPress&lt;/a&gt; might be very helpful, the &lt;a href=&quot;https://encrypt.to/&quot; target=&quot;_blank&quot;&gt;Encrypt.to service&lt;/a&gt; allows you to quickly send encrypted email with just one click. It looks powerful.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href=&quot;https://encrypt.to/earneson@arnesonium.com&quot; target=&quot;_blank&quot;&gt;click here to send me encrypted email&lt;/a&gt; or visit the &lt;a href=&quot;https://github.com/encrypt-to/encrypt.to&quot; target=&quot;_blank&quot;&gt;source code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://encrypt.to/earneson@arnesonium.com&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://arnesonium.com/wp-content/uploads/2015/05/Screenshot-from-2015-05-29-125540.png&quot; alt=&quot;Screenshot from 2015-05-29 12:55:40&quot; width=&quot;489&quot; height=&quot;545&quot; class=&quot;aligncenter size-full wp-image-441&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>A Look Back on the History of Cryptography</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/06/a-look-back-on-the-history-of-cryptography/" rel="alternate" type="text/html" title="A Look Back on the History of Cryptography" />
        <updated>2015-06-01T15:30:02+00:00</updated>
        <id>https://arnesonium.com/2015/06/a-look-back-on-the-history-of-cryptography</id>
          <category term="cryptography" />
        
          <category term="history" />
        
          <category term="history-of-cryptography" />
        
          <category term="programming" />
        
          <category term="public-speaking" />
        
          <category term="pugs" />
        
          <category term="teaching" />
        <content type="html" xml:base="https://arnesonium.com/2015/06/a-look-back-on-the-history-of-cryptography/">&lt;p&gt;In May, I taught a &lt;a href=&quot;https://arnesonium.com/2015/04/the-history-of-cryptography-at-pugs/&quot;&gt;class on the History of Cryptography&lt;/a&gt; at &lt;a href=&quot;http://www.pugspdx.com/&quot; target=&quot;_blank&quot;&gt;Portland Underground Grad School&lt;/a&gt;. I’m extremely grateful to PUGS for asking me to teach, because I’d never done it before. It was a great experience. My students were intelligent and the discussion was good. I learned quite a few things in the process.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;Teaching Isn&apos;t the Same as Lecturing&lt;/h2&gt;
&lt;p&gt;I have a lot of experience with public speaking. I spent time in &lt;a href=&quot;http://www.toastmasters.org/&quot; target=&quot;_blank&quot;&gt;Toastmasters International&lt;/a&gt; and have given many lectures. In fact, here’s a video of me giving a lecture on the art of memory back in 2013. (( I embedded this video just to exploit a neat WordPress feature. ))&lt;/p&gt;

&lt;p&gt;https://www.youtube.com/watch?v=-WpxbPHkq4A&lt;/p&gt;

&lt;p&gt;I knew that teaching would be different, but I didn’t know what to expect. Luckily, Douglas Tsoi, &lt;a href=&quot;http://www.portlandmonthlymag.com/arts-and-entertainment/culturephile-portland-arts/articles/get-smarter-for-cheap-at-portland-s-underground-grad-school-march-2015&quot; target=&quot;_blank&quot;&gt;the mastermind behind PUGS&lt;/a&gt;, helped me design my four-week curriculum and gave me a lot of advice. The two main differences that I noticed are that, first, teaching is a lot more like a conversation, and second, you continue following up week after week. Conversation and continuity!&lt;/p&gt;

&lt;p&gt;Douglas’s help was invaluable. He’s the reason that PUGS is able to bring in experts without teaching experience while providing a rich educational environment.&lt;/p&gt;
&lt;h2&gt;It&apos;s Hard to Boil Down Experience&lt;/h2&gt;
&lt;blockquote&gt;&quot;There is so much to learn! I enjoyed being able to ask questions at will and go deeper into the subject with a knowledgeable instructor.&quot; -- An anonymous student&lt;/blockquote&gt;
&lt;p&gt;A PUGS class lasts four weeks, and there’s only one class per week. That’s not a lot of time to cover a complicated subject. Going into the class, I just didn’t realize how difficult it is to cram decades of experience into just a few weeks. In our third class, while discussing &lt;a href=&quot;https://www.philzimmermann.com/&quot; target=&quot;_blank&quot;&gt;Phil Zimmerman&lt;/a&gt; and the &lt;a href=&quot;http://openpgp.vie-privee.org/history.htm&quot; target=&quot;_blank&quot;&gt;creation of PGP&lt;/a&gt;, I realized that I’d been learning about cryptography for &lt;strong&gt;over 20 years.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The learning curve in cryptography is &lt;strong&gt;staggering.&lt;/strong&gt; I didn’t realize that going into it, but it’s really difficult to introduce things like the &lt;a href=&quot;https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange&quot; target=&quot;_blank&quot;&gt;Diffie-Hellman key exchange protocol&lt;/a&gt; to people who had just learned to do an alphabetic substitution cipher for the first time. All of my students were very intelligent people, but none of them were computer scientists or mathematicians. My curriculum is going to take some adjustment.&lt;/p&gt;
&lt;h2&gt;Teaching is Fun&lt;/h2&gt;
&lt;p&gt;Through this class I met many interesting people. While preparing for the class, I had to brush up on a lot of dusty knowledge. In the process I learned a lot. The entire thing was mentally engaging, socially stimulating, and a blast. I hope that PUGS will have me again, because this class is only going to get better.&lt;/p&gt;

&lt;p&gt;If you enjoy learning, you owe it to yourself to take a class at the Portland Underground Grad School. &lt;a href=&quot;http://www.pugspdx.com/&quot; target=&quot;_blank&quot;&gt;Go check them out!&lt;/a&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>New Release of OpenPGP for WordPress</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/05/new-release-of-openpgp-for-wordpress/" rel="alternate" type="text/html" title="New Release of OpenPGP for WordPress" />
        <updated>2015-05-13T18:16:07+00:00</updated>
        <id>https://arnesonium.com/2015/05/new-release-of-openpgp-for-wordpress</id>
          <category term="cryptography" />
        
          <category term="openpgp" />
        
          <category term="plugin" />
        
          <category term="programming" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2015/05/new-release-of-openpgp-for-wordpress/">&lt;p&gt;&lt;span data-icon=&quot;&amp;#xe088;&quot; style=&quot;float:left;font-size:xx-large;padding-right:0.1em&quot;&gt;&lt;/span&gt;Version 1.3.0 of the &lt;a href=&quot;http://arnesonium.com/wordpress-openpgp/&quot;&gt;OpenPGP Form Encryption for WordPress&lt;/a&gt; plugin is now available. It’s important to upgrade. It includes the following changes.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Updates OpenPGP.js to version 1.0.1&lt;/li&gt;
    &lt;li&gt;Tests the plugin against WordPress 4.2.2&lt;/li&gt;
    &lt;li&gt;Ensures that the browser can support OpenPGP.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few new features planned for this plugin. Expect a major version release in the next few months.&lt;/p&gt;

&lt;p&gt;Check out the plugin page on the &lt;a href=&quot;https://wordpress.org/plugins/openpgp-form-encryption/&quot; target=&quot;_blank&quot;&gt;WordPress Plugin Repository&lt;/a&gt;.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Please Use Version Control</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/04/please-use-version-control/" rel="alternate" type="text/html" title="Please Use Version Control" />
        <updated>2015-04-09T03:07:44+00:00</updated>
        <id>https://arnesonium.com/2015/04/please-use-version-control</id>
          <category term="git" />
        
          <category term="github" />
        
          <category term="programming" />
        
          <category term="stack-overflow" />
        
          <category term="version-control" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/04/please-use-version-control/">&lt;p&gt;Stack Overflow released their &lt;a href=&quot;http://stackoverflow.com/research/developer-survey-2015&quot; title=&quot;Stack Overflow Developer Survey 2015&quot; target=&quot;_blank&quot;&gt;2015 Developer Survey&lt;/a&gt; this week, and it has some interesting results. There are plenty of articles being written about their findings, so I’m only going to focus on one of them: version control.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;9.3% of Respondents Don&apos;t Use Version Control&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://arnesonium.com/wp-content/uploads/2015/04/Screenshot-from-2015-04-08-192457.png&quot; alt=&quot;Almost 10% of programmers aren&apos;t using version control.&quot; width=&quot;300&quot; height=&quot;188&quot; class=&quot;size-medium wp-image-345&quot; /&gt;&lt;/p&gt;

&lt;p&gt;StackOverflow says that &lt;a href=&quot;http://stackoverflow.com/research/developer-survey-2015#tech-sourcecontrol&quot; title=&quot;Stack Overflow Developer Survey 2015&quot; target=&quot;_blank&quot;&gt;almost 10% of developers still aren’t using version control&lt;/a&gt;. This is terrible. If you happen to be one of the developers who hasn’t adopted version control yet, &lt;b&gt;make it your next priority!&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Version control, also known as source control or revision control, is vital to best programming practices. It provides an incremental backup along with comments and notes on changes that have been made. It provides a view of changes and all kinds of handy features, such as handling conflicts between changes, release tagging, code branches, and more. If you aren’t sure what version control is, check out Ilya Olevsky’s post, &lt;a href=&quot;http://www.codeservedcold.com/version-control-importance/&quot; title=&quot;Why Version Control is Critical to Your Success&quot; target=&quot;_blank&quot;&gt;“Why Version Control is Critical to Your Success,”&lt;/a&gt; and then come back here.&lt;/p&gt;

&lt;h2&gt;Essential to Collaboration and Continuity&lt;/h2&gt;

&lt;p&gt;If you are looking to hire a freelance developer, make sure you hire one that uses version control. It is essential to maintaining a healthy history of code releases, project updates, and bug fixes. What if you only need to use your freelancer every once in a while? What if you decide to add more developers, or change developers all together? Without version control, this becomes a nightmare.&lt;/p&gt;

&lt;p&gt;A client recently brought me a project that had been built by another developer a couple of years ago. They wanted to move their web application from one host to another. However, there was a lot that needed to be cleaned up before the move could happen, including some outdated PHP code and odd database settings. In the project’s main directory, there was a mess of old, unused source code files. Just the &lt;code&gt;index.php&lt;/code&gt; file had multiple versions:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;index2.php&lt;/li&gt;
	&lt;li&gt;index3.php&lt;/li&gt;
	&lt;li&gt;indexold.php&lt;/li&gt;
	&lt;li&gt;index.php_old&lt;/li&gt;
	&lt;li&gt;index.php_bak&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all, there were 598 unused files that were unnecessary backups of old, broken code. This type of mess is easily avoided with version control. Please stay sane, keep your customers happy, and your source code easy to navigate. Use version control.&lt;/p&gt;

&lt;h2&gt;Getting Started with Version Control&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://arnesonium.com/wp-content/uploads/2015/04/git-logo.png&quot; alt=&quot;git-logo&quot; width=&quot;220&quot; height=&quot;92&quot; class=&quot;alignright size-full wp-image-347&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you’ve decided to make the right move and start using version control, you will see that there are many to choose from. However, if you’re just going to learn one, you should start with &lt;b&gt;Git&lt;/b&gt;. As you can see from the survey, it is the most widely used. The best place to start is probably in the free e-book offered by the Git development team. &lt;a href=&quot;http://git-scm.com/book/en/v1/Getting-Started&quot; title=&quot;Git: Getting Started&quot; target=&quot;_blank&quot;&gt;Click here to get started.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;If You&apos;re Doing It, Thank You&lt;/h2&gt;

&lt;p&gt;The first time I encountered a team that wasn’t using version control, I was shocked. The second time, I sighed in exasperation. Now, I am thankful that over 90% of developers are using it, and I look forward to the day that every project I join comes with a &lt;code&gt;git log&lt;/code&gt; command. If you are using version control, I hope you spread the word and make sure that your fellow programmers are doing it, too. Save the rest of us some pain!&lt;/p&gt;

&lt;p&gt;As a bonus, here’s my favorite &lt;code&gt;git log&lt;/code&gt; command. Add it to your aliases.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git log &lt;span class=&quot;nt&quot;&gt;--oneline&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--graph&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--decorate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;The featured image for this post is a pile of logs, to remind you that logs are important, and a vital part of version control.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Link Rodeo: Go Package Management and Boring Technology</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/04/link-rodeo-go-package-management-and-boring-technology/" rel="alternate" type="text/html" title="Link Rodeo: Go Package Management and Boring Technology" />
        <updated>2015-04-06T15:47:00+00:00</updated>
        <id>https://arnesonium.com/2015/04/link-rodeo-go-package-management-and-boring-technology</id>
          <category term="best-practices" />
        
          <category term="golang" />
        
          <category term="javascript" />
        
          <category term="management" />
        
          <category term="node-js" />
        
          <category term="ocaml" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2015/04/link-rodeo-go-package-management-and-boring-technology/">&lt;p&gt;Here are a number of interesting topics for you to think about this week.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I’ve been learning the &lt;a href=&quot;http://arnesonium.com/tag/golang/&quot; title=&quot;Go language&quot;&gt;Go programming language&lt;/a&gt; recently, and in the process I’ve been having conversations about it with friends and colleagues. Go has a unique package management system that has already caused me a number of headaches. The recommended method for taking care of package dependencies is lacking, at best. Over at Nerdbucket, my buddy Nerdmaster has written &lt;a href=&quot;http://blog.nerdbucket.com/go-dependency-freezing/article&quot; title=&quot;Go Dependency Freezing at Nerdbucket&quot; target=&quot;_blank&quot;&gt;a thoughtful piece about it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While I’m talking about new technology, I’d also like to contradict myself by agreeing with Dan McKinley’s great piece, &lt;a href=&quot;http://mcfunley.com/choose-boring-technology&quot; title=&quot;Choose Boring Technology by Dan McKinley&quot; target=&quot;_blank&quot;&gt;“Choose Boring Technology.”&lt;/a&gt; He argues that a project should be careful about adopting lots of new tools and technologies. It reminds me of a time recently when I was looking for a Node.js programmer, and one of the replies I got back was, “For us, Node.js is glue. Its ecosystem is still too young to support anything long-term. Libraries and packages move too fast to build a product that will need actual maintenance.” I’ve had the same feeling about many technologies I’ve wanted to try, such as &lt;a href=&quot;http://ocsigen.org/&quot; title=&quot;Ocsigen&quot; target=&quot;_blank&quot;&gt;Ocsigen for OCaml&lt;/a&gt;, which has a build system and API that is always several steps ahead of its documentation.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;This post’s featured photo is courtesy of Flickr user &lt;a href=&quot;https://www.flickr.com/photos/municipiopinas/8161449094/&quot; target=&quot;_blank&quot;&gt;MunicipioPinas&lt;/a&gt;.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Create a Document From Twitter with TweetBook</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/04/create-a-document-from-twitter-with-tweetbook/" rel="alternate" type="text/html" title="Create a Document From Twitter with TweetBook" />
        <updated>2015-04-01T17:48:56+00:00</updated>
        <id>https://arnesonium.com/2015/04/create-a-document-from-twitter-with-tweetbook</id>
          <category term="golang" />
        
          <category term="google-cloud" />
        
          <category term="programming" />
        
          <category term="publishing" />
        
          <category term="tweetbook" />
        
          <category term="twitter" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/04/create-a-document-from-twitter-with-tweetbook/">&lt;p&gt;I just released &lt;a href=&quot;http://tweetbook.arnesonium.com/&quot; title=&quot;TweetBook&quot; target=&quot;_blank&quot;&gt;TweetBook&lt;/a&gt;, a web application to transform a Twitter stream into a simple document that can easily be turned into a photo album.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;A client came to me complaining that there was no available solution to export a Twitter feed as a document filled with images. There are various other Twitter-to-document converters out there, but they all focus on the text. The client asked me to build a tool to fill this void.&lt;/p&gt;

&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;Since I’ve been working with Google App Engine a lot lately, I used Go to write a tool that retrieves Tweets from a search or timeline. It provides a number of formatting options, and then creates a simple document suitable for exporting into an HTML or PDF file.&lt;/p&gt;

&lt;h2&gt;Try It Out!&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;As of 2022, this application is seven years old and probably doesn’t work anymore.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The client told me to do whatever I wanted with the code, so I’m making it available for use! &lt;strong&gt;&lt;a href=&quot;http://tweetbook.arnesonium.com/&quot; title=&quot;TweetBook&quot; target=&quot;_blank&quot;&gt;Click here to try TweetBook!&lt;/a&gt;&lt;/strong&gt; If you find it useful, please consider funding further development by contributing a small amount with this button:&lt;/p&gt;

&lt;form action=&quot;https://www.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot; target=&quot;_top&quot;&gt;
 &lt;button type=&quot;submit&quot; class=&quot;btn&quot;&gt;Contribute $1.99 &amp;raquo;&lt;/button&gt;&lt;input type=&quot;hidden&quot; name=&quot;cmd&quot; value=&quot;_s-xclick&quot; /&gt;&lt;input type=&quot;hidden&quot; name=&quot;hosted_button_id&quot; value=&quot;3PNSJJHRF9XWA&quot; /&gt;
 &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://www.paypalobjects.com/en_US/i/scr/pixel.gif&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;
&lt;/form&gt;

&lt;h2&gt;Do You Have a Suggestion? A Bug Report?&lt;/h2&gt;
&lt;p&gt;If you have additional ideas for TweetBook, please visit my &lt;a href=&quot;http://arnesonium.com/contact/&quot; title=&quot;Contact&quot;&gt;Contact page&lt;/a&gt;. I’m eager to hear your feedback and get suggestions and bug reports!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Don&apos;t Modify the Clipboard with JavaScript</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/03/dont-modify-the-clipboard-with-javascript/" rel="alternate" type="text/html" title="Don't Modify the Clipboard with JavaScript" />
        <updated>2015-03-02T16:42:53+00:00</updated>
        <id>https://arnesonium.com/2015/03/dont-modify-the-clipboard-with-javascript</id>
          <category term="best-practices" />
        
          <category term="javascript" />
        
          <category term="programming" />
        
          <category term="web-design" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/03/dont-modify-the-clipboard-with-javascript/">&lt;p&gt;Recently, I was reading an article about a newly published book that I’m interested in. However, the article didn’t include a link to the book, so I copied the title by highlighting it with the mouse and hitting ‘Ctrl-C’, and opened a new browser tab to do a search. However, upon pasting, I saw the book title along with an annoying addition: “To read more, visit our website at [redacted].”&lt;/p&gt;

&lt;p&gt;This sort of website behavior is not okay.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://arnesonium.com/wp-content/uploads/2015/02/3429454121_9a93f53855_o-300x200.jpg#right&quot; alt=&quot;3429454121_9a93f53855_o&quot; width=&quot;300&quot; height=&quot;200&quot; class=&quot;alignright size-medium wp-image-309&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ve seen the behavior on a number of websites, and it is among my least favorite trends in web development. The user is probably using his clipboard for one of two reasons. First, the website has a UX problem, and it has neglected to link to something important. Second, the user needs the text either for a quote, or to look up an unrelated term. For instance, this sentence has the word “bucolic” in it, and that’s an uncommon word that you might want to look up.&lt;/p&gt;

&lt;p&gt;But you can’t easily, because I’ve included JavaScript on this page that modifies your copy buffer. Do you see how annoying that is? Please don’t go mucking about in your users’ copy buffers.&lt;/p&gt;

&lt;p&gt;If you want to see what happens when you try to copy and paste on this page, highlight some text on the page and hit ‘Ctrl-C’ (or ‘Cmd-C’ for OS X users). Then go to the handy text area below and paste with ‘Ctrl-V’.&lt;/p&gt;

&lt;textarea style=&quot;width:100%&quot;&gt;&lt;/textarea&gt;

&lt;p&gt;That’s really obnoxious, isn’t it?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was updated in 2022 to use Jekyll to load custom JavaScript instead of a custom WordPress plugin.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;The image for this post comes from &lt;a href=&quot;https://www.flickr.com/photos/shimelle/&quot; target=&quot;_blank&quot;&gt;Flickr user Shimelle Laine&lt;/a&gt;.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Pansophie Online Color Test</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/pansophie-online-color-test/" rel="alternate" type="text/html" title="Pansophie Online Color Test" />
        <updated>2015-02-23T16:46:52+00:00</updated>
        <id>https://arnesonium.com/2015/02/pansophie-online-color-test</id>
          <category term="javascript" />
        
          <category term="jquery" />
        
          <category term="php" />
        
          <category term="programming" />
        
          <category term="web-design" />
        
          <category term="web-development" />
        
          <category term="zend-framework" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/pansophie-online-color-test/">&lt;p&gt;&lt;a href=&quot;http://eyesandedge.com/pansophie/&quot; target=&quot;_blank&quot;&gt;Pansophie Personality and Color&lt;/a&gt; is focused on mapping personalities to colors. Alexandra Hall wanted an online testing platform with flexible questions, testing mechanisms, and report generation. I built a full-featured web application to meet Pansophie PC’s requirements. This was one of my early Zend Framework projects, but it ended up with some neat features.
&lt;!--more--&gt;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;A private administrative interface&lt;/li&gt;
	&lt;li&gt;Seamless jQuery-backed test interface with few pageloads&lt;/li&gt;
	&lt;li&gt;Custom PDF reports, generated on the fly&lt;/li&gt;
	&lt;li&gt;A customer database with contact information&lt;/li&gt;
	&lt;li&gt;API endpoints for test generation&lt;/li&gt;
	&lt;li&gt;Integration with 3rd party e-commerce system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pansopie PC isn’t currently doing business.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Prime Number Service on Google App Engine</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/prime-number-google-app-engine/" rel="alternate" type="text/html" title="Prime Number Service on Google App Engine" />
        <updated>2015-02-20T22:37:41+00:00</updated>
        <id>https://arnesonium.com/2015/02/prime-number-google-app-engine</id>
          <category term="cloud" />
        
          <category term="github" />
        
          <category term="golang" />
        
          <category term="google-cloud" />
        
          <category term="php" />
        
          <category term="plugin" />
        
          <category term="prime-numbers" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/prime-number-google-app-engine/">&lt;p&gt;As I &lt;a href=&quot;http://arnesonium.com/2015/02/random-link-rodeo/&quot; title=&quot;Random Link Rodeo&quot;&gt;mentioned earlier this week&lt;/a&gt;, I’ve decided to learn the &lt;a href=&quot;http://golang.org/&quot; target=&quot;_blank&quot;&gt;Go programming language&lt;/a&gt;. I’ve also been very interested in Google App Engine, which lets you deploy applications to the cloud from a development sandbox. It’s like magic for web and mobile applications!
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Since I’m so fond of prime numbers, I thought I’d build a web service for calculating them. It does some other fun stuff, too, like figuring out if a number is happy. It also caches primes in the Google Cloud Datastore with some minimal statistics. If you’d like to see the source code for the prime number service, it’s &lt;a href=&quot;https://github.com/pymander/prime-json-service&quot; target=&quot;_blank&quot;&gt;available on GitHub&lt;/a&gt;.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The next thing I did was write the simplest of all WordPress plugins to query the service and return the latest prime number in the sequence. This all happens in a post using the [[nextprime]] shortcode. ((Including this information has the side-effect of revealing how much traffic this page gets.))&lt;/p&gt;

&lt;h1&gt;[nextprime]&lt;/h1&gt;

&lt;p&gt;You can also &lt;a href=&quot;http://sigma-crow-364.appspot.com/&quot; title=&quot;Prime Number Web App&quot; target=&quot;_blank&quot;&gt;visit the app itself&lt;/a&gt; and read about querying the service to get prime numbers for your own web page!&lt;/p&gt;

&lt;p&gt;Learning Go and writing for the Google App Engine has been really fun. I’m ready for a new challenge! If you have a web application in mind, &lt;a href=&quot;http://arnesonium.com/contact/&quot; title=&quot;Contact&quot;&gt;contact me and let’s figure out how to build it&lt;/a&gt;!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>How to Enable XPath in Internet Explorer</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/how-to-enable-xpath-in-internet-explorer/" rel="alternate" type="text/html" title="How to Enable XPath in Internet Explorer" />
        <updated>2015-02-12T17:13:32+00:00</updated>
        <id>https://arnesonium.com/2015/02/how-to-enable-xpath-in-internet-explorer</id>
          <category term="epub" />
        
          <category term="internet-explorer" />
        
          <category term="javascript" />
        
          <category term="programming" />
        
          <category term="publishing" />
        
          <category term="web-development" />
        
          <category term="windows" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/how-to-enable-xpath-in-internet-explorer/">&lt;p&gt;Yesterday, I shared a little bit about using a virtual machine to &lt;a href=&quot;http://arnesonium.com/2015/02/test-internet-explorer-without-booting-windows/&quot; title=&quot;How to Test Your Frontend Against Internet Explorer Without Booting Windows&quot;&gt;test frontend code under Internet Explorer (IE)&lt;/a&gt;. My goal was to use &lt;a href=&quot;https://code.google.com/p/wicked-good-xpath/&quot; title=&quot;Wicked Good XPath&quot; target=&quot;_blank&quot;&gt;Wicked Good XPath&lt;/a&gt; to add the proper XPath features to IE so that EPUB.js would work correctly, thus making the &lt;a href=&quot;http://arnesonium.com/2015/01/philalethes-e-bulletin-online-reader/&quot; title=&quot;Philalethes E-Bulletin Online Reader&quot;&gt;&lt;em&gt;Philalethes E-Bulletin&lt;/em&gt; Online Reader&lt;/a&gt; work on all major browsers.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Well, I’d been thinking about this problem for a while, but had delayed working on it because I just didn’t want to fiddle with IE. While I’d been thinking about it, the &lt;a href=&quot;https://github.com/futurepress/epub.js/commit/f2fa7497939e5876ff6676cf8de34d7284498495#diff-04c6e90faac2675aa89e2176d2eec7d8&quot; target=&quot;_blank&quot;&gt;EPUB.js instructions were updated&lt;/a&gt; with IE-specific steps. I didn’t have to look far.&lt;/p&gt;

&lt;p&gt;After loading &lt;code&gt;wgxpath.install.js&lt;/code&gt; in the header, I just had to add this bit of JavaScript before anything important happened:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
// Internet Explorer workaround.
if (!window.XPathResult) {
    EPUBJS.Hooks.register(&quot;beforeChapterDisplay&quot;).wgxpath = function(callback, renderer){
       wgxpath.install(renderer.render.window);

       if (callback) callback();
    };
    wgxpath.install(window);
}
&lt;/pre&gt;

&lt;p&gt;You can see on line 2 that I test for &lt;code&gt;window.XPathResult&lt;/code&gt; instead of looking for a user agent or anything like that. That’s because it’s not really IE I’m interested in detecting. I want to find out if XPath is both available and somewhat standard. User agents are unreliable. &lt;a href=&quot;http://learn.jquery.com/code-organization/feature-browser-detection/&quot; target=&quot;_blank&quot;&gt;Always test for feature availability instead!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://arnesonium.com/wp-content/uploads/2015/02/Screenshot-from-2015-02-11-133823.png&quot; alt=&quot;Recent web browser usage&quot; width=&quot;350&quot; height=&quot;130&quot; class=&quot;alignright size-full wp-image-279&quot; /&gt;The results are good enough for now: the Online Reader works in IE, but it’s not perfect. The cover image doesn’t load full-size and fonts don’t seem to be loading correctly. IE users account for only 10% of the traffic on the website, so obviously I need to work on the EPUB.js cross-browser support. For now, though, it works. And it looks great on Chrome, Safari, and Firefox.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>How to Test Your Frontend Against Internet Explorer Without Booting Windows</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/test-internet-explorer-without-booting-windows/" rel="alternate" type="text/html" title="How to Test Your Frontend Against Internet Explorer Without Booting Windows" />
        <updated>2015-02-11T19:15:26+00:00</updated>
        <id>https://arnesonium.com/2015/02/test-internet-explorer-without-booting-windows</id>
          <category term="debugging" />
        
          <category term="epub" />
        
          <category term="internet-explorer" />
        
          <category term="javascript" />
        
          <category term="programming" />
        
          <category term="testing" />
        
          <category term="web-development" />
        
          <category term="windows" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/test-internet-explorer-without-booting-windows/">&lt;p&gt;Internet Explorer (IE) has been frustrating me. I want to use stronger words than that, but it would be unprofessional.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I recently launched the &lt;a href=&quot;http://arnesonium.com/2015/01/philalethes-e-bulletin-online-reader/&quot; title=&quot;Philalethes E-Bulletin Online Reader&quot;&gt;&lt;em&gt;Philalethes E-Bulletin&lt;/em&gt; Online Reader&lt;/a&gt;, which uses EPUB.js and an implementation of XPath that, for some strange reason, isn’t available in IE. I found a few solutions which would work, but all of them require testing in IE. Of course.&lt;/p&gt;

&lt;p&gt;This seems like it wouldn’t be a problem, except that I run Linux all the time. All of my work happens on the Linux side of things, so booting into Windows just to run IE for one tiny bug fix is an inconvenience and a chore.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;A friend of mine pointed me to &lt;a href=&quot;https://www.modern.ie/&quot; title=&quot;modern.IE: Virtual Machines for running Internet Explorer&quot; target=&quot;_blank&quot;&gt;modern.IE&lt;/a&gt;. Microsoft has graciously released virtual machines usable under MacOS and Linux for running IE and testing. Be warned, however, that the license only lasts 90 days.&lt;/p&gt;

&lt;p&gt;I downloaded the 3.5GB virtual machine image and loaded it up in VirtualBox. This might be unusual, but I don’t do a lot of work with virtual machines on my development box. I was immediately greeted with this:
[caption id=”attachment_269” align=”aligncenter” width=”530”]&lt;img src=&quot;http://arnesonium.com/wp-content/uploads/2015/02/Screenshot-from-2015-02-11-094245.png&quot; alt=&quot;Don&amp;#039;t worry, the loading time was a lie. It only took 5 minutes.&quot; width=&quot;530&quot; height=&quot;423&quot; class=&quot;size-full wp-image-269&quot; /&gt; Don’t worry, the loading time was a lie. It only took 5 minutes.[/caption]&lt;/p&gt;

&lt;p&gt;This solution is not the best for my setup. My computer is getting long in the tooth, so VirtualBox runs neither quickly nor smoothly. However, in this situation, I only needed to test a few lines of code, so it worked.&lt;/p&gt;

&lt;p&gt;In my next blog post, which should be coming out shortly, I’ll talk about how I got the &lt;em&gt;Philalethes E-Bulletin&lt;/em&gt; Online Reader working for IE.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>When to Develop Apps From Scratch</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/when-to-develop-apps-from-scratch/" rel="alternate" type="text/html" title="When to Develop Apps From Scratch" />
        <updated>2015-02-03T20:56:10+00:00</updated>
        <id>https://arnesonium.com/2015/02/when-to-develop-apps-from-scratch</id>
          <category term="management" />
        
          <category term="optimization" />
        
          <category term="programming" />
        
          <category term="publishing" />
        
          <category term="web-design" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/when-to-develop-apps-from-scratch/">&lt;p&gt;I haven’t had time to write anything interesting for the blog this week, so instead check out Sebastian Green’s article, &lt;a href=&quot;http://www.developerdrive.com/2015/02/a-transparent-box-the-case-for-developing-from-scratch/&quot; target=&quot;_blank&quot;&gt;“A transparent box: the case for developing from scratch,”&lt;/a&gt; which has been published over at Developer Drive.&lt;/p&gt;

&lt;p&gt;Mr Green makes some great arguments for developing from scratch. Good software takes good planning, no matter what.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Integrating Cedexis Radar with WordPress Sites</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/01/integrating-cedexis-radar-with-wordpress-sites/" rel="alternate" type="text/html" title="Integrating Cedexis Radar with WordPress Sites" />
        <updated>2015-01-26T20:00:52+00:00</updated>
        <id>https://arnesonium.com/2015/01/integrating-cedexis-radar-with-wordpress-sites</id>
          <category term="cedexis" />
        
          <category term="performance" />
        
          <category term="php" />
        
          <category term="plugin" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="web-performance" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2015/01/integrating-cedexis-radar-with-wordpress-sites/">&lt;p&gt;&lt;a href=&quot;http://www.cedexis.com/radar/&quot; target=&quot;_blank&quot;&gt;Cedexis Radar&lt;/a&gt; is a real user monitoring (RUM) system that collects millions of metrics every day. It’s used to measure the health of networks in order for &lt;a href=&quot;http://www.cedexis.com/openmix/&quot; target=&quot;_blank&quot;&gt;Cedexis Openmix&lt;/a&gt; to make intelligent routing decisions for web service users.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://cedexis.com&quot;&gt;&lt;img src=&quot;/wp-content/uploads/2015/01/logo-cedexis.png#right&quot; alt=&quot;Cedexis Logo&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I put together &lt;a href=&quot;/cedexis-radar-tracking-for-wordpress/&quot; title=&quot;Cedexis Radar Tracking for WordPress&quot;&gt;a simple plugin&lt;/a&gt; to add Cedexis Radar tracking codes to a WordPress website. I’m not yet sure how much of an overlap there is between WordPress users and Cedexis Openmix users, but if you’re using both, &lt;a href=&quot;/cedexis-radar-tracking-for-wordpress/&quot; title=&quot;Cedexis Radar Tracking for WordPress&quot;&gt;check out my new plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sometime between 2015 and 2022, Cedexis was purchased by Citrix and no longer exists.&lt;/em&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Web Page Size is Vital</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/01/web-page-size-is-vital/" rel="alternate" type="text/html" title="Web Page Size is Vital" />
        <updated>2015-01-19T20:05:17+00:00</updated>
        <id>https://arnesonium.com/2015/01/web-page-size-is-vital</id>
          <category term="optimization" />
        
          <category term="performance" />
        
          <category term="programming" />
        
          <category term="web-design" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/01/web-page-size-is-vital/">&lt;p&gt;When I first learned how to program a computer, optimization was a big deal. Figuring out how to squeeze every bit of performance out of a subroutine was difficult but rewarding. Articles were frequently written about how to best go about optimizing source code.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;In the late 1990s, I began working on my first web applications. Bandwidth was expensive, so we worked on ways to make our websites more compact. We &lt;a href=&quot;http://www.feedthebot.com/pagespeed/enable-compression.html&quot; target=&quot;_blank&quot;&gt;compressed web pages&lt;/a&gt; and figured out ways to strip out whitespace. However, today websites have quite a bit going on in the front of the house. There’s a lot of JavaScript and CSS that gets passed to the browser, and as a result, web applications are transmitting more data than ever.&lt;/p&gt;

&lt;p&gt;Tammy Everts writes a blog called &lt;a href=&quot;http://www.webperformancetoday.com/&quot; title=&quot;Web Performance Today&quot; target=&quot;_blank&quot;&gt;Web Performance Today&lt;/a&gt;, where she follows trends in web application development. It is essential for web developers to pay attention to the amount of data they send to users and how that affects application performance.&lt;/p&gt;

&lt;p&gt;https://twitter.com/tameverts/status/555780016563564544&lt;/p&gt;

&lt;p&gt;Ms Everts has shown over and over that web pages are growing. She points out that the average web page has &lt;a href=&quot;http://www.webperformancetoday.com/2014/12/02/page-bloat-update-average-top-1000-web-page-1795-kb-size/&quot; target=&quot;_blank&quot;&gt;grown 186% since 2010&lt;/a&gt;, and it shows no sign of stopping. I believe that every responsible web developer owes it to himself ((Or herself.)) to follow Ms Everts’ blog.&lt;/p&gt;

&lt;p&gt;Please, fellow web developers, pay attention to how big your web pages are getting. Let’s reverse this trend.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Hypothes.is Web Annotation Tool</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/01/hypothes-is-web-annotation-tool/" rel="alternate" type="text/html" title="Hypothes.is Web Annotation Tool" />
        <updated>2015-01-14T23:38:13+00:00</updated>
        <id>https://arnesonium.com/2015/01/hypothes-is-web-annotation-tool</id>
          <category term="javascript" />
        
          <category term="programming" />
        
          <category term="tools" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/01/hypothes-is-web-annotation-tool/">&lt;p&gt;While working on the &lt;a title=&quot;Philalethes E-Bulletin Online Reader&quot; href=&quot;/2015/01/philalethes-e-bulletin-online-reader/&quot;&gt;&lt;em&gt;Philalethes E-Bulletin&lt;/em&gt; Online Reader&lt;/a&gt;, I came across a useful web-based annotation tool called &lt;a title=&quot;Hypothes.is: The Web, Annotated&quot; href=&quot;http://hypothes.is/&quot; target=&quot;_blank&quot;&gt;Hypothes.is&lt;/a&gt;. It’s worth checking out. The tool uses a browser plugin to provide a number of cool features.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://hypothes.is/&quot;&gt;&lt;img src=&quot;/wp-content/uploads/2015/01/hypothelogo_light2.png#right&quot; alt=&quot;Hypothes.is Logo&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Annotation&lt;/li&gt;
	&lt;li&gt;Discussion&lt;/li&gt;
	&lt;li&gt;Tagging&lt;/li&gt;
	&lt;li&gt;Sharing&lt;/li&gt;
	&lt;li&gt;Privacy Control&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also provides an &lt;a title=&quot;Hypothes.is annotation stream&quot; href=&quot;https://hypothes.is/stream&quot; target=&quot;_blank&quot;&gt;annotation stream&lt;/a&gt; that allows you to view public annotations as they’re being made all over the web.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Philalethes E-Bulletin Online Reader</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/01/philalethes-e-bulletin-online-reader/" rel="alternate" type="text/html" title="Philalethes E-Bulletin Online Reader" />
        <updated>2015-01-12T22:33:11+00:00</updated>
        <id>https://arnesonium.com/2015/01/philalethes-e-bulletin-online-reader</id>
          <category term="epub" />
        
          <category term="freemasonry" />
        
          <category term="javascript" />
        
          <category term="php" />
        
          <category term="programming" />
        
          <category term="publishing" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/01/philalethes-e-bulletin-online-reader/">&lt;p&gt;I began working on the &lt;a href=&quot;http://freemasonry.org/ebulletin/&quot; title=&quot;Philalethes E-Bulletin&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;Philalethes E-Bulletin&lt;/em&gt;&lt;/a&gt; in the Fall of 2013, and published the first issue in January of 2014. The &lt;em&gt;E-Bulletin&lt;/em&gt; is published quarterly in EPUB and MOBI formats.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/wp-content/uploads/2014/12/Screenshot-from-2014-12-18-214441.png#left&quot; alt=&quot;Philalethes Society Seal&quot; width=&quot;203&quot; height=&quot;171&quot; class=&quot;alignright size-full wp-image-189&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s been a great learning experience. Not only have I learned a lot about editing, but I’ve really had to dive into how electronic publishing works. The intricacies of electronic book formats have become well-known to me.&lt;/p&gt;

&lt;p&gt;The Philalethes Society isn’t entirely comfortable with modern technology, however. Most complaints about the &lt;em&gt;E-Bulletin&lt;/em&gt; came from those who didn’t have e-book readers and weren’t comfortable installing software on their PC to handle a new file format. Because of this, I built an online e-book reader specifically for the &lt;em&gt;E-Bulletin&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The online e-book reader is based around the excellent &lt;a href=&quot;https://github.com/futurepress/epub.js/&quot; target=&quot;_blank&quot;&gt;EPUB.js library&lt;/a&gt;, with additional backend code written in PHP.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://freemasonry.org/ebulletin/reader/&quot; title=&quot;Philalethes E-Bulletin Online Reader&quot; target=&quot;_blank&quot;&gt;Click here to visit the &lt;em&gt;Philalethes E-Bulletin&lt;/em&gt; Online Reader.&lt;/a&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>An English-language Stemmer for OCaml</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/an-english-language-stemmer-for-ocaml/" rel="alternate" type="text/html" title="An English-language Stemmer for OCaml" />
        <updated>2014-12-29T16:47:38+00:00</updated>
        <id>https://arnesonium.com/2014/12/an-english-language-stemmer-for-ocaml</id>
          <category term="c" />
        
          <category term="ocaml" />
        
          <category term="opam" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/an-english-language-stemmer-for-ocaml/">&lt;p&gt;A stemming algorithm attempts to reduce words to their stem. For instance, “swimming” would be reduced to “swim”, and “avocados” would become “avocado”. This is useful in a number of situations, most especially in searching text. This library is a direct port of the Porter English stemming algorithm.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;It was one of my first OCaml projects. I wrote it back in 2003, when I was still new to the language. I had been spending a lot of time writing C libraries that were being called by Perl scripts for my day job. Perl has, or had, a cumbersome, messy interface to C that made such interfaces very difficult to write and maintain.&lt;/p&gt;

&lt;p&gt;When I discovered how easy it was to link C libraries into OCaml, I was overjoyed! This was my first attempt. Before reading further, check out my &lt;a href=&quot;https://github.com/pymander/ocaml-stemmer&quot;&gt;ocaml-stemmer library on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Updating the Code&lt;/h2&gt;

&lt;p&gt;Recently, while overhauling all of my publicly-available code, I decided to update my English-language stemmer for OCaml. It’s not a very large piece of code, but its age really shows. It wouldn’t compile cleanly with the latest version of OCaml. It looks like the code of somebody who hasn’t really grokked functional programming yet. Just look at this.&lt;/p&gt;

&lt;div class=&quot;language-ocaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;replace_end&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rule_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rule_list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match_rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply_rule&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;replace_end&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ouch, right?&lt;/p&gt;

&lt;p&gt;I decided that the scary code would stand as a good message ((Or maybe I should say a good warning.)) to future functional programmers. For now, I just wanted to get this code to compile and not look messy. That ended up being easy.&lt;/p&gt;

&lt;h2&gt;Finding The Bug&lt;/h2&gt;

&lt;p&gt;Once I got it compiled cleanly, however, I found a bug. Back in 2003, I was big on test-driven development. I wrote tests for lots of code. The OCaml stemmer, it turns out, has been broken for quite a while. It doesn’t handle words with apostrophes correctly!&lt;/p&gt;

&lt;p&gt;I thought that fixing the bug it would be a challenge. However, I quickly I discovered in the OCaml manual that the &lt;code&gt;or&lt;/code&gt; operator was deprecated, and that &lt;code&gt;||&lt;/code&gt; should be used instead. Embarrassingly, the &lt;code&gt;or&lt;/code&gt; operator was deprecated back in 2002. That never should have been in the code! You can view the &lt;a href=&quot;https://github.com/pymander/ocaml-stemmer/commit/40cb816c4d97eea0d51de0f66533c09011f6cbd0&quot; target=&quot;_blank&quot;&gt;commit which fixed the bug here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;My Stemmer Library is Now on OPAM&lt;/h2&gt;

&lt;p&gt;This is my second library on &lt;a href=&quot;http://opam.ocaml.org/&quot; target=&quot;_blank&quot;&gt;OPAM&lt;/a&gt;, including my &lt;a href=&quot;http://arnesonium.com/2014/12/camlprime-now-on-opam/&quot; title=&quot;Camlprime Now on OPAM&quot; target=&quot;_blank&quot;&gt;prime number library&lt;/a&gt;. You can &lt;a href=&quot;http://opam.ocaml.org/packages/stemmer/stemmer.0.2/&quot; target=&quot;_blank&quot;&gt;view it on OPAM here&lt;/a&gt;.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Official Release of Libbucket 1.0.4</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/official-release-of-libbucket-1-0-4/" rel="alternate" type="text/html" title="Official Release of Libbucket 1.0.4" />
        <updated>2014-12-18T18:56:02+00:00</updated>
        <id>https://arnesonium.com/2014/12/official-release-of-libbucket-1-0-4</id>
          <category term="announcement" />
        
          <category term="c" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/official-release-of-libbucket-1-0-4/">&lt;p&gt;&lt;img src=&quot;https://img.shields.io/github/release/pymander/libbucket.svg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ve tagged &lt;a href=&quot;https://github.com/pymander/libbucket/releases/tag/v1.0.4&quot; target=&quot;_blank&quot;&gt;version 1.0.4&lt;/a&gt; of libbucket over on GitHub. You can download a tarball &lt;a href=&quot;https://github.com/pymander/libbucket/archive/v1.0.4.tar.gz&quot; target=&quot;_blank&quot;&gt;at this link&lt;/a&gt;. If you’d like to read more about libbucket, see &lt;a href=&quot;http://arnesonium.com/2014/12/modernizing-libbucket/&quot; title=&quot;Modernizing libbucket&quot;&gt;my post from earlier this week&lt;/a&gt;.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Very handy edit:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can download version 1.0.4 of libbucket and an OpenPGP signature here:&lt;/p&gt;

&lt;blockquote&gt;&lt;a href=&quot;https://s3.amazonaws.com/arnesonium-downloads/libbucket-1.0.4.tar.gz&quot;&gt;libbucket-1.0.4.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://s3.amazonaws.com/arnesonium-downloads/libbucket-1.0.4.tar.gz.asc&quot;&gt;libbucket-1.0.4.tar.gz.asc&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;[caption id=”attachment_184” align=”aligncenter” width=”300”]&lt;img src=&quot;http://arnesonium.com/wp-content/uploads/2014/12/hakamairi-bucketflowers.png&quot; alt=&quot;I never realized how much bucket clip-art existed.&quot; width=&quot;300&quot; height=&quot;164&quot; class=&quot;size-full wp-image-184&quot; /&gt; I never realized how much bucket clip-art existed.[/caption]&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Small Team Software Change Management</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/small-team-software-change-management/" rel="alternate" type="text/html" title="Small Team Software Change Management" />
        <updated>2014-12-18T01:45:51+00:00</updated>
        <id>https://arnesonium.com/2014/12/small-team-software-change-management</id>
          <category term="freshbooks" />
        
          <category term="git" />
        
          <category term="github" />
        
          <category term="management" />
        
          <category term="programming" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/small-team-software-change-management/">&lt;p&gt;Until October, I’d been using a paid &lt;a href=&quot;http://github.com/&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt; account to manage source code changes and issue tracking for private projects. GitHub is a software-as-a-service (SaaS) product providing a web-based interface for source control management and various project tracking tasks. &lt;a href=&quot;http://blogs.perl.org/users/jt_smith/2011/12/github-is-an-amazing-service-that-much-of-the-perl-community-has.html&quot; target=&quot;_blank&quot;&gt;Some people love it&lt;/a&gt; and &lt;a href=&quot;http://laurent.bachelier.name/2012/05/github-kinda-sucks/&quot; target=&quot;_blank&quot;&gt;some aren’t fond of it&lt;/a&gt;.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;My software development clients are typically small companies wanting fairly simple web applications. They hire me because having a developer on staff doesn’t fit into their budget or business plan. They don’t usually care what the source code for their project looks like, but they do care about tracking issues.&lt;/p&gt;

&lt;p&gt;Because of the scope of these applications, it’s rare that I work with other programmers. This meant that I wasn’t using any of the special features of GitHub for private code repositories, so in October I cancelled my subscription.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://eriklarneson.freshbooks.com/refer/www&quot;&gt;&lt;img src=&quot;/wp-content/uploads/2014/12/FreshBooks_Cloud_Accounting_Logo.png#right&quot; alt=&quot;FreshBooks&quot; /&gt;&lt;/a&gt;My private repositories are now self-hosted, and I browse them using &lt;a href=&quot;http://gitlist.org/&quot; target=&quot;_blank&quot;&gt;GitList&lt;/a&gt;, which bills itself as “an elegant and modern git repository viewer.” It looks nice, and I’ve got no complaints. For issue tracking, I use &lt;a href=&quot;https://eriklarneson.freshbooks.com/refer/www&quot; target=&quot;_blank&quot;&gt;Freshbooks&lt;/a&gt;, a SaaS accounting system. With Freshbooks, I can not only keep track of bug reports and issues, but I can record time spent on bug reports, feature creep, and other client-related issues.&lt;/p&gt;

&lt;p&gt;GitList and Freshbooks isn’t a perfect solution. At some point, I will be working with another developer, and we will need a way to track bugs and issues internally. When that happens, I plan to deploy &lt;a href=&quot;http://gitolite.com/gitolite/index.html&quot; target=&quot;_blank&quot;&gt;Gitolite&lt;/a&gt; and find some new issue-tracking solution.&lt;/p&gt;

&lt;p&gt;By the way, another reason I stopped using paid GitHub features is because &lt;a href=&quot;http://www.businessweek.com/articles/2013-06-20/github-got-silly-rich-dot-next-step-make-more-awesome&quot; target=&quot;_blank&quot;&gt;they’ve already made plenty of money&lt;/a&gt;, and I’m not sure they’re doing the right things with all of that money.&lt;/p&gt;

&lt;p&gt;I’m curious about what others are using. How does your incredibly small team track code changes and issues? Are all of your software issues internal, or are you developing for clients? I’d love to hear some ideas.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Modernizing libbucket</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/modernizing-libbucket/" rel="alternate" type="text/html" title="Modernizing libbucket" />
        <updated>2014-12-15T16:45:55+00:00</updated>
        <id>https://arnesonium.com/2014/12/modernizing-libbucket</id>
          <category term="c" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/modernizing-libbucket/">&lt;p&gt;If you’re here to learn about my experience in software development, you’ve probably poked around &lt;a href=&quot;https://github.com/pymander&quot;&gt;my GitHub page&lt;/a&gt;. One the older projects on there is &lt;a href=&quot;https://github.com/pymander/libbucket&quot;&gt;libbucket&lt;/a&gt;, a very fast dynamic string buffer library. I originally wrote it while working for Musician’s Friend, and was given permission to release it as an open sourced library in 2005.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://arnesonium.com/wp-content/uploads/2014/11/bucket-303359_640-300x293.png#right&quot; alt=&quot;Metaphorically similar to this kind of bucket.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Recently I decided to update the build system in the library, which was using an old version of autoconf and automake. I haven’t worked with those tools in a number of years. They are solid and flexible, but they’re also a confusing tangle of m4 macros and crazy shell scripts. Also, they change a lot.&lt;/p&gt;

&lt;p&gt;A few important things had changed. For instance, &lt;code&gt;aclocal&lt;/code&gt; wanted to read from &lt;code&gt;configure.ac&lt;/code&gt; instead of &lt;code&gt;configure.in&lt;/code&gt;. In addition, the &lt;code&gt;AM_INIT_AUTOMAKE&lt;/code&gt; macro was completely different, but the tool was nice enough to point me to &lt;a href=&quot;https://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation&quot;&gt;the relevant part of the automake manual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Building a library is also a little different now than it was in 2002. &lt;a href=&quot;https://www.gnu.org/software/libtool/&quot;&gt;GNU Libtool&lt;/a&gt; is a great program for building dynamic and shared libraries correctly for Unix systems, but its usage is different now. Luckily, it spit out all of the information I needed to update things.&lt;/p&gt;

&lt;p&gt;One thing I didn’t quite figure out is how to get automake to recognize the &lt;code&gt;README.org&lt;/code&gt; file as satisfying its README requirement. I ended up with an initialization block in &lt;code&gt;configure.ac&lt;/code&gt; that looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-m4&quot;&gt;AC_INIT([libbucket], [1.0.4])
AC_CONFIG_SRCDIR([src/bucket.c])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign])
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see the unpleasant “cheat” on line 4. Sorry about that, world.&lt;/p&gt;

&lt;p&gt;After all of that mess, there were just a couple of small fixes to the documentation, which is written in GNU Texinfo, and the library compiled just fine.&lt;/p&gt;

&lt;p&gt;Unfortunately, I don’t have any tests. When I first developed libbucket, we had a proprietary test interface for C and C++ libraries at Musician’s Friend. That never got open sourced, so I had to remove it all before making the libbucket code public. Maybe tests are next.&lt;/p&gt;

&lt;p&gt;If you’d like to take a look at the changes I made, &lt;a href=&quot;https://github.com/pymander/libbucket/commit/6314493fb7c8397318ac4a8d10624159aab07204&quot;&gt;here’s the Git commit&lt;/a&gt;.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>PunchlinePDX Event Manager</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/punchlinepdx-event-manager/" rel="alternate" type="text/html" title="PunchlinePDX Event Manager" />
        <updated>2014-12-08T17:23:17+00:00</updated>
        <id>https://arnesonium.com/2014/12/punchlinepdx-event-manager</id>
          <category term="database" />
        
          <category term="javascript" />
        
          <category term="php" />
        
          <category term="programming" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/punchlinepdx-event-manager/">&lt;p&gt;&lt;a href=&quot;http://www.punchlinepdx.com/&quot;&gt;PunchlinePDX&lt;/a&gt; is a slow-motion video booth for events and parties based out of Portland, Oregon. Earlier this year, I helped them develop event management software that would allow them to upload and curate video.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;This was their first experience hiring a software developer, so I had the opportunity to walk them through the entire process. We started by outlining requirements and coming up with a solid plan with application screens, functions, and things to meet their business needs. We then brainstormed additional features and came up with something pretty amazing.&lt;/p&gt;

&lt;p&gt;These are a few of the interesting things we came up with:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Cloud-backed storage for all videos&lt;/li&gt;
    &lt;li&gt;Text messaging interface&lt;/li&gt;
    &lt;li&gt;Smart social media sharing&lt;/li&gt;
    &lt;li&gt;Contact management&lt;/li&gt;
    &lt;li&gt;Event and sharing privacy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best part was the testing process. While I ran them through their new software, they made slow-motion video of me and used the software to upload and manage it. Check it out!&lt;/p&gt;

&lt;video controls=&quot;&quot; autoplay=&quot;&quot; loop=&quot;&quot; style=&quot;width:98%&quot; poster=&quot;https://punchline-staging.s3.amazonaws.com/event-5-video-14.jpg&quot;&gt;
   &lt;source src=&quot;https://punchline-staging.s3.amazonaws.com/event-5-video-14.mp4&quot; type=&quot;video/mp4&quot; /&gt;
   Your browser does not support the video tag.
&lt;/video&gt;

&lt;p&gt;&lt;strong&gt;You should seriously consider booking these guys for your holiday party.&lt;/strong&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Camlprime Now on OPAM</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/camlprime-now-on-opam/" rel="alternate" type="text/html" title="Camlprime Now on OPAM" />
        <updated>2014-12-02T22:19:09+00:00</updated>
        <id>https://arnesonium.com/2014/12/camlprime-now-on-opam</id>
          <category term="math" />
        
          <category term="ocaml" />
        
          <category term="opam" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/camlprime-now-on-opam/">&lt;p&gt;My first &lt;a href=&quot;http://opam.ocaml.org/&quot; target=&quot;_blank&quot;&gt;OCaml Package Manager (OPAM)&lt;/a&gt; submission has just been accepted. You can now find &lt;a href=&quot;http://arnesonium.com/2014/11/prime-number-library-for-ocaml/&quot; title=&quot;Prime Number Library for OCaml&quot;&gt;Camlprime, a prime number library&lt;/a&gt;, on &lt;a href=&quot;http://opam.ocaml.org/packages/camlprime/camlprime.0.5/&quot; target=&quot;_blank&quot;&gt;OPAM here&lt;/a&gt;.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Handy Tools for the Bourne Again Shell</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/12/handy-tools-for-the-bourne-again-shell/" rel="alternate" type="text/html" title="Handy Tools for the Bourne Again Shell" />
        <updated>2014-12-01T16:38:30+00:00</updated>
        <id>https://arnesonium.com/2014/12/handy-tools-for-the-bourne-again-shell</id>
          <category term="bash" />
        
          <category term="programming" />
        
          <category term="shell" />
        <content type="html" xml:base="https://arnesonium.com/2014/12/handy-tools-for-the-bourne-again-shell/">&lt;p&gt;If you’re a Unix geek, you’ve probably used bash, the Bourne-Again Shell. If you’ve been around a while, you’ve probably spent a lot of time customizing bash.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Back when I worked for Yahoo!, my friend Bryan gave me a great directory stack for bash. I loved it, so I rewrote it and have been hacking on it and using it ever since. Observe.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[user@host:~]$ cd /tmp
[user@host:/tmp]$ cd /var/log
[user@host:/var/log]$ dl
1   ~
2   /tmp
3 * /var/log
[user@host:/var/log]$ go 1
1   /home/user
[user@host:~]$ go log
3   /var/log
[user@host:/var/log]$ 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In addition to the handy new &lt;code&gt;go&lt;/code&gt; command, it also includes &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;f&lt;/code&gt; for moving backwards and forwards on the stack. It was inspired by &lt;code&gt;pushd&lt;/code&gt; and &lt;code&gt;popd&lt;/code&gt;, but it’s so much more.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arnesonium.com/wp-content/uploads/2014/11/sea_shell.jpg&quot;&gt;&lt;img src=&quot;https://arnesonium.com/wp-content/uploads/2014/11/sea_shell-300x211.jpg#left&quot; alt=&quot;Not this kind of shell.&quot; width=&quot;300&quot; height=&quot;211&quot; class=&quot;size-medium wp-image-65&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’d like to check it out, take a look at my &lt;a href=&quot;https://github.com/pymander/bashtools&quot;&gt;bashtools repository on GitHub&lt;/a&gt; or just &lt;a href=&quot;https://github.com/pymander/bashtools/archive/v1.0.tar.gz&quot; title=&quot;bashtools 1.0&quot;&gt;download version 1.0&lt;/a&gt;. I don’t change it very often, but I’m thinking of hammering out a long-standing bug in the directory stack code.&lt;/p&gt;

&lt;p&gt;N.B. If you use all of my scripts, you’ll get some great prompts for your xterms. You’re welcome!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Website: Bruno San Rafael&apos;s Home for Former Trapeze</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/11/website-bruno-san-rafaels-home-for-former-trapeze/" rel="alternate" type="text/html" title="Website: Bruno San Rafael's Home for Former Trapeze" />
        <updated>2014-11-24T17:29:56+00:00</updated>
        <id>https://arnesonium.com/2014/11/website-bruno-san-rafaels-home-for-former-trapeze</id>
          <category term="html" />
        
          <category term="javascript" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="portfolio" />
        <content type="html" xml:base="https://arnesonium.com/2014/11/website-bruno-san-rafaels-home-for-former-trapeze/">&lt;p&gt;Back in 2012, I had the pleasure of working with my good friend Joel Barker on his amazing project, &lt;a href=&quot;http://brunosanrafael.com/&quot;&gt;Bruno San Rafael’s Home for Former Trapeze&lt;/a&gt;. This project is a collaboration between Joel, a bunch of musicians, a photographer, and a web developer (me!). My contribution was probably the smallest of the bunch, but it was a lot of fun.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Please check out the website by clicking on the screenshot below. If you use “View Source” in your browser, you can see every line of code I used to finish the site. It’s one simple, medium-length monolithic HTML file with JavaScript and CSS thrown in.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://brunosanrafael.com/&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;aligncenter size-large wp-image-60&quot; src=&quot;/wp-content/uploads/2014/11/Screenshot-from-2014-11-13-092922-1024x499.png&quot; alt=&quot;Bruno San Rafael&quot; width=&quot;580&quot; height=&quot;282&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I now work with Joel regularly at &lt;a href=&quot;http://www.wordlions.com/&quot;&gt;Word Lions&lt;/a&gt;, where I write and do a little more website development.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Prime Number Library for OCaml</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2014/11/prime-number-library-for-ocaml/" rel="alternate" type="text/html" title="Prime Number Library for OCaml" />
        <updated>2014-11-13T17:08:39+00:00</updated>
        <id>https://arnesonium.com/2014/11/prime-number-library-for-ocaml</id>
          <category term="math" />
        
          <category term="ocaml" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2014/11/prime-number-library-for-ocaml/">&lt;p&gt;A couple of weeks ago, I cleaned up my prime number library for &lt;a href=&quot;https://ocaml.org/&quot;&gt;OCaml&lt;/a&gt;. This library has a number of primality-testing methods in it, but my favorite is the &lt;a href=&quot;http://jeremykun.com/2013/06/16/miller-rabin-primality-test/&quot;&gt;Miller-Rabin primality test&lt;/a&gt;. It’s fast and rather accurate.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;If you’d like to take a look at the library, please check out the &lt;a href=&quot;https://github.com/pymander/camlprime&quot;&gt;camlprime GitHub page&lt;/a&gt;. The library is pretty easy to use. If you download and compile the library, you’ll end up with a toplevel that you can play with.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;test.ml&lt;/code&gt; file has some examples of how to use the primality tests. However, my favorite thing about this library is that it includes a &lt;a href=&quot;https://www.haskell.org/haskellwiki/Lazy_evaluation&quot;&gt;lazy list&lt;/a&gt; implementation of prime numbers. The following example shows how to set up a lazy list of prime numbers proved using the MR algorithm in the toplevel.&lt;/p&gt;

&lt;div class=&quot;language-ocaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prime_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Prime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Prime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;miller_rabin&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_of_int&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prime_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;503&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Prime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nth&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prime_list&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4363&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The library is pretty fast, even for really large numbers. I’ve tested it on 300-digit prime numbers, and I’m sure it will scale to sizes much larger than that.&lt;/p&gt;

&lt;p&gt;Any thoughts or improvements? Let me know in the comments.&lt;/p&gt;</content>
      </entry>
    
</feed>
