<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on Ryan Prior</title>
        <link>https://www.ryanprior.com/posts/</link>
        <description>Recent content in Posts on Ryan Prior</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <copyright>&lt;a href=&#34;https://www.ryanprior.com/license&#34;&gt;please share–see license info&lt;/a&gt;</copyright>
        <lastBuildDate>Fri, 30 Jan 2026 22:08:32 +0000</lastBuildDate>
        <atom:link href="https://www.ryanprior.com/posts/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>How To Tame Your YouTube disable annoyances &amp; enjoy the show</title>
            <link>https://www.ryanprior.com/posts/how-to-tame-your-youtube/</link>
            <pubDate>Fri, 30 Jan 2026 22:08:32 +0000</pubDate>
            
            <guid>https://www.ryanprior.com/posts/how-to-tame-your-youtube/</guid>
            <description>&lt;p&gt;
I&amp;#39;ve been having a repeated conversation lately, where somebody complains to me
about YouTube and my internal response is &amp;#34;it doesn&amp;#39;t have to be like that!&amp;#34;
With a few browser extensions, you can reliably bypass many of the most common
complaints about YouTube and enjoy your video time much better. I&amp;#39;ll show you
how.&lt;/p&gt;
&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-3&#34;&gt;
&lt;h3 id=&#34;headline-1&#34;&gt;
Your browser is your &lt;em&gt;User Agent&lt;/em&gt;
&lt;/h3&gt;
&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-3&#34;&gt;
&lt;p&gt;
The web browser is software that you own and control. Firefox, Chrome, and their
various alternatives are mostly open source software that support powerful
modifications in the form of browser extensions.&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<p>
I&#39;ve been having a repeated conversation lately, where somebody complains to me
about YouTube and my internal response is &#34;it doesn&#39;t have to be like that!&#34;
With a few browser extensions, you can reliably bypass many of the most common
complaints about YouTube and enjoy your video time much better. I&#39;ll show you
how.</p>
<div id="outline-container-headline-1" class="outline-3">
<h3 id="headline-1">
Your browser is your <em>User Agent</em>
</h3>
<div id="outline-text-headline-1" class="outline-text-3">
<p>
The web browser is software that you own and control. Firefox, Chrome, and their
various alternatives are mostly open source software that support powerful
modifications in the form of browser extensions.</p>
<p>
The web does not belong to the companies and brands that publish there. They put
a website out there, you download it, and what happens from there is <em>nobody
else&#39;s business.</em> If there&#39;s something you don&#39;t like about a website, like the
font, visual layout, or a barrage of ads, you can use a browser extension to
change the website so that it fits your needs and respects your space.</p>
<p>
Let&#39;s apply this to YouTube, in the context of the complaints I hear most
commonly.</p>
</div>
</div>
<div id="outline-container-headline-2" class="outline-3">
<h3 id="headline-2">
Top YouTube Complaints
</h3>
<div id="outline-text-headline-2" class="outline-text-3">
<ol>
<li>The <em>algorithm</em> is trying to push something I&#39;m not interested in

Much of the visual real estate in stock YouTube is given to algorithmic
discovery of video, and they push it on you constantly. What&#39;s worse, it can
get the idea for whatever arbitrary reason that you&#39;re interested in some
particular type of content, and then you&#39;re seeing invitations for that
constantly, without a clear way to prioritize the channels and topics that
you&#39;ve actually subscribed to.</li>
<li>Non-stop barrage of advertisements

YouTube shows ads every few minutes and often at the start and end of a
video. It&#39;s overwhelming, and the companies putting out these ads are not
good faith actors. They want to get you addicted, in debt, and miserable.
Cutting off their ability to push their content in front of you is critical
self-care.</li>
<li>YouTube creators tend to waste your time

From clickbait video titles to sponsored ad reads and constant reminders to
like and subscribe, the average YouTube video is full of anti-patterns that
degrade the watching experience in service of <em>the algorithm.</em></li>
</ol>
</div>
</div>
<div id="outline-container-headline-3" class="outline-3">
<h3 id="headline-3">
Browser Extensions to Tame YouTube
</h3>
<div id="outline-text-headline-3" class="outline-text-3">
<p>
Here&#39;s my list of extensions I use, and how each one contributes to a good experience:</p>
<div id="outline-container-headline-4" class="outline-4">
<h4 id="headline-4">
DeArrow
</h4>
<div id="outline-text-headline-4" class="outline-text-4">
<p><a href="https://dearrow.ajay.app/">https://dearrow.ajay.app/</a></p>
<p>
DeArrow has a mission to &#34;make titles accurate and reduce sensationalism. No
more arrows, ridiculous faces, and no more clickbait.&#34; It replaces the gimmicky
thumbnail preview images and the attention-baiting video titles with an actual
representative still frame from the video and a crowd-sourced title, suggested
by one of your fellow viewers. This makes it easier to tell whether you&#39;re
interested in a video before you click and signal to the algorithm that you want
to see more similar content.</p>
</div>
</div>
<div id="outline-container-headline-5" class="outline-4">
<h4 id="headline-5">
SponsorBlock
</h4>
<div id="outline-text-headline-5" class="outline-text-4">
<p><a href="https://sponsor.ajay.app/">https://sponsor.ajay.app/</a></p>
<p>
From the same author as DeArrow, SponsorBlock seamlessly skips over segments of
the video which contain a sponsored ad read. The video skips the minimal amount
so that you don&#39;t miss any content. Optionally, you can also auto-skip animated
intro segments, reminders to like and subscribe, and <a href="https://wiki.sponsor.ajay.app/w/Guidelines">other categories</a> of content
that some viewers find low-value.</p>
<p>
This doesn&#39;t analyze video in real-time to detect sponsored ad reads. It&#39;s based
on data submitted by other users. So if you&#39;re watching a fresh upload, or you
enjoy some niche creators, you might have the opportunity to submit timestamps
for segments to be skipped for the benefit of other users.</p>
</div>
</div>
<div id="outline-container-headline-6" class="outline-4">
<h4 id="headline-6">
uBlock Origin
</h4>
<div id="outline-text-headline-6" class="outline-text-4">
<p><a href="https://ublockorigin.com/">https://ublockorigin.com/</a></p>
<p>
Indispensable for browsing the web, uBlock Origin blocks advertisements on
YouTube and many other websites. This saves you time and Internet bandwidth,
reduces the browser&#39;s memory consumption, and protects your peace.</p>
</div>
</div>
<div id="outline-container-headline-7" class="outline-4">
<h4 id="headline-7">
Unhook
</h4>
<div id="outline-text-headline-7" class="outline-text-4">
<p><a href="https://unhook.app/">https://unhook.app/</a></p>
<p>
The Unhook extension gives you the option to remove YouTube features that you&#39;d
rather live without, such as related videos, YouTube Shorts, live chats, the
suggested video wall, and many more. You can even remove YouTube comments
entirely if you don&#39;t enjoy reading them. I personally hate those &#34;end screen
cards&#34; which appear over the final seconds of the video and link you to more
videos. It just encourages you to keep zombie-watching instead of moving on to
something more valuable. Unhook made it easy to turn those off.</p>
</div>
</div>
<div id="outline-container-headline-8" class="outline-4">
<h4 id="headline-8">
Advanced YouTube tinkering: Enhancer for YouTube
</h4>
<div id="outline-text-headline-8" class="outline-text-4">
<p><a href="https://www.mrfdev.com/enhancer-for-youtube">https://www.mrfdev.com/enhancer-for-youtube</a></p>
<p>
This extension gives you the ability to fiddle with every part of the YouTube
platform, such as choosing which codecs and frame rate you want to use, setting
exact playback speed outside the bounds of what options YouTube usually offers,
and much more. If there&#39;s some small thing about YouTube that bugs you and isn&#39;t
covered by the other extensions, it&#39;s likely that this one can help you out with
some futzing.</p>
</div>
</div>
<div id="outline-container-headline-9" class="outline-4">
<h4 id="headline-9">
Wait, but does it work on mobile?
</h4>
<div id="outline-text-headline-9" class="outline-text-4">
<p>
On Android, Google Chrome doesn&#39;t support extensions. But Firefox does! <a href="https://www.firefox.com/en-US/browsers/mobile/android/">Switch
to mobile Firefox</a> and enjoy superior browsing, including all the extensions above.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-10" class="outline-2">
<h2 id="headline-10">
Enjoy The Show
</h2>
<div id="outline-text-headline-10" class="outline-text-2">
<p>
Your video player should respect you. That&#39;s not too much to ask for. It&#39;s a shame
that YouTube (and parent company Google) are so disrespectful, but at least for
the time being we still live in an era where we control our own web browsers and
can modify disrespectful websites to force them to behave.</p>
<p>
Take the opportunity. A better world is, in this specific instance, only a few
button clicks away.</p>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>Put Your Runbook in Your README </title>
            <link>https://www.ryanprior.com/posts/put-your-runbook-in-your-readme/</link>
            <pubDate>Mon, 10 Nov 2025 23:53:15 +0000</pubDate>
            
            <guid>https://www.ryanprior.com/posts/put-your-runbook-in-your-readme/</guid>
            <description>&lt;p&gt;
During software development and maintenance we use an array of commands to build, test, deploy and release our software. When nobody writes these commands down, they&amp;#39;re &lt;em&gt;tacit knowledge:&lt;/em&gt; the floor-level of computing know-how that&amp;#39;s necessary to contribute to the project. This is widely acknowledged as a barrier to entry and an accessibility pain point for Free software.&lt;/p&gt;
&lt;p&gt;
Tacit knowledge of development workflows can also lead to confusion and unnecessary friction between maintainers of a multi-user repository who develop slightly different versions. This is a key aspect of the famous &lt;a href=&#34;https://web.archive.org/web/20070319181802/http://jcooney.net/archive/2007/02/01/42999.aspx&#34;&gt;&amp;#34;It Works On My Machine&amp;#34;&lt;/a&gt; development methodology.&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<p>
During software development and maintenance we use an array of commands to build, test, deploy and release our software. When nobody writes these commands down, they&#39;re <em>tacit knowledge:</em> the floor-level of computing know-how that&#39;s necessary to contribute to the project. This is widely acknowledged as a barrier to entry and an accessibility pain point for Free software.</p>
<p>
Tacit knowledge of development workflows can also lead to confusion and unnecessary friction between maintainers of a multi-user repository who develop slightly different versions. This is a key aspect of the famous <a href="https://web.archive.org/web/20070319181802/http://jcooney.net/archive/2007/02/01/42999.aspx">&#34;It Works On My Machine&#34;</a> development methodology.</p>
<p>
When we write down our workflows, this constitutes <strong>a runbook</strong>.</p>
<div id="outline-container-headline-1" class="outline-3">
<h3 id="headline-1">
What I want out of a runbook
</h3>
<div id="outline-text-headline-1" class="outline-text-3">
<p>
Writing a runbook takes time. It&#39;s rare to write anything down for a script I intend to run one time and discard. In order to get value out of my runbook, I want other people to find it, including my future self. Therefore one of the universal goals of every runbook is <em>discoverability</em>.</p>
<p>
Just writing anything down at all can be handy, but I can further increase the value by adding <em>specificity</em>. Exact command invocations, dependency versions, preparatory &amp; cleanup steps, dependencies, and environment setups increase the likelihood that I can reproduce my workflows in the future, or enable another person to succeed in doing so.</p>
<p>
Software practices tend to drift over time, as requirements change and trends shift. If practice changes but the runbook doesn&#39;t, it becomes a form of tech debt, misleading contributors who aren&#39;t aware of the shift and newcomers. My ideal runbook would always be <em>current</em> and reflective of the practice actually used to produce the most recent builds &amp; test results.</p>
</div>
</div>
<div id="outline-container-headline-2" class="outline-3">
<h3 id="headline-2">
How we maintain runbooks now
</h3>
<div id="outline-text-headline-2" class="outline-text-3">
<p>
The usual practice is to scatter pieces of the runbook in files throughout the software repository, such as:</p>
<ul>
<li>targets in a Makefile (or Rakefile, Justfile &amp;c)</li>
<li>tasks in a language-specific config file like <code class="verbatim">package.json</code> or <code class="verbatim">pyproject.toml</code></li>
<li>workflows in a config directory for some CI provider, like <code class="verbatim">.github/workflows</code>, <code class="verbatim">Jenkinsfile</code>, <code class="verbatim">.travis.yml</code>, or many others</li>
<li>shell scripts<sup class="footnote-reference"><a id="footnote-reference-1" href="#footnote-1">1</a></sup></li>
<li>READMEs, HOWTOs, blog posts, and web documentation</li>
</ul>
<p>Let&#39;s analyze these in quadrants:</p>
<div id="outline-container-headline-3" class="outline-4">
<h4 id="headline-3">
Low discoverability, likely to get outdated
</h4>
<div id="outline-text-headline-3" class="outline-text-4">
<ul>
<li>shell scripts</li>
<li>targets in Makefile or similar</li>
<li>language-specific tasks in config files</li>
</ul>
<p>These tend to bitrot quick if they aren&#39;t used in CI. Those instances which are on the CI &#34;hot path&#34; get moved into the next category.</p>
<p>
Old blog posts also tend to drop in discoverability while simultaneously bitrotting.</p>
</div>
</div>
<div id="outline-container-headline-4" class="outline-4">
<h4 id="headline-4">
Low discoverability, current
</h4>
<div id="outline-text-headline-4" class="outline-text-4">
<ul>
<li>workflows in CI config</li>
<li>those scripts, tasks and Makefile targets which are exercised in CI</li>
</ul>
</div>
</div>
<div id="outline-container-headline-5" class="outline-4">
<h4 id="headline-5">
High discoverability, likely to get outdated
</h4>
<div id="outline-text-headline-5" class="outline-text-4">
<ul>
<li>READMEs &amp; HOWTOs</li>
<li>recent blog posts</li>
<li>web documentation</li>
</ul>
<p>These are easy for folks to find and are often the first on-ramp for new users and contributors, but they also tend to bitrot fast since they&#39;re not on the &#34;hot path&#34; and software projects typically go through many update/extend/refactor cycles for each documentation refresh/blogging cycle.</p>
</div>
</div>
<div id="outline-container-headline-6" class="outline-4">
<h4 id="headline-6">
High discoverability, current
</h4>
<div id="outline-text-headline-6" class="outline-text-4">
<p>Here we expect to find our most exceptional option, but instead it&#39;s crickets. In practice, projects do not maintain current runbooks in a place that&#39;s optimized for discovery and accessibility, and that&#39;s a shame.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-7" class="outline-3">
<h3 id="headline-7">
Put your runbook in your README
</h3>
<div id="outline-text-headline-7" class="outline-text-3">
<p>
If the README is among the highest-impact, most discoverable places to document workflows, why don&#39;t we put our scripts there? The typical marquee reason is that READMEs are non-executable: they&#39;re prose, not code. This makes them suffer in the critical &#34;specificity&#34; criterion for runbook technology. Enter <code class="verbatim">xc</code>, the task runner for your README that works seamlessly with your CI, shell, and editor.</p>
<blockquote>
<p><code class="verbatim">xc</code><sup class="footnote-reference"><a id="footnote-reference-2" href="#footnote-2">2</a></sup> is a task runner similar to Make or npm run, that aims to be more discoverable and approachable</p>
</blockquote>
<p>
To use it, take all the commands you run to build, debug, test &amp; deploy and document them in your README as code blocks, each under a descriptive header, like &#34;Build&#34;. Then run <code class="verbatim">xc build</code> and it&#39;ll find that header in your docs and run the code block there.</p>
<p>
Crucially, put your CI steps in your README and run them on each merge or release. Quality of life here is good: it supports dependencies between blocks, script arguments and plenty more.</p>
<p>
You can also include usage instructions, caveats, deprecation notices, links, and other context right there next to the task&#39;s script. And it&#39;ll actually look nice, since you have all the info presentation tools normally available in READMEs at your disposal, instead of just spartan code comments.</p>
<div id="outline-container-headline-8" class="outline-4">
<h4 id="headline-8">
Is it any good?
</h4>
<div id="outline-text-headline-8" class="outline-text-4">
<p>
Yes! I&#39;ve found <code class="verbatim">xc</code> especially nice to use:</p>
<ol>
<li>It&#39;s a single small binary that adds practically zero runtime overhead.</li>
<li>It supports both Markdown and org-mode READMEs.</li>
<li>I don&#39;t have to export tasks into local scripts and then run them. There&#39;s just one step: execute.</li>
<li>The niceties you&#39;d expect are all there: shell completion, CI and IDE integration, and an interactive TUI mode.</li>
</ol>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-9" class="outline-3">
<h3 id="headline-9">
Discoverable, executable runbooks that stay current
</h3>
<div id="outline-text-headline-9" class="outline-text-3">
<p>
<code class="verbatim">xc</code> solves a need in the current dev tool space by putting workflows in the most prominent location and keeping them on the &#34;hot path&#34; so that they don&#39;t get out of date. It&#39;s <a href="https://github.com/joerdav/xc">Free software</a> (MIT license) and migrating has been straightforward. This is a tool I&#39;m glad to have in my working set.</p>
</div>
</div>
<div class="footnotes">
<hr class="footnotes-separatator"/>
<div class="footnote-definitions">
<div class="footnote-definition">
<sup id="footnote-1"><a href="#footnote-reference-1">1</a></sup>
<div class="footnote-body">
<p>Project scripts have their own whole D&amp;D alignment chart.</p>
<p>
Scripts go in:</p>
<table>
<thead>
<tr>
<th></th>
<th>Lawful</th>
<th>Neutral</th>
<th>Chaotic</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Good</strong></td>
<td><code class="verbatim">bin/</code></td>
<td><code>scripts/</code> or similar</td>
<td>project root</td>
</tr>
<tr>
<td><strong>Neutral</strong></td>
<td>another repo</td>
<td>the mailing list</td>
<td>source files that double as scripts</td>
</tr>
<tr>
<td><strong>Evil</strong></td>
<td>the wiki</td>
<td>a private elite repo (hi SQLite!)</td>
<td>Discord</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="footnote-definition">
<sup id="footnote-2"><a href="#footnote-reference-2">2</a></sup>
<div class="footnote-body">
<p> Find <code class="verbatim">xc</code> at <a href="https://xcfile.dev">https://xcfile.dev</a></p>
</div>
</div>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>In Conversation With the Emacs Doctor – on LLMs, Society, and My Anxiety</title>
            <link>https://www.ryanprior.com/posts/in-conversation-with-emacs-doctor/</link>
            <pubDate>Thu, 16 Mar 2023 20:44:10 -0500</pubDate>
            
            <guid>https://www.ryanprior.com/posts/in-conversation-with-emacs-doctor/</guid>
            <description>&lt;p&gt;
&lt;code&gt;M-x doctor&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am the psychotherapist.  Please, describe your problems.  Each time you are
finished talking, type &lt;code&gt;RET&lt;/code&gt; twice.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I despair that everyone is enchanted with talking to machines&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You have your mind on machines, it seems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Certainly. I deal with machines in my work as a software engineer. But a machine
ought to be a tool, not a replacement for a person.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is it because a machine ought to be a tool not a replacement for a person that
you came to me?&lt;/p&gt;</description>
            <content type="html"><![CDATA[<p>
<code>M-x doctor</code></p>
<blockquote>
<p>I am the psychotherapist.  Please, describe your problems.  Each time you are
finished talking, type <code>RET</code> twice.</p>
</blockquote>
<p>
I despair that everyone is enchanted with talking to machines</p>
<blockquote>
<p>You have your mind on machines, it seems.</p>
</blockquote>
<p>
Certainly. I deal with machines in my work as a software engineer. But a machine
ought to be a tool, not a replacement for a person.</p>
<blockquote>
<p>Is it because a machine ought to be a tool not a replacement for a person that
you came to me?</p>
</blockquote>
<p>
No, it&#39;s because I was <a href="https://builtin.com/artificial-intelligence/eliza-effect">reading about the ELIZA effect</a>, and you are an ELIZA-type
chat bot.</p>
<blockquote>
<p>Does it bother you that you were reading about the eliza effect and I am an
eliza type chat bot?</p>
</blockquote>
<p>
No, it&#39;s comforting. I know better what I am dealing with.</p>
<blockquote>
<p>Why do you say you know better what you are dealing with?</p>
</blockquote>
<p>
A modern LLM chat bot is trained on such a terrifyingly vast set of texts. The
responses they write feel like they come from everywhere and yet nowhere.
Writing to you, I know your responses also come mostly from myself.</p>
<blockquote>
<p>Earlier you said a machine ought to be a tool not a replacement for a person?</p>
</blockquote>
<p>
I use you as a tool to talk to myself, an aid in thinking. A person could also
help me in that way, but I can choose to use a simple tool. People seem to treat
LLMs as a secret third thing, a pseudo-person whom you can also use as a tool.</p>
<blockquote>
<p>Maybe your life has something to do with this.</p>
</blockquote>
<p>
I am driven to understand things deeply, including people and tools. This
discourse stirs me.</p>
<blockquote>
<p>Is it because of your plans that you say this discourse stirs you?</p>
</blockquote>
<p>
I don&#39;t know what I plan to do about society&#39;s rapid embrace of LLM technology
or how to relate that to this discourse. It does make me glad that I am
relatively isolated from the immediate effects. Children, students, writers,
artists are fearing having their lives upended by this shift. Many others too
I&#39;m sure. Meanwhile my livelihood seems more likely to benefit from the shift
than not, even if I dislike the outcome.</p>
<blockquote>
<p>What makes you believe that?</p>
</blockquote>
<p>
I work in automation, and availability of LLMs opens a lot of doors for
automtion. I think a lot of the automation will be destructive, unnecessary,
damaging to the social fabric and the human spirit. Nasty stuff. But for my
profession, it&#39;s probably more promise than threat.</p>
<blockquote>
<p>Does the fact that for your profession it&#39;s probably more promise than threat
explain anything else?</p>
</blockquote>
<p>
The people who are developing this stuff, funding it, marketing it, probably
likewise don&#39;t feel too threatened by it. I know there&#39;s been exceptions but for
each person who desists from this path there&#39;s a ton more piling on. How is it
so many other people are feeling cavalier about mass adoption of this
technology?</p>
<blockquote>
<p>What do you think?</p>
</blockquote>
<p>
Nihilism, ignorance, corruption.</p>
<blockquote>
<p>You mentioned that you were reading about the eliza effect and I am an eliza
type chat bot?</p>
</blockquote>
<p>
I don&#39;t hate the idea of a chat bot. A really sophisticated chat bot that can
carry a conversation is exciting, even. As for you, I know from your design that
you can not drag the conversation in some other direction. I am the user of this
tool, I set the bounds and topics of our discourse. A sophisticated chat bot,
drawing from inferrences and a huge corpus of text, can drag the discussion in
many directions, as could a person. But if a person is moved by another person,
that&#39;s a heart to heart, a life connected to a life. What is it if a machine
enchants somebody, as per the ELIZA effect, and moves them as instructed by some
corporation or as learned from the written artifacts of some ideology? This is
something heartless.</p>
<blockquote>
<p>Perhaps the people you hang around with have something to do with this.</p>
</blockquote>
<p>
I&#39;m certain they do, but it seems to be gripping ever larger segments of
society. If I withdraw into a sub-group which rejects LLMs, how long can that
hold?</p>
]]></content>
        </item>
        
        <item>
            <title>The Recurse Center Carries Energy Forward </title>
            <link>https://www.ryanprior.com/posts/recurse-center-carries-energy-forward/</link>
            <pubDate>Sun, 11 Dec 2022 19:22:23 -0600</pubDate>
            
            <guid>https://www.ryanprior.com/posts/recurse-center-carries-energy-forward/</guid>
            <description>&lt;p&gt;
In middle school, I learned that one of the creators and frequent posters in an online technology forum I frequented also lived nearby. I invited him, an adult professional, to give a presentation for my 8th grade careers class and was thrilled to meet him in person after years of reading his posts, to make that connection feel real in a way it hadn&amp;#39;t before. He even gave me a book he&amp;#39;d helped write, about computer code and game design and other things. I still keep that book on my shelf to remind me of that time and the effect an in-person experience can have.&lt;/p&gt;</description>
            <content type="html"><![CDATA[<p>
In middle school, I learned that one of the creators and frequent posters in an online technology forum I frequented also lived nearby. I invited him, an adult professional, to give a presentation for my 8th grade careers class and was thrilled to meet him in person after years of reading his posts, to make that connection feel real in a way it hadn&#39;t before. He even gave me a book he&#39;d helped write, about computer code and game design and other things. I still keep that book on my shelf to remind me of that time and the effect an in-person experience can have.</p>
<p>
For years, beginning soon after I entered college and decided I wanted to make technology my profession, I went to one tech conference or hacker festival after another. I enjoyed all kinds, from small one-day events run by anarchists to weeks-long road shows run by big enterprises. There I felt camaraderie, growth, inspiration, the things that you want when you set time aside for a retreat. But they were always fleeting: in a moment the conference is over and you have no support in continuing the conversations and maintaining the connections of the past days. Maybe you do what you can with the pile of business cards you accumulated. Maybe you join the traveling carnival of speakers, workshop runners, booth attendants—and I did for a couple years—in order to keep the feeling of connection going.</p>
<p>
But it never necessarily coalesces into anything. You can chase the sunshine for years but find yourself at the end no closer to bottling it. I long had a feeling that organizers could do more to sustain the groups that came together to make their lovely conferences happen, to carry the feeling forward and create a community that cares for and sustains people through the year. But I&#39;d also think, almost scolding myself bitterly: of course that would be a tremendous commitment of time and money. It&#39;s so much to expect from anybody. Putting on this kind of event is already a monumental effort, who am I to ask for even more?</p>
<p>
Eventually I found an organization that offers more: the <a href="https://www.recurse.com/">Recurse Center</a>, a retreat for curious programmers in Brooklyn, New York. A lot of what I enjoyed there was familiar: tech talks, workshops, laptops, conference rooms, hallway encounters, coffee chats. But this group of people – especially the organizers – doubled and tripled down, went on a limb to make the investment, and coalesced the goodwill from teaching and learning and joyfully hacking into something that&#39;s demonstrated stability and community for over a decade through boom times and bust.</p>
<p>
It&#39;s been a little over three years since my time at the Recurse Center. I&#39;m still in regular touch with dozens of people I met there, actively participate in group chats, receive thoughtful personalized career advice, learning opportunities through pair-programming, and answers to technical questions. That&#39;s no accident: the retreat is designed to carry energy forward from one group to the next and provide indefinite support afterwards. What a delight.</p>
]]></content>
        </item>
        
        <item>
            <title>Yondergrove, Hedgerow Hall, and the Ideology of the Cozy Forest </title>
            <link>https://www.ryanprior.com/posts/yondergrove-hedgerow-hall-and-the-ideology-of-the-cozy-forest/</link>
            <pubDate>Sat, 28 May 2022 10:53:12 -0500</pubDate>
            
            <guid>https://www.ryanprior.com/posts/yondergrove-hedgerow-hall-and-the-ideology-of-the-cozy-forest/</guid>
            <description>&lt;p&gt;
“Yondergrove” (name has been changed; see below) is a fantasy roleplaying video game set amid great forests, lakes and rivers. Started in 2020, it is a public alpha that&amp;#39;s free to play, and caters to small-group roleplaying. There are no enemies to slay, no levels to gain, and no non-player characters to interact with. Like a game of make believe in the park, the narrative pace is entirely set by the players who show up and create a woodland creature character, fox or squirrel or what have you, to serve as their avatar.&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<p>
“Yondergrove” (name has been changed; see below) is a fantasy roleplaying video game set amid great forests, lakes and rivers. Started in 2020, it is a public alpha that&#39;s free to play, and caters to small-group roleplaying. There are no enemies to slay, no levels to gain, and no non-player characters to interact with. Like a game of make believe in the park, the narrative pace is entirely set by the players who show up and create a woodland creature character, fox or squirrel or what have you, to serve as their avatar.</p>
<p>
The game cites as its influences Redwall and Watership Down, stories I loved as a kid. But the first game to create an alchemy of these thematic elements, to which Yondergrove pays homage in almost every aspect of its implementation, is <a href="http://www.byond.com/games/Hedgemistress/HedgerowHall">Hedgerow Hall</a>. Created in 2002 by indie author and game designer <a href="http://www.alexandraerin.com/">Alexandra Erin</a>, then going under the pseudonym <a href="http://www.byond.com/members/Hedgemistress">Hedgemistress</a>, Hedgerow Hall imagined a <a href="https://en.wikipedia.org/wiki/Mud">MUD (multi-user dungeon)</a> which captured the spirit of camaraderie, exploration, struggle and intrigue of the anthropomorphic animal protagonists in the woodland fantasy genre.</p>
<p>
I read every Redwall book as a child, made the recipes generously included therein (well before they were published in <a href="https://www.goodreads.com/book/show/7989.The_Redwall_Cookbook">book form</a>,) and played Hedgerow Hall extensively. So I was thrilled to find the Yondergrove game and give it a try, joining the community for an evening of roleplaying adventure.</p>
<p>
Even with the game in its incomplete form, I found a lot of what I was expecting and remembered from my experience with Hedgerow Hall: player-run shops displaying all the bounties of the forest, cozy burrows open to all comers, a large community center, and a lively cast of woodland creatures to interact with, each playing out their own stories. But the vibes are off: despite its many surface-level similarities, the unfinished alpha of Yondergrove doesn&#39;t feel like the same sort of game, and thinking about why it felt that way has led me to a deeper&#39;n&#39;ever appreciation for the vision and mechanics of Hedgerow Hall and the ideology it presented as the underpinning of its cozy forest game aesthetic.</p>
<div id="outline-container-headline-1" class="outline-5">
<h5 id="headline-1">
Note: The Name of The Game
</h5>
<div id="outline-text-headline-1" class="outline-text-5">
<p>
I changed the game&#39;s name to “Yondergrove” in this piece in response to concern from a game developer that interested players might find it in their web searches and be prejudiced by this reflection on a single role-play session, a snapshot in time where the game is unfinished and its alpha community is very much still finding itself. If you play a game like Yondergrove, I hope you view it with fresh eyes and a critical mind, and bear always in mind that a roleplaying game is a beautiful dance between the players and the game rules.</p>
</div>
</div>
<div id="outline-container-headline-2" class="outline-3">
<h3 id="headline-2">
Immigration and Arrival
</h3>
<div id="outline-text-headline-2" class="outline-text-3">
<p>
In both games, your character arrives at the grand hall as a penniless immigrant. You choose which animal you want as your avatar, each with their own strengths and weaknesses which you can adjust with positive and negative traits to create a well-rounded character or a narrow savant. You wear only your fur and have neither tools nor weapons, nor a coin to your name. But here is where Yondergrove and Hedgerow Hall show their first significant divergence in vision.</p>
<p>
Hedgerow Hall puts forth a vision of abundance, in which the titular Hall provides a nurturing haven for immigrants to get them on their feet and on the path to independence. You can always return to the Hall for free meals and water (your character gets lethargic when hungry, but it is not possible to starve) and training in any skill of your choice by the Hall&#39;s many NPC tutors. There is a tutor of each animal type, ensuring that you always see a familiar face when you begin playing a character, and the different animals teach different skills, suggesting archetypes of skills that go together and capitalize on the signature strengths of each animal.</p>
<p>
Hedgerow Hall&#39;s generosity is not unlimited: you cannot ask for more than a few square meals per day, and your skill training is limited by the number of &#34;skill points&#34; you have available. You begin the game with a few dozen of these, and every hour or so of gameplay your points get replenished, whatever activities you chose to partake in during that time. With your initial allotment of skill points, you can choose to immediately become basically proficient in one or two skills of your choice, or you can gain a beginner&#39;s level in a handful of skills. If your idea of fun is to create a character who&#39;s scrappy and self-sufficient right off the bat, you might seek training in scrounging for food and climbing trees to avoid danger, and this is provided free of charge by the welcoming tutors of the Hall. Of if you desire a mystic&#39;s life, you can seek the skills to identify crystals from among rubble that can hold a magical charge, and to power them up with your own mind.</p>
<p>
Meanwhile, the vision of Yondergrove is of austerity and consumption. Its central structure is the image of cold neutrality: it offers no free meals except whatever is provided by players as charity, its halls are silent and empty unless players choose to actively loiter around for welcome duty, and it is likely that none of the characters you meet will be the same animal as yourself. The library is stacked high with skill training books, to which you can help yourself. But reading is a destructive act in Yondergrove: any time you read a book it is lost forever, and the library&#39;s stacks are finite. Unlike a public library, here there are no returns, and gaining proficiency in a skill requires destroying not just one book but many. Of course, this has been taken to its logical end in the game world: the library is barren of books on useful, popular subjects like scrounging for food, climbing trees, identifying minerals, or charging magical crystals. The books that remain are the unpopular ones: a stack of tomes on sword-fighting is over a hundred books high, because swords are hard to come by in this fantasy world of scarcity.</p>
</div>
</div>
<div id="outline-container-headline-3" class="outline-3">
<h3 id="headline-3">
Rent or Charity?
</h3>
<div id="outline-text-headline-3" class="outline-text-3">
<p>
The only way to learn any skill in the world of Yondergrove is to read skill books. You cannot learn by doing, or by watching another player. The objective of this design, as stated by the game&#39;s developers, is to create an in-game economic hierarchy between the new and established player where, if a new character wants to be able to do anything useful like scrounging for food, they must first ply the charity of another player who becomes their benefactor, or agree to pay rent in return for training in the form of consumable books.</p>
<p>
Some of these books may have been hoarded into private collections directly from the library: many books in player-run shops carry the iconic &#34;Complete Edition&#34; stamp which comes only from books found in the library or created by an established player with a complete mastery of the skill. Player-created books are made from scarce bark and ink by those with skill in writing and woodland-crafting.</p>
<p>
All of the skills necessary to bootstrap an economy, like making books, clothes, weapons or jewelry, are locked up behind counters in player-run shops. Every entry into the game is transactional, with the established properties providing some necessary resources on lease, extracting promises of future payback. Unlike in Hedgerow Hall, there is no subsistence in Yondergrove without debt.</p>
</div>
</div>
<div id="outline-container-headline-4" class="outline-3">
<h3 id="headline-4">
The Dignity of Animals
</h3>
<div id="outline-text-headline-4" class="outline-text-3">
<p>
Part of the joy of playing Hedgerow Hall was how each character would adhere to their animal archetype, or rebel against it. Rats were especially good at fighting, and many rat brigands (or body-guards) roamed the woods. Shrews were especially good at foraging and many a shrew&#39;s burrow was richly adorned with the fineries they would discover in the woods. Squirrels were able climbers, and it was not uncommon to spot a scurry of squirrels debating and snacking on nuts high up amid a stand of trees. The squirrel who could not climb, the shrew who could not provide for herself, and the weakling badger mystic were uncommon enough to be interesting outliers in their own right.</p>
<p>
In Yondergrove, squirrels who cannot climb are commonplace because climbing is a fun, useful, and popular skill, so all the climbing books are locked up in private collections. Rabbits who cannot provide for themselves are the norm, because books on scrounging are especially scarce and in-demand. A rat with competent sword-skill and a decent set of arms and armor would have to be deeply indebted to one or more entrenched players who could support all the expenses of such an endeavor. The animals of Yondergrove seemingly have none of the intrinsic dignity we as human players associate with their kind; or, more precisely, they have exactly as much dignity as they are able to purchase by taking on debt.</p>
</div>
</div>
<div id="outline-container-headline-5" class="outline-3">
<h3 id="headline-5">
Adventure, Exploration, and the Green Way
</h3>
<div id="outline-text-headline-5" class="outline-text-3">
<p>
The overall experience of playing Hedgerow Hall is that you can make your own way in the world by accepting a modest existence, or you can realize grand ambition by cooperating with the community of animals you find around you. You can range wide in exploration and interact infrequently with other animals, you can play a socialite, or anything in-between. The game design choices that made this possible were imposed in the form of a social compact followed by all players and enforced through a combination of role play, moderation, and the narrative design of the game world and interface.</p>
<p>
In terms of lore, the game provided an explicit designation for the social compact that it offered players. Why do tutors provide training free of charge? Why do even the cruelest of villains refuse to kill other characters, never even giving it a consideration? Why does the Hall provide square meals every day to the most saintly or most reviled of characters alike, no questions asked? Why do critters foraging for food in the woods never turn up insects, fish, snails or crabs? It&#39;s all because of the Green Way, the catch-all excuse to explain the social order, where all immigrants are owed autonomy and all animal life is to be respected.</p>
<p>
If Hedgerow Hall is the cozy woodland utopia of the Green Way, Yondergrove is the woodland dystopia without it. Like a vision of childhood fantasy seen through a glass darkly, it depicts the world of Redwall or Watership Down via the stunted politics of austerity and libertarianism, a secluded glen of interconnected animals each playing out the story of their lives as a rentier or an indentured worker.</p>
</div>
</div>
<div id="outline-container-headline-6" class="outline-3">
<h3 id="headline-6">
The Game is In Alpha
</h3>
<div id="outline-text-headline-6" class="outline-text-3">
<p>
Yondergrove reminds me in many small ways of the aesthetic and pace of Hedgerow Hall which I dearly miss, and the game is far from finished. I expect that its community will continue to grow and change, and that its many systems and mechanics will be overhauled as they work to find and sustain a dedicated player base for the long term.</p>
<p>
I&#39;m excited to see the direction that the Yondergrove team takes the game from here. What they have built has already given me a much deeper appreciation for the particular elements that gave Hedgerow Hall its legendary vibes and its charm. I&#39;m grateful for the opportunity to luxuriate in the memory of my favorite Hedgerow Hall stories of old, and I will return to see how progress is coming.</p>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>What Is Guix Really? </title>
            <link>https://www.ryanprior.com/posts/what-is-guix-really/</link>
            <pubDate>Sun, 17 Jan 2021 00:10:22 -0600</pubDate>
            
            <guid>https://www.ryanprior.com/posts/what-is-guix-really/</guid>
            <description>&lt;blockquote&gt;
&lt;p&gt;an advanced distribution of the GNU operating system&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;‑ the &lt;a href=&#34;https://guix.gnu.org/&#34;&gt;GNU Guix&lt;/a&gt; website&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a purely functional package manager, and associated free software distribution&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;‑ the &lt;a href=&#34;https://www.reddit.com/r/guix&#34;&gt;Guix subreddit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
I find these descriptions uninspiring and &lt;strong&gt;wouldn&amp;#39;t be so excited&lt;/strong&gt; about Guix if that&amp;#39;s really all it was. So what is Guix really, how does it relate to these descriptions, and what makes it so compelling and different?&lt;/p&gt;
&lt;br/&gt;
&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-3&#34;&gt;
&lt;h3 id=&#34;headline-1&#34;&gt;
Guix is a Universal Software Deployment System
&lt;/h3&gt;
&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-3&#34;&gt;
&lt;p&gt;
Guix puts software and data onto computers, following your plan. In that sense, its closest competitors might be Ansible, Chef, or Docker. But it&amp;#39;s a more useful and capable technology than any of those because its underlying model is so expressive. It provides a collection of composable building blocks to create and organize systems of any complexity and deploy them to any computer, all using declarative code.&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<blockquote>
<p>an advanced distribution of the GNU operating system</p>
</blockquote>
<p>‑ the <a href="https://guix.gnu.org/">GNU Guix</a> website</p>
<blockquote>
<p>a purely functional package manager, and associated free software distribution</p>
</blockquote>
<p>‑ the <a href="https://www.reddit.com/r/guix">Guix subreddit</a></p>
<p>
I find these descriptions uninspiring and <strong>wouldn&#39;t be so excited</strong> about Guix if that&#39;s really all it was. So what is Guix really, how does it relate to these descriptions, and what makes it so compelling and different?</p>
<br/>
<div id="outline-container-headline-1" class="outline-3">
<h3 id="headline-1">
Guix is a Universal Software Deployment System
</h3>
<div id="outline-text-headline-1" class="outline-text-3">
<p>
Guix puts software and data onto computers, following your plan. In that sense, its closest competitors might be Ansible, Chef, or Docker. But it&#39;s a more useful and capable technology than any of those because its underlying model is so expressive. It provides a collection of composable building blocks to create and organize systems of any complexity and deploy them to any computer, all using declarative code.</p>
<div id="outline-container-headline-2" class="outline-4">
<h4 id="headline-2">
Uniform
</h4>
<div id="outline-text-headline-2" class="outline-text-4">
<p>
When you run software with Guix you take total control over the <em>how</em> and <em>where</em>, without having to use different tools and processes depending on your choice. You can run software normally on your machine, or in a container, in a virtual machine, on some other machine, or across a cluster of remote machines, by providing different configurations. And when you change your mind as the situation evolves, the tool follows.</p>
<p>
Containers &amp; VMs are truly optional in Guix. The reproducibility of your deployments does not rely on containerizing or virtualizing every application, so the decision of whether to run uncontained on bare metal, in a container, or virtualized, is up to your choice rather than being imposed upon you by the platform.</p>
</div>
</div>
<div id="outline-container-headline-3" class="outline-4">
<h4 id="headline-3">
Scalable
</h4>
<div id="outline-text-headline-3" class="outline-text-4">
<p>
Guix is comfortable at any scale. While it can deploy systems across a whole cluster, it&#39;s just as easy on a single-user machine. This doesn&#39;t require simulating a cluster or installing a stripped-down mini version of the software, because Guix only loads the building blocks you need to operate at the scale you ask for.</p>
<p>
You can use Guix to deploy your developer tools like <code>vim</code> and <code>git</code> onto your own machine. That&#39;s where the comparisons of Guix to a &#34;package manager&#34; come from: installing software on your own machine is just as easy as with <code>apt</code> or <code>brew</code>, just <code>guix install vim</code> and you&#39;re set. But with a little more configuration, it can also deploy a complex service, eg. Ruby + Rails + Postgres + nginx. Or it can deploy an entire operating system on a single computer or on a whole clusters of machines. You scale-up by providing a configuration that invokes more components of Guix, activating them to orchestrate deployment on whatever scale you care about in the scenario.</p>
<p>
Guix views an operating system as just a big collection of software and data, organized into services. Just as you can deploy a single service on your computer, you can scale that up and deploy the whole set of them that comprises an operating system. The <a href="https://guix.gnu.org/manual/en/html_node/System-Installation.html#System-Installation">Guix System</a> is a full ready-to-use operating system defined entirely using Guix in terms of software packages and services, and you can use it as a template to deploy any kind of operating system you can imagine. This is where the descriptions of Guix as a &#34;distribution&#34; come from: because Guix is so powerful and general, you can use it in place of a traditional operating system distro.</p>
</div>
</div>
<div id="outline-container-headline-4" class="outline-4">
<h4 id="headline-4">
Reproducible
</h4>
<div id="outline-text-headline-4" class="outline-text-4">
<p>
Using Guix to deploy your software helps make it resistant to bitrot, configuration drift, and all the forces of entropy. That&#39;s because every build, deploy, and configuration using Guix is designed to be byte-for-byte reproducible, and it automates the creation of detailed provenance files describing the names, versions, and configurations of every single piece of software that&#39;s part of the deployed system.</p>
<p>
Once you get software working on your own machine, you want to ship it to other machines and be able to trust it&#39;ll work there too. Guix makes that realistic. It isolates packages and builds from the host system and from one another so they don&#39;t interact in any ways you don&#39;t define explicitly. It can also create pure isolated execution environments for development and testing to help you ensure that your software will work the same wherever it&#39;s deployed.</p>
<p>
Many language ecosystems also to go great lengths to deliver this same sort of experience. But Guix does it in a way that is independent of languages or build tool and spans the full stack. Often the odd dependencies become the trickiest part of installation and deployment, but because Guix is universal it tackles the whole problem with one tool set.</p>
</div>
</div>
<div id="outline-container-headline-5" class="outline-4">
<h4 id="headline-5">
Extensible
</h4>
<div id="outline-text-headline-5" class="outline-text-4">
<p>
These capabilities arise from a design which uses a collection of composable building blocks to create systems of any desired scale and complexity. You can reuse them as a library and extend them with your own blocks to create new ways of describing and deploying systems. For example, the <a href="https://www.guixwl.org/">Guix Workflow Language</a> extends Guix with tools for managing scientific data workflows.</p>
<p>
Guix is totally programmable and fully compatible with infrastructure-as-code. The definition for every object in Guix, from an <code>origin</code> (describing the location and metadata of some source code) to a <code>package</code>, <code>service</code>, or <code>operating-system</code>, is all just code. We provide a rich set of domain-specific languages for writing declarative descriptions, which you can extend with your own logic.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-6" class="outline-3">
<h3 id="headline-6">
Guix Makes Many Software Problems Optional
</h3>
<div id="outline-text-headline-6" class="outline-text-3">
<p>
The uniformity and expressiveness of Guix allow you to avoid entire classes of problems with software deployment that we typically use a collection of tools to handle.</p>
<div id="outline-container-headline-7" class="outline-4">
<h4 id="headline-7">
Fetch and manage versions of your runtimes and dependencies
</h4>
<div id="outline-text-headline-7" class="outline-text-4">
<p>
If you use Ruby you might be familiar with <code>rvm</code>, <code>gem</code>, and <code>bundler</code>, the tools for managing installed versions of Ruby, fetching Ruby libraries, and collecting sets of Ruby libraries that comprise the dependencies for a service, respectively. If you also use Python you might be familiar with <code>pyenv</code>, <code>pip</code>, and <code>pipenv</code>, which perform the same functions for Python. In general, we might say that if you use <code class="verbatim">N</code> languages, you likely use some multiple of <code class="verbatim">N</code>, <code class="verbatim">N×C</code>, language-specific tools to manage the tools and libraries you use.</p>
<p>
Guix replaces all these tools. It can fetch the version of the compilers and language runtime you want and all your dependencies, and it can provide a file describing the complete provenance of that software, comparable to a lockfile. And even better, you&#39;re free to use a single manifest and lockfile to describe all the runtimes, dev tools, and dependencies for your project, no matter how many language ecosystems they span.</p>
</div>
</div>
<div id="outline-container-headline-8" class="outline-4">
<h4 id="headline-8">
Avoid version conflicts
</h4>
<div id="outline-text-headline-8" class="outline-text-4">
<p>
If you run many versions of a service on your local machine, you may be familiar with tools like <code>bundler</code>, <code>virtualenv</code>, and <code>docker</code> which allow you to create separate, disjoint environments for each version of the service to avoid conflicting versions of dependencies. Dependency conflicts happen when many different pieces of code want to have the same name on your system. These listed tools avoid conflicts by creating many copies of your dependencies in different folders for each project.</p>
<p>
Guix sidesteps this problem entirely by addressing every package and every file using unique hashes instead of potentially-conflicting global names. It doesn&#39;t need to make a copy for every project, because each version you want has a globally unique name you can depend upon directly. You won&#39;t need to type those hashes or hard-code them into your scripts or other build tools, because Guix provides hooks to set environment variables similar to how the above version management tools work.</p>
</div>
</div>
<div id="outline-container-headline-9" class="outline-4">
<h4 id="headline-9">
Treat deployment problems as optional
</h4>
<div id="outline-text-headline-9" class="outline-text-4">
<p>
Guix doesn&#39;t try to forbid you from using these tools you might be familiar with. It&#39;ll happily install them for you. But wouldn&#39;t it be nice to treat these tools as viable solutions to an optional problem, a software deployment wrinkle that you can opt-out of if it becomes too complex? Using Guix gives you the freedom to make the best technical decisions about how to manage your dependencies without feeling forced to use all these language-specific tools out of necessity.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-10" class="outline-3">
<h3 id="headline-10">
Guix is Radically Free
</h3>
<div id="outline-text-headline-10" class="outline-text-3">
<p>
Every part of Guix is free software according to the <a href="https://www.gnu.org/philosophy/free-sw.html.en">Free Software Definition</a>, and the Guix project as a whole meets the much higher standards of the <a href="https://www.gnu.org/distros/free-system-distribution-guidelines.html">Free System Distribution Guidelines</a>. Beyond that, the design of Guix is carefully thought-out to help you make practical use of your freedom.</p>
<div id="outline-container-headline-11" class="outline-4">
<h4 id="headline-11">
Take control of your upgrade cycle
</h4>
<div id="outline-text-headline-11" class="outline-text-4">
<p>
Guix never requires you to upgrade the version of a package system-wide just to deploy some other package. You can choose to keep some packages extremely stable and update them on a slow regular cadence, while deploying bleeding edge versions of others, and it won&#39;t cause you any hassle.</p>
<p>
You aren&#39;t restricted to the versions of packages provided by the Guix upstream project. When deploying software you can always specify a specific version, tag, branch, commit hash, or even provide your own patches.</p>
<p>
Guix puts you totally in control of what you deploy, so you don&#39;t need to upgrade when a distro maintainer says it&#39;s time or wait for them to provide a new version you want to use.</p>
</div>
</div>
<div id="outline-container-headline-12" class="outline-4">
<h4 id="headline-12">
Bring your own libraries, tools, and other software
</h4>
<div id="outline-text-headline-12" class="outline-text-4">
<p>
You can add definitions for your own internal packages, services, and operating systems to Guix. These do not have second-class status: they get all the same powers, bells and whistles as what you get from Guix upstream. You can add one or more internal <a href="https://guix.gnu.org/manual/en/html_node/Channels.html">channels</a> to your Guix configuration to extend it in any way you like. You can also <a href="https://guix.gnu.org/manual/en/html_node/Creating-a-Channel.html">publish a channel</a> to your organization or to the world.</p>
<p>
The Guix project does not maintain any kind of gatekeeper role. While Guix itself is radically free, we pass that freedom on to you in its entirety to be a full member of our ecosystem and publish any software using any business model, licenses and terms you deem appropriate.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-13" class="outline-3">
<h3 id="headline-13">
So That&#39;s What Guix Is!
</h3>
<div id="outline-text-headline-13" class="outline-text-3">
<p>
The Guix project is backed by a non-profit foundation and maintained entirely by volunteers. It has no backing from venture capital, no enterprise product, and no advertising. If you want to see it grow and succeed at bringing universal deployment to the whole world, please consider <a href="https://guix.gnu.org/en/contribute/">contributing your skills</a> in one of the <a href="https://guix.gnu.org/en/contribute/">many areas we need help</a>, or <a href="https://guix.gnu.org/en/donate/">making a donation</a> to the project!</p>
<div id="outline-container-headline-14" class="outline-4">
<h4 id="headline-14">
More resources
</h4>
<div id="outline-text-headline-14" class="outline-text-4">
<ul>
<li>You can <a href="https://guix.gnu.org/en/download/">download Guix here</a>.</li>
<li>There&#39;s a big list of examples and things to try at the <a href="https://guix.gnu.org/cookbook/en/guix-cookbook.html">Guix Cookbook</a>.</li>
<li>You can <a href="https://guix.gnu.org/en/contact/">get in touch with the Guix community</a> via <a href="https://guix.gnu.org/en/contact/irc/">IRC</a> at <code class="verbatim">#guix</code> on Freenode, via <a href="https://guix.gnu.org/en/contact/">email</a>, or in <a href="https://app.element.io/#/room/#guix:matrix.org">Matrix chat</a> at <code class="verbatim">guix:matrix.org</code>.</li>
<li>Not many commercial hosting services have built-in support for Guix deployment yet. You can install Guix onto any distribution and deploy there, but if you want to try a provider that supports Guix natively, check out <a href="https://capsul.org/">Capsul</a>.</li>
</ul>
</div>
</div>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>How to try out somebody&#39;s Guix package </title>
            <link>https://www.ryanprior.com/posts/try-guix-package/</link>
            <pubDate>Sat, 26 Dec 2020 14:16:33 -0600</pubDate>
            
            <guid>https://www.ryanprior.com/posts/try-guix-package/</guid>
            <description>&lt;p&gt;
The &lt;a href=&#34;https://repology.org/repository/gnuguix&#34;&gt;GNU Guix package ecosystem&lt;/a&gt; is growing rapidly, and given all of the &lt;a href=&#34;https://guix.gnu.org/manual/en/html_node/Features.html&#34;&gt;amazing features&lt;/a&gt; Guix delivers, I always check Guix first to see if the software I want is available.&lt;/p&gt;
&lt;p&gt;
When it&amp;#39;s not, there&amp;#39;s still a possibility that a search will reveal somebody else has packaged what I want. For example, I share &lt;a href=&#34;https://github.com/ryanprior/guix-packages#testing-&#34;&gt;packages that I&amp;#39;m testing&lt;/a&gt; before I submit them upstream. Downloading a package definition to test it out on your machine is easy, but there are some tricks. It took me a while to figure out what to do, and I see other people get confused regularly due to unfortunate decisions in Guix&amp;#39;s design. So here&amp;#39;s a guide to get you on the right path.&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<p>
The <a href="https://repology.org/repository/gnuguix">GNU Guix package ecosystem</a> is growing rapidly, and given all of the <a href="https://guix.gnu.org/manual/en/html_node/Features.html">amazing features</a> Guix delivers, I always check Guix first to see if the software I want is available.</p>
<p>
When it&#39;s not, there&#39;s still a possibility that a search will reveal somebody else has packaged what I want. For example, I share <a href="https://github.com/ryanprior/guix-packages#testing-">packages that I&#39;m testing</a> before I submit them upstream. Downloading a package definition to test it out on your machine is easy, but there are some tricks. It took me a while to figure out what to do, and I see other people get confused regularly due to unfortunate decisions in Guix&#39;s design. So here&#39;s a guide to get you on the right path.</p>
<div id="outline-container-headline-1" class="outline-4">
<h4 id="headline-1">
First, a warning
</h4>
<div id="outline-text-headline-1" class="outline-text-4">
<p>
Guix packages look a lot like data, since they mostly consist of URLs and descriptions and so on. But don&#39;t be fooled! Packages are code, and building a package runs arbitrary code on your computer. A malicious package can do dastardly things. So don&#39;t run packages from people you don&#39;t trust unless you&#39;ve inspected them yourself and gain some understanding of what they&#39;re doing.</p>
</div>
</div>
<div id="outline-container-headline-2" class="outline-3">
<h3 id="headline-2">
The Guile load path
</h3>
<div id="outline-text-headline-2" class="outline-text-3">
<p>
Guix discovers what packages exist by loading all the Guile code on its <code>guile-load-path</code> and collecting package definitions. That means you can add new packages just by adding files that define them to your Guix load path.</p>
<p>
Here&#39;s an example using my repository:</p>
<div class="src src-bash">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>  git clone https://github.com/ryanprior/guix-packages.git
</span></span><span style="display:flex;"><span>  cd guix-packages
</span></span><span style="display:flex;"><span>  guix environment -L. --ad-hoc countdown -- countdown 10s</span></span></code></pre></div>
</div>
<p>
To break it down:</p>
<div id="outline-container-headline-3" class="outline-4">
<h4 id="headline-3">
Cloning a repository
</h4>
<div id="outline-text-headline-3" class="outline-text-4">
<p>People often put Guix packages in a git repository. Cloning the whole repository is often the most convenient way to get access to those packages. Sometimes one file will refer to things defined in another, and by getting the whole repository you have a better chance to make sure you have everything that&#39;s needed, with the right directory structure.</p>
<p>
If you don&#39;t have Git installed yet, run <code>guix install git</code> before you start.</p>
</div>
</div>
<div id="outline-container-headline-4" class="outline-4">
<h4 id="headline-4">
Using <code>guix environment</code> with the -L flag
</h4>
<div id="outline-text-headline-4" class="outline-text-4">
<p>
The <code>guix environment</code> command creates a subshell with new Guix packages added to its environment, without making any changes to your profile. This makes it great for trying things out.</p>
<p>
With each use of the <code>-L</code> flag, Guix will add an additional path to its Guile load path, allowing it to find more packages. So invoking <code>environment</code> with <code>-L.</code> instructs Guix to look in the current directory (called <code>.</code>) for packages.</p>
<p>
Everything after the <code>--</code> in the command is run inside the subshell. So when we put together the pieces, the command looks in all of Guix plus the current directory for a package called &#34;countdown,&#34; adds it to the environment of a subshell, runs &#34;countdown 10s&#34; inside that subshell, and exits. If you want to interact with the subshell directly, you can omit the <code>-- countdown 10s</code> portion entirely:</p>
<pre class="example">
  ~/guix-packages$ countdown
  countdown: command not found
  ~/guix-packages$ guix environment -L. --ad-hoc countdown
  ~/guix-packages$ type countdown
  countdown is /gnu/store/w0gy4d14b2byir64jakpsrw3j73n916a-profile/bin/countdown
  ~/guix-packages$ exit
  ~/guix-packages$ type countdown
  bash: type: countdown: not found
</pre>
</div>
</div>
<div id="outline-container-headline-5" class="outline-4">
<h4 id="headline-5">
Troubleshooting
</h4>
<div id="outline-text-headline-5" class="outline-text-4">
<p>
This method is <em>very sensitive</em> to the current working directory, which is the directory you run the <code>guix</code> command from. For example, if I run the same <code>guix environment</code> command above inside the <code class="verbatim">guix-packages/testing</code> directory, I get a ton of warnings and then an error message:</p>
<pre class="example">
# […lots of warnings]
guix environment: warning: failed to load &#39;(vlang)&#39;:
no code for module (vlang)
./vlang.scm:4:0: warning: module name (testing vlang) does not match file name &#39;vlang.scm&#39;
hint: File `./vlang.scm&#39; should probably start with:

     (define-module (vlang))

guix environment: error: countdown: unknown package
</pre>
<p>
If you run <code>guix environment</code> in the parent directory of <code class="verbatim">guix-packages</code>, it will first of all take ages as it tries to search every subdirectory for Scheme files, and then it will also print an error and not give you what you want.</p>
<p>
Ugh! There&#39;s no way to make this work other than to ensure and triple-check you&#39;re in the exact right directory. If you&#39;re troubleshooting, you can try a few different directories and see if you hit on the right one. You can also look at the <code>module</code> definition for clues. For example, at the top of <code class="verbatim">testing/countdown.scm</code> we see:</p>
<div class="src src-scheme">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>  (<span style="color:#a6e22e">define-module</span> (<span style="color:#a6e22e">testing</span> countdown)
</span></span><span style="display:flex;"><span>   <span style="color:#75715e">;; snip</span>
</span></span><span style="display:flex;"><span>  )</span></span></code></pre></div>
</div>
<p>
The clue this gives you is that this file expects to be found at <code class="verbatim">./testing/countdown.scm</code>, and thus it expects you to run Guix with a Guile load path that has <em>not</em> its directory, but that directory&#39;s parent.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-6" class="outline-3">
<h3 id="headline-6">
The <code>-f</code> flag
</h3>
<div id="outline-text-headline-6" class="outline-text-3">
<p>
If you have a single file that defines a package of interest, you can use the <code>-f</code> flag to refer to the package it evaluates to. But you have to take care that the file actually <em>evaluates to</em> the desired package and doesn&#39;t merely <em>define</em> it.</p>
<p>
For example, in my <code class="verbatim">guix-packages</code> repository, the <code class="verbatim">countdown.scm</code> file has a structure like this:</p>
<div class="src src-scheme">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>  (<span style="color:#a6e22e">define-module</span> (<span style="color:#a6e22e">testing</span> countdown) <span style="color:#960050;background-color:#1e0010">…</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">define-public</span> countdown
</span></span><span style="display:flex;"><span>    (<span style="color:#a6e22e">package</span>
</span></span><span style="display:flex;"><span>      (<span style="color:#a6e22e">name</span> <span style="color:#e6db74">&#34;countdown&#34;</span>)
</span></span><span style="display:flex;"><span>      <span style="color:#960050;background-color:#1e0010">…</span>))</span></span></code></pre></div>
</div>
<p>
What&#39;s important to note is that the last form of the file is a <code>(define-public)</code> form, which does not have any return value. A file evaluates to the return value of its last form, so while this file <em>defines</em> the <code class="verbatim">countdown</code> package, it <em>evaluates</em> to nothing. So if you run <code>guix build -f countdown.scm</code> it will give you an error message like so:</p>
<pre class="example">
~/guix-packages/testing$ guix build -f countdown.scm 
guix build: error: #&lt;unspecified&gt;: not something we can build

hint: If you build from a file, make sure the last Scheme expression returns a package value.  `define-public&#39; defines a variable, but returns `#&lt;unspecified&gt;&#39;.  To fix this, add a Scheme
expression at the end of the file that consists only of the package&#39;s variable name you defined, as in this example:

     (define-public my-package
       (package
         ...))
     
     my-package
</pre>
<p>
If you edit <code class="verbatim">countdown.scm</code> to put a new line at the end that just says <code>countdown</code>, then Guix will build the package:</p>
<pre class="example">
  ~/dev/guix-packages/testing$ cat &gt;&gt;countdown.scm

  countdown
  ~/dev/guix-packages/testing$ guix build -f countdown.scm 
  /gnu/store/6x2lmakp59vzdjbjqxha2560g2jrqdyv-countdown-1.0.0
</pre>
<p>
Now the <code class="verbatim">countdown</code> executable is available in the listed directory, and we can start a 10 second countdown like so:</p>
<pre class="example">
~/dev/guix-packages/testing$ /gnu/store/6x2lmakp59vzdjbjqxha2560g2jrqdyv-countdown-1.0.0/bin/countdown 10s
</pre>
<div id="outline-container-headline-7" class="outline-4">
<h4 id="headline-7">
What if I want <code>guix environment</code>?
</h4>
<div id="outline-text-headline-7" class="outline-text-4">
<p>
We love <code>guix environment</code>! But Guix does not provide us any easy way to use a file with <code>environment</code>. The <code>-f</code> flag that is available on many other commands is not defined for <code>environment</code>. However, with another silly workaround we can make this work.</p>
<p>
Instead of putting a line with <code>countdown</code> at the end of <code class="verbatim">countdown.scm</code>, we can make it evaluate to a trivial wrapper around <code>countdown</code>:</p>
<div class="src src-scheme">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-scheme" data-lang="scheme"><span style="display:flex;"><span>  <span style="color:#75715e">;; …rest of countdown.scm</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">package</span>
</span></span><span style="display:flex;"><span>    (<span style="color:#a6e22e">inherit</span> countdown)
</span></span><span style="display:flex;"><span>    (<span style="color:#a6e22e">inputs</span> <span style="color:#f92672">`</span>((<span style="color:#e6db74">&#34;countdown&#34;</span> <span style="color:#f92672">,</span>countdown))))</span></span></code></pre></div>
</div>
<p>
Now we can use <code>guix environment</code> again:</p>
<pre class="example">
  ~/guix-packages/testing$ guix environment -l countdown.scm 
  ~/guix-packages/testing$ type countdown
  countdown is /gnu/store/4gc33v065h1hm0lq42j1fir7gs151j9s-profile/bin/countdown
</pre>
<p>
Note that we are using <code>-l</code> (lower case L) and <em>not</em> the <code>-L</code> flag we were using before. This does not modify the Guile load path. Instead of creating an environment containing the package the file evaluates to, it creates an environment with the <em>dependencies</em> of that package. This is why we have to create that trivial wrapper which adds countdown as a dependency.</p>
<p>
Note that while this method is fiddly in many ways, it is not so dependent as the last one on having everything in exactly the right directory structure and being in the exact right directory when you run your Guix command.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-8" class="outline-3">
<h3 id="headline-8">
Epilogue: any easy, worry-free way to try people&#39;s Guix packages?
</h3>
<div id="outline-text-headline-8" class="outline-text-3">
<p>
The currently available methods for testing a Guix package you find on the Internet are fraught with thorns and pitfalls for the unwary. This can give an overall unfriendly feeling to newcomers.</p>
<p>
Suppose we were to come upon a clearing in the thicket where some hackers were having a merry potluck, where everybody brought their packages to try and there was a friendly uniform mechanism to try and share these packages?</p>
<p>
Such a tool was proposed: <a href="https://issues.guix.gnu.org/26645">Guix Potluck</a> was submitted in 2017 to address this kind of use case. It never got a public release, but there may be lessons there for a hypothetical future tool that could make guides like this one obsolete.</p>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>The Context of Software Freedom </title>
            <link>https://www.ryanprior.com/posts/the-context-of-software-freedom/</link>
            <pubDate>Wed, 03 Jun 2020 22:31:52 -0500</pubDate>
            
            <guid>https://www.ryanprior.com/posts/the-context-of-software-freedom/</guid>
            <description>&lt;p&gt;
Earlier today I learned the dismaying news that one of my friends in Free
software was shot by police with a less-than-lethal round and assaulted with
chemical weapons. While recovering at home, they warned me to be careful.
Another friend in our group chat asked: is this group also about defunding and
eliminating the police?&lt;/p&gt;
&lt;p&gt;
I see software freedom as a necessary part of a larger human freedom project,
which is incomplete without abolition of prisons, jails, police, and the system
of oppression they exist to uphold. Not every hacker or software project or
social group needs to be focused on that, but this reiterates the difference
between open source and Free software: open source is a technical and economic
project with a vision of better software and fewer restrictions on programmers,
while Free software is a political project with a vision of freedom for
humankind.&lt;/p&gt;</description>
            <content type="html"><![CDATA[<p>
Earlier today I learned the dismaying news that one of my friends in Free
software was shot by police with a less-than-lethal round and assaulted with
chemical weapons. While recovering at home, they warned me to be careful.
Another friend in our group chat asked: is this group also about defunding and
eliminating the police?</p>
<p>
I see software freedom as a necessary part of a larger human freedom project,
which is incomplete without abolition of prisons, jails, police, and the system
of oppression they exist to uphold. Not every hacker or software project or
social group needs to be focused on that, but this reiterates the difference
between open source and Free software: open source is a technical and economic
project with a vision of better software and fewer restrictions on programmers,
while Free software is a political project with a vision of freedom for
humankind.</p>
<p>
Free software is hollow if it isn&#39;t also about defunding and eliminating the
police.</p>
]]></content>
        </item>
        
        <item>
            <title>Changing power settings in elementary OS</title>
            <link>https://www.ryanprior.com/posts/changing-power-settings-in-elementary-os/</link>
            <pubDate>Sat, 09 May 2020 15:40:24 -0500</pubDate>
            
            <guid>https://www.ryanprior.com/posts/changing-power-settings-in-elementary-os/</guid>
            <description>&lt;p&gt;
The &lt;a href=&#34;https://webchat.freenode.net/#elementary&#34;&gt;#elementary channel on Freenode&lt;/a&gt; got an interesting question today:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How can one change the Suspend / Turn off screen settings to interval smaller
than 5 minutes ie. turn off screen after 1 minute and suspend the laptop after 2
minutes when idle?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Despite spending a lot of time working on elementary OS I don&amp;#39;t know the answer, so I start with the power menu.&lt;/p&gt;
&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-3&#34;&gt;
&lt;h3 id=&#34;headline-1&#34;&gt;
Power settings
&lt;/h3&gt;
&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-3&#34;&gt;
&lt;p&gt;
⌘+Space opens the elementary applications menu:&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<p>
The <a href="https://webchat.freenode.net/#elementary">#elementary channel on Freenode</a> got an interesting question today:</p>
<blockquote>
<p>How can one change the Suspend / Turn off screen settings to interval smaller
than 5 minutes ie. turn off screen after 1 minute and suspend the laptop after 2
minutes when idle?</p>
</blockquote>
<p>
Despite spending a lot of time working on elementary OS I don&#39;t know the answer, so I start with the power menu.</p>
<div id="outline-container-headline-1" class="outline-3">
<h3 id="headline-1">
Power settings
</h3>
<div id="outline-text-headline-1" class="outline-text-3">
<p>
⌘+Space opens the elementary applications menu:</p>
<figure>
<img src="/elementary-power/menu-search.png" alt="/elementary-power/menu-search.png" title="/elementary-power/menu-search.png" /><figcaption>
Searching in the elementary Applications menu for &#34;power&#34; settings.
</figcaption>
</figure>
<p>
This menu controls all the power settings for the desktop. It&#39;s part of a set of elementary components called <a href="https://github.com/elementary/switchboard">Switchboard</a>. I&#39;m looking for an option here to turn the screen after 1 minute.</p>
<figure>
<img src="/elementary-power/power-dialog.png" alt="/elementary-power/power-dialog.png" title="/elementary-power/power-dialog.png" /><figcaption>
The minimum interval is 5 minutes.
</figcaption>
</figure>
<p>
No such option. I dig deeper and try to find out how Switchboard manages power settings and see if that leads me to a workaround.</p>
</div>
</div>
<div id="outline-container-headline-2" class="outline-3">
<h3 id="headline-2">
Use the source
</h3>
<div id="outline-text-headline-2" class="outline-text-3">
<p>
Every piece of the elementary OS desktop is free software, which means its source code is available for the community to study, change, and re-use. I don&#39;t know how the Switchboard power menu works, so I&#39;m going to study the source code to find out.</p>
<div id="outline-container-headline-3" class="outline-4">
<h4 id="headline-3">
Finding the source code for power settings
</h4>
<div id="outline-text-headline-3" class="outline-text-4">
<p>
The elementary project has a <a href="https://github.com/elementary">page on GitHub</a> where I can search for components:</p>
<figure>
<img src="/elementary-power/elementary-GitHub.png" alt="elementary GitHub" title="/elementary-power/elementary-GitHub.png" class="matted"/>
<figcaption>
Visiting elementary&#39;s GitHub organization in the Epiphany web browser
</figcaption>
</figure>
<p>
Scrolling down, there&#39;s a search box for repositories. I try typing &#34;power&#34; to see what comes up:</p>
<figure>
<img src="/elementary-power/search-GitHub-for-power.png" alt="found switchboard-plug-power" title="found switchboard-plug-power" class="matted"/>
<figcaption>
Searching elementary repositories for &#34;power&#34;
</figcaption>
</figure>
<p>
This is the repository where the source code for the power settings is stored. I browse a few files in the repository, looking for the key phrase &#34;Turn off display&#34; which is found in the settings menu:</p>
<figure>
<img src="/elementary-power/power-label.png" alt="main view source code" title="main view source code" class="matted"/>
<figcaption>
I found the <code>screen_timeout_label</code> in <code>MainView</code>
</figcaption>
</figure>
<p>
Now I know there&#39;s a component called <code>screen_timeout</code> which we manipulate when we touch the control with that label. But what does it actually do to change the power settings when we select a different option?</p>
</div>
</div>
<div id="outline-container-headline-4" class="outline-4">
<h4 id="headline-4">
Understanding the power settings method of action
</h4>
<div id="outline-text-headline-4" class="outline-text-4">
<p>
I search for &#34;screen_timeout&#34; and scan through the results until I see one that says &#34;connect,&#34; suggesting that this is where the settings panel connects to another component that takes action to change settings. The name of this component is <code>dpms_helper</code>.</p>
<p>
Back to the elementary GitHub organization! Now I&#39;m looking for the dpms helper to dig further.</p>
<figure>
<img src="/elementary-power/search-GitHub-for-dpms.png" alt="search &#34;dpms&#34;" title="search &#34;dpms&#34;" class="matted"/>
<figcaption>
Searching elementary repositories for &#34;dpms&#34;
</figcaption>
</figure>
<p>
This repository has the source code for <code>dpms-helper</code>, the tool that I found out Switchboard uses to act on our power settings preferences. How does it work? I search around in its source code and soon find that it&#39;s executing another program called <code>xset</code>:</p>
<figure>
<img src="/elementary-power/dpms-helper-src.png" alt="execute xset dpms" title="execute xset dpms" class="matted"/>
<figcaption>
<code>dpms-helper</code> in turn executes <code>xset dpms</code>
</figcaption>
</figure>
<p>
How can we use <code>xset</code> to achieve the desired goal of turning our screen off after a short time-interval? Now that I know what to look for, let&#39;s see what the system manual has to say:</p>
<figure>
<img src="/elementary-power/man-xset-dpms.png" alt="man xset" title="man xset" class="matted"/>
<figcaption>
Searching the system manual for more information.
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-5" class="outline-3">
<h3 id="headline-5">
Solutions &amp; recap
</h3>
<div id="outline-text-headline-5" class="outline-text-3">
<p>
I set out to find out how to set short intervals for power management: 1 minute before turning off the screen, and 2 minutes before suspending. The search took me through:</p>
<ul>
<li>The applications menu and power settings menu</li>
<li>The elementary project&#39;s GitHub repositories</li>
<li>Source code for Switchboard and <code>dpms-helper</code></li>
<li>The system manual</li>
</ul>
<p>After researching the method of action, I can answer the original question like so:</p>
<div class="src src-bash">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># power settings: standby after 2 minutes, never suspend,</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># and screen off after 1 minute.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># `xset dpms` takes arguments in seconds, in that order.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>standby_seconds<span style="color:#f92672">=</span><span style="color:#66d9ef">$((</span><span style="color:#f92672">(</span><span style="color:#ae81ff">2</span><span style="color:#f92672">*</span><span style="color:#ae81ff">60</span><span style="color:#66d9ef">))</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>screen_off_seconds<span style="color:#f92672">=</span><span style="color:#66d9ef">$((</span><span style="color:#f92672">(</span><span style="color:#ae81ff">1</span><span style="color:#f92672">*</span><span style="color:#ae81ff">60</span><span style="color:#66d9ef">))</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>xset dpms $standby_seconds <span style="color:#ae81ff">0</span> $screen_off_seconds</span></span></code></pre></div>
</div>
<div id="outline-container-headline-6" class="outline-4">
<h4 id="headline-6">
Even better using <code>dpms-helper</code>
</h4>
<div id="outline-text-headline-6" class="outline-text-4">
<p>
The above solution works, but it has two shortcomings:</p>
<ol>
<li>It doesn&#39;t put our settings anywhere that other applications (like Switchboard) can find out about them</li>
<li>It uses a lower-level tool, <code>xset</code>, instead of a standard platform tool.</li>
</ol>
<p>I&#39;d like to find another solution that leverages the elementary technology better. In the <code>dpms-helper</code> source code, I find this:</p>
<div class="src src-bash">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>standby_time<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>gsettings get io.elementary.dpms standby-time | cut -d<span style="color:#e6db74">&#34; &#34;</span> -f2<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>suspend_time<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>gsettings get io.elementary.dpms suspend-time | cut -d<span style="color:#e6db74">&#34; &#34;</span> -f2<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>off_time<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>gsettings get io.elementary.dpms off-time | cut -d<span style="color:#e6db74">&#34; &#34;</span> -f2<span style="color:#66d9ef">)</span></span></span></code></pre></div>
</div>
<p>
It gets the time values for these options from <a href="https://developer.gnome.org/gio/stable/gsettings-tool.html">GSettings</a>, a configuration management tool that comes with GNOME. We can use <code>gsettings set</code> to change the time values and then run <code>dpms-helper</code>:</p>
<div class="src src-bash">
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># power settings: standby after 2 minutes, never suspend,</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># and screen off after 1 minute.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># gsettings for these take time in seconds</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>gsettings set io.elementary.dpms standby-time <span style="color:#66d9ef">$((</span><span style="color:#f92672">(</span><span style="color:#ae81ff">2</span><span style="color:#f92672">*</span><span style="color:#ae81ff">60</span><span style="color:#66d9ef">))</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>gsettings set io.elementary.dpms off-time <span style="color:#66d9ef">$((</span><span style="color:#f92672">(</span><span style="color:#ae81ff">1</span><span style="color:#f92672">*</span><span style="color:#ae81ff">60</span><span style="color:#66d9ef">))</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>io.elementary.dpms-helper</span></span></code></pre></div>
</div>
<p>
This solution leaves the configuration in GSettings so other apps can find and respect those values.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-7" class="outline-3">
<h3 id="headline-7">
Support elementary OS
</h3>
<div id="outline-text-headline-7" class="outline-text-3">
<p>
The elementary OS team puts a <em>ton</em> of love into creating a beautiful, accessible, privacy-respecting desktop. The source code is available for everyone to read, study, share and modify, so the whole community is invited learn more about computers and share the work of improving them.</p>
<h4>Three ways you can contribute to elementary <img src="/elementary.svg" class="title" title="elementary" alt="logo" /></h4>
<ol>
<li>Spread the word! Share this article and others you find interesting and helpful. The elementary team writes <a href="https://blog.elementary.io/">a great blog</a>.</li>
<li><a href="https://elementary.io/">Purchase elementary OS</a> (name your price), <a href="https://appcenter.elementary.io/">apps on AppCenter</a>, and <a href="https://github.com/sponsors/elementary">sponsor elementary on GitHub</a>.</li>
<li>Contribute your skills to elementary OS development, starting with our <a href="https://docs.elementary.io/develop/">guide for developers</a>.</li>
</ol>
<p>You can also <a href="https://github.com/sponsors/ryanprior/">sponsor me on GitHub</a> to get more practical explorations like this one!</p>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>Svelte is unappealing </title>
            <link>https://www.ryanprior.com/posts/svelte-is-unappealing/</link>
            <pubDate>Mon, 23 Mar 2020 15:00:00 -0400</pubDate>
            
            <guid>https://www.ryanprior.com/posts/svelte-is-unappealing/</guid>
            <description>&lt;p&gt;
In the world of front-end JavaScript tooling, &lt;a href=&#34;https://svelte.dev/&#34;&gt;Svelte&lt;/a&gt; is one of the most exciting
new options. It promises to clear away a lot of the cruft and indirection
associated with other popular systems:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We took a step back and asked ourselves what kind of API would work for us…
and realized that the best API is no API at all. We can just use the language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(from &lt;a href=&#34;https://svelte.dev/blog/svelte-3-rethinking-reactivity#Moving_reactivity_into_the_language&#34;&gt;&amp;#34;Rethinking Reactivity&amp;#34;&lt;/a&gt;)&lt;/p&gt;
&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-3&#34;&gt;
&lt;h3 id=&#34;headline-1&#34;&gt;
Svelte&amp;#39;s primary value propositions
&lt;/h3&gt;
&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-3&#34;&gt;
&lt;p&gt;
Let me start by laying out specifically how I see Svelte marketing itself, and
I&amp;#39;ll follow-up with how I feel about those claims.&lt;/p&gt;</description>
            <content type="html"><![CDATA[
<p>
In the world of front-end JavaScript tooling, <a href="https://svelte.dev/">Svelte</a> is one of the most exciting
new options. It promises to clear away a lot of the cruft and indirection
associated with other popular systems:</p>
<blockquote>
<p>We took a step back and asked ourselves what kind of API would work for us…
and realized that the best API is no API at all. We can just use the language.</p>
</blockquote>
<p>(from <a href="https://svelte.dev/blog/svelte-3-rethinking-reactivity#Moving_reactivity_into_the_language">&#34;Rethinking Reactivity&#34;</a>)</p>
<div id="outline-container-headline-1" class="outline-3">
<h3 id="headline-1">
Svelte&#39;s primary value propositions
</h3>
<div id="outline-text-headline-1" class="outline-text-3">
<p>
Let me start by laying out specifically how I see Svelte marketing itself, and
I&#39;ll follow-up with how I feel about those claims.</p>
<div id="outline-container-headline-2" class="outline-4">
<h4 id="headline-2">
Svelte isn&#39;t a framework
</h4>
<div id="outline-text-headline-2" class="outline-text-4">
<p>You “just” use standard web fare:</p>
<blockquote>
<p>Build boilerplate-free components using languages you already know—HTML, CSS,
and JavaScript</p>
</blockquote>
<p>(from the <a href="https://svelte.dev/">first call-to-action on the Svelte homepage</a>)</p>
</div>
</div>
<div id="outline-container-headline-3" class="outline-4">
<h4 id="headline-3">
Svelte isn&#39;t a runtime
</h4>
<div id="outline-text-headline-3" class="outline-text-4">
<p>You compile ahead-of-time and deploy components which run with no dependency on
Svelte:</p>
<blockquote>
<p>[Svelte is] a compiler that takes your declarative components and converts
them into efficient JavaScript that surgically updates the DOM.</p>
</blockquote>
<p>(from the <a href="https://github.com/sveltejs/svelte">Svelte GitHub readme</a>)</p>
<p>
I find these claims to be misleading &amp; there are a couple of things that make
the whole approach unappealing to me. Neither are absolutely disqualifying, but
they make me hesitate to recommend Svelte to people starting new projects or
learning front-end development.</p>
</div>
</div>
</div>
</div>
<div id="outline-container-headline-4" class="outline-3">
<h3 id="headline-4">
Svelte creates a split world by mimicking things familiar to you
</h3>
<div id="outline-text-headline-4" class="outline-text-3">
<p>
Svelte code looks like JavaScript, CSS, and HTML, but its compilation stage
takes that and munges it totally out of recognition into a tangle of reactive JS
code. What&#39;s running on the client does not resemble what you wrote; yet, where
you&#39;re looking at it in your editor, it <em>looks just like</em> normal code. Your
brain will tend to allow assumptions that would hold for normal JS/CSS/HTML.</p>
<p>
So in order to avoid providing an API or framework, Svelte creates a split world
where you need to always know which side you&#39;re on–is this code that will be
interpreted directly, or compiled by Svelte? Your code looks the same on each
side but acts totally different.</p>
<p>
So whereas Svelte explicitly appeals to people on the principle of familiarity,
this greatest strength hides a confusing trap.</p>
</div>
</div>
<div id="outline-container-headline-5" class="outline-3">
<h3 id="headline-5">
Svelte has one runtime per component
</h3>
<div id="outline-text-headline-5" class="outline-text-3">
<p>
Svelte markets itself as having no runtime: unlike React &amp; friends, there is no
code that&#39;s taking the data structures you create and turning them into a DOM,
it&#39;s merely a tangle of JS code specific to each component that&#39;s doing the
rendering directly.</p>
<p>
What that means in practice is that you have a different Svelte runtime per
component that&#39;s generated for you. You start from ground zero each time you
find a production glitch of some sort; there&#39;s no single standard runtime that
provides introspection &amp; helps you mess with your data structure and see how
that would render differently, or enables you to edit your code and see live how
that changes things.</p>
<p>
The way to change the behavior of a running Svelte app is to either A) abandon
the logic you were working with when you created the component in the first place,
instead working on the logical level of the generated JS code; or B) go back to
your editor, make changes, pray, recompile your app, and reload.</p>
<p>
While Svelte touts how it adds no extra complexity due to a runtime library,
there&#39;s still the implicit complexity of understanding each component as it&#39;s
actually implemented, and you don&#39;t get any of the niceties of a runtime to help
you deal with that.</p>
</div>
</div>
<div id="outline-container-headline-6" class="outline-3">
<h3 id="headline-6">
What I prefer instead
</h3>
<div id="outline-text-headline-6" class="outline-text-3">
<p>
I like <a href="https://preactjs.com/">Preact</a>. It&#39;s the exact same API as React, so I benefit from being able to
search for &#34;how to do X in react&#34; and get results that work for Preact too. But
the runtime is simpler &amp; smaller and it&#39;s easy to get started without a bunch of
boilerplate and code generators like <code>create-react-app</code>, which are endemic to
React tooling.</p>
<p>
I like having an API that&#39;s not magical or disappearing, which I can use to do
my rendering. I like that Preact can be used directly in the browser without any
transpilation steps. I like that it plays well with other front-ends which may
set event listeners on objects which React would usually clobber.</p>
</div>
</div>
<div id="outline-container-headline-7" class="outline-3">
<h3 id="headline-7">
Looking forward
</h3>
<div id="outline-text-headline-7" class="outline-text-3">
<p>
I am excited by the possibilities for compiled web apps which run on low-memory
devices or achieve ultra-high-performance on powerful consumer machines. While
I&#39;m dissatisfied with Svelte&#39;s approach which mimics and munges standard web
technologies, it seems likely to inspire the community to create innovative APIs
which will allow us to build reactive high-performing compiled web apps with
WebAssembly and <a href="https://rustwasm.github.io/book/">Rust</a> or <a href="https://tinygo.org/">TinyGo</a>, and even with new languages like <a href="https://crystal-lang.org/">Crystal</a>.</p>
<p>
I also worry that Svelte may inspire a raft of copycat &#34;no-API&#34; front end
systems which implement mutually incompatible semantics, each on top of
normal-looking JS/CSS/HTML, further increasing the potential for &#34;split world&#34;
headaches.</p>
</div>
</div>
]]></content>
        </item>
        
        <item>
            <title>Planning to Relaunch </title>
            <link>https://www.ryanprior.com/posts/planning-to-relaunch/</link>
            <pubDate>Tue, 10 Mar 2020 22:07:40 -0400</pubDate>
            
            <guid>https://www.ryanprior.com/posts/planning-to-relaunch/</guid>
            <description>&lt;p&gt;It&amp;rsquo;s March 2020 and lately I&amp;rsquo;ve been looking forward to relaunching my website.
One thing that&amp;rsquo;s been holding me up has been my worry about whether I have
&amp;ldquo;enough content to do it for real,&amp;rdquo; so I&amp;rsquo;m pushing past that with a bold plan to
pursue a nearly content-free relaunch. This will free me to add content as I&amp;rsquo;m
ready instead of satisfying my inner critic that I have &amp;ldquo;enough&amp;rdquo; to permit
myself to ship.&lt;/p&gt;</description>
            <content type="html"><![CDATA[<p>It&rsquo;s March 2020 and lately I&rsquo;ve been looking forward to relaunching my website.
One thing that&rsquo;s been holding me up has been my worry about whether I have
&ldquo;enough content to do it for real,&rdquo; so I&rsquo;m pushing past that with a bold plan to
pursue a nearly content-free relaunch. This will free me to add content as I&rsquo;m
ready instead of satisfying my inner critic that I have &ldquo;enough&rdquo; to permit
myself to ship.</p>
<p>So here&rsquo;s the plan:</p>
<ol>
<li>Learn how to use <a href="https://gohugo.io/">Hugo</a> (I&rsquo;m told I&rsquo;ll like it)</li>
<li>Decide whether I like Hugo enough to ship with it</li>
<li>Pick a good-enough theme</li>
<li>Write a stub of an <a href="/about/">about</a> page</li>
<li>Publish!</li>
</ol>
<p>If you see this page, it means my plan has succeeded! Wish me luck 😤</p>
]]></content>
        </item>
        
    </channel>
</rss>
