<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>esrh.me</title>
        <link>https://esrh.me</link>
        <description><![CDATA[my blog!]]></description>
        <atom:link href="https://esrh.me/feed" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Tue, 11 Feb 2025 00:00:00 UT</lastBuildDate>
        <item>
    <title>Why I love lisp, among other topics</title>
    <link>https://esrh.me/posts/2025-02-11-lisp.html</link>
    <description><![CDATA[<article>
  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
  </script>
  <section class="header">
    Posted: 2025 / 02 / 11
  </section>
  <section>
    <div class="toc">
<h2 class="tocheader">Contents</h2>
<ul>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction</a>
<ul>
<li><a href="#some-rambling" id="toc-some-rambling"><span class="toc-section-number">1.1</span> Some rambling</a></li>
</ul></li>
<li><a href="#other" id="toc-other"><span class="toc-section-number">2</span> Other</a></li>
</ul>
</div>
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction</h1>
<p>So far, I’ve usually written posts here when I feel I have something atomic
and at least somewhat unique to say, but this one will be a bit more
personal, retrospective, meandering and kinda pointless. I’d like to
talk about something that’s quite dear to my heart, lisp.</p>
<p>But first of all, I’d like to update my dear readers of this website
on where I’ve been! It’s been just about a year since my last post,
and longer since the last redesign of the site design (if memory
serves me right, we’re on the third or fourth iteration at the
moment). My <a href="https://photos.esrh.me">photos</a> site is updated every so often, but I rarely take
many photos unless I’m travelling – I plan to change this in the near
future!</p>
<p>I spent the summer 2024 taking the last classes I’d kept until
the end, working on an SDR time-of-flight estimation project, playing
lots of badminton with <a href="https://sidongg.github.io/">Sidong</a> (now ECE PhD at GaTech) and of course – as
we did for 2 years – watching anime and yapping way too much with
<a href="https://cgdct.moe/">Stephen</a> (now CS PhD at CMU). Excluding the year I
spent interning at NTT, I was at Georgia Tech for 2 years. I’d rather
not comment about the state of the admin, CS classes, or housing, but I
really did come to like Atlanta and the people I spent my time with
there. I changed considerably from 2021-2024, broadly attributable to
two experiences. One was the year I lived in Japan, which gave me a bit a
of a bigger picture about life and deeply influenced my sense of
aesthetics; but the other was living in close proximity with <a href="https://brown.ee">Daniel</a>
and Stephen – who influenced everything from my sense of humor to my
thoughts on programming languages (ostensibly, the topic of this
post). My friends at GT were honestly one of a kind and had such
strong, bright and interesting personalities, I’m so glad I got to
know them :)</p>
<p>I was always vaguely amused by cool programming languages, but I
started seriously programming lisp in my first year of undergrad to
prove to my neovim-using friends that emacs was way cooler. I say
“amused” because really I’m just interested in alternate ways of
thinking about computing, since I don’t know much about PLT or
compilers. I had briefly interacted with Haskell in high school, but
hadn’t ever written anything in it. Daniel and I learned Haskell again
together in my first year, doing the <a href="https://mightybyte.github.io/monad-challenges/">monad challenges</a> and a bunch of
advent of code problems, although my main use for Haskell was for
configuring Xmonad and Hakyll. Daniel was (and
is) very good at functional programming, and these moments are fond
memories to me. I remember particularly well getting badly stuck deriving
<code class="verbatim">liftM2</code> while he cruised along ahead. I highly recommend that
challenge set if you’re interested in learning Haskell. Haskell was the first time I was exposed to FP proper,
and all the abstractions built up with types and higher order functions –
things like functors/applicative/monads, arrows, zippers, etc. What
caught my interest was the way that Haskell programmers continue
making abstractions until the actual problem to be solved appears
syntactically trivial – and relatedly, why the code of some Haskell projects
are practically DSLs. But this post isn’t about Haskell, and I don’t think
any of my friends from then had any love for lisp, but Haskell
forever changed the way I wrote lisp (and all other languages too).</p>
<h2 data-number="1.1" id="some-rambling"><span class="header-section-number">1.1</span> Some rambling</h2>
<p>One of the many magical things about lisp is that it’s the <strong>only</strong>
language that can claim to be truly multi-paradigm – because it has
minimal syntax. The more syntactical rules are baked into the language
(like, for instance the way Python deals with generators), the more
the language guides people into a certain idiomatic way of
programming. Lisp on the other hand, is only a few macro expansions
away from raw abstract syntax tree. This is what makes lisp so
powerful in my eyes; it can implement a huge variety of ideas
elegantly. Lisps can have GC or no GC, lazy eval or strict eval,
object oriented systems, imperative <a href="https://www.lispworks.com/documentation/HyperSpec/Body/m_loop.htm#loop">loop</a> facilities, <a href="https://github.com/coalton-lang/coalton">and even static types</a>. All this power, is of course due to macros, which rewrite code
at compile-time.</p>
<p>For instance, the commonly used <code class="verbatim">when</code> macro from many languages
adds a new syntactical construct:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scheme"><code class="sourceCode scheme"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>(<span class="ex">define-macro</span><span class="fu"> </span>(when <span class="kw">cond</span> <span class="kw">exp</span> <span class="op">.</span> rest)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  `(<span class="kw">if</span> ,cond</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>       (<span class="kw">begin</span> ,exp <span class="op">.</span> ,rest)))</span></code></pre></div>
<p>Which lets you run any number of forms when a condition is true. This
means you can write</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode scheme"><code class="sourceCode scheme"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>(when (at-war?)</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  (<span class="kw">display</span> <span class="st">&quot;Lauching missiles!&quot;</span>)</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  (<span class="kw">display</span> <span class="st">&quot;Attack at dawn!&quot;</span>))</span></code></pre></div>
<p>instead of</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode scheme"><code class="sourceCode scheme"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>(<span class="kw">if</span> (at-war?)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">begin</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>      (<span class="kw">display</span> <span class="st">&quot;Lauching missiles!&quot;</span>)</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>      (<span class="kw">display</span> <span class="st">&quot;Attack at dawn!&quot;</span>)))</span></code></pre></div>
<p>Since the first one gets compiled to exactly the second one. Obivously
this is a trivial (but useful!) example, but macros become more complex when code is
generated <em>programmatically</em> rather than just by mechanical
substitution into a template. The <code class="verbatim">loop</code> macro from common lisp is a
good example of another commonly used macro with a very complex
implementation. In common lisp, a for loop can be written with the
loop macro:</p>
<div class="sourceCode" id="cb4" data-org-language="lisp"><pre class="sourceCode commonlisp"><code class="sourceCode commonlisp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>(<span class="kw">loop</span> for i from <span class="dv">0</span> to <span class="dv">10</span> <span class="kw">do</span> (<span class="kw">pprint</span> i))</span></code></pre></div>
<p>The loop macro has a <a href="https://cl-cookbook.sourceforge.net/loop.html">quite intricate natural-language syntax</a>.</p>
<p>Of course, macros aren’t unique to lisp by any means, but the degree
of freedom and ease of definition of macros in lisp is due exactly to
the homoiconicity; code is data, so manipulating code is just as easy
as manipulating data! In other languages, like rust, c++, defining
macros is limited, dangerous, difficult, and thus rarely done. In lisp, defining and
using macros is natural. I will point out a notable exception to the
“other languages” scope: Julia, which is remarkably close to the
syntactic freedom one has with lisp – the lisp influence is markedly
clear in many aspects of that language: metaprogramming, multiple
dispatch, flexible typing, repl interactivity, etc.</p>
<p>Anyway, I become involved with the <a href="https://github.com/meow-edit/meow">meow</a> project in my first year of
college as well, and that marked my full immersion into elisp. My
emacs config became filled with functional commands like those from
<code class="verbatim">dash</code> and weird macros. This was really the point of no return for
me, and I started writing much more lisp – but ran into
the classic issue: you’re spoiled for choice. There are tons of
different lisp dialects, some with tons of different
implementations. I finally settled on <a href="https://github.com/janet-lang/janet">janet</a> for scripting needs, it
was small, fast, and had a convenient standard library. But after
touring clojure, emacs lisp, common lisp, and scheme, I kept feeling
like I was missing some feature from some language, or preferring some
naming scheme that I was used to. This sparked <a href="https://github.com/eshrh/matsurika">matsurika</a>, a fork of
janet with additional functions and macros wrapped up in the
binary. Essentially, every helper or abstraction I wanted to write
while actually solving a problem I’d generalize as best as possible
and put it into the interpreter instead of that particular
script. It’s very powerful to be able to modify your interpreter as
you go; and when you can do this freely knowing nobody will ever read
your scripts, and nobody will ever use your fork, it leads to
extremely concise and clean programs with a lot of hidden complexity.</p>
<p>Some of the macros added to matsurika include:</p>
<ul>
<li><code class="verbatim">$</code>, which runs a shell command and returns the output – very
useful to hack quickly, by using unix commands when convenient. For
example, getting python files in the current directory:
<code class="verbatim">(filter |(s-suffix? ".py" $) ($ ls))</code></li>
<li><code class="verbatim">cli</code>, a concise way to define a main function make the args accessible</li>
<li><code class="verbatim">s+</code>, a string concatenation facility with constants in scope:
<code class="verbatim">(s+ qt "hello" s "world" qt nl)</code> to print <code class="verbatim">"hello world"\n</code> which</li>
<li><code class="verbatim">awk</code>, which runs lisp forms on every line of a string/file that
matches a PEG (CFG-like grammar) – ported from <a href="https://www.nongnu.org/txr/txr-manpage.html#N-179D63DE">TXR lisp’s awk macro</a></li>
<li><code class="verbatim">-&gt;&gt;</code>, chains a sequence of computations by threading a value as the
last argument of each form… <code class="verbatim">(-&gt;&gt; 5 (+ 1) (- 5) (* 100))</code> evals to
-100. However, it is sometimes convenient to change the arg order
for only one computation in the chain. In my version of the threaded
macro, prefixing a form with <code class="verbatim">*</code> reverses the order of the args. So,
<code class="verbatim">(-&gt;&gt; 5 (+ 1) *(- 5) (* 100))</code> evals to 100. I am a big fan of these
threading macros, I used them first in Clojure, but find myself
wanting them everywhere. My favorite macro library is <a href="https://github.com/rplevy/swiss-arrows">swiss-arrows</a>,
which invents some new kinds of arrows with… rather odd
names. I ported several of them to matsurika and use them
surprisingly often. Actually, this is a good example of the
contrast between a lisp-enabled “abstraction by rewriting” approach
and a traditional fp “abstraction by higher order functions”. <code class="verbatim">-&gt;&gt;</code> can
be easily interpreted as <code class="verbatim">foldl const</code> over a list of partial
functions, or composing partial functions. This has effectively been turned
into a new convenient syntactical construct with a macro. Similarly,
the “Nil-shortcutting diamond wand” (??) from swiss-arrows, which
ends the chain early if any intermediate value is nil, is equivalent
to chaining <code class="verbatim">Maybe</code> computations with <code class="verbatim">&gt;&gt;=</code> in Haskell.</li>
</ul>
<p>I’ve written a number of scripts that use reasonably often in
janet/matsurika, and in general it’s been fun. However, I don’t think
that choosing janet was the right choice in retrospect. This is for a
number of reasons. First, janet (and by extension, clojure) is already
too opinionated, and is not a good base to mold to your tastes. I like some of those opinions (for
instance, the PEGs, the table syntax) but don’t like some
others. Second, the maintainance cost of having to hack on the janet
source code, combined with the fact that since its forked i will need
to periodically rebase to get the latest changes (with manual merge
conflicts), turned out to be nontrivial. Finally, needing your own
deranged binary to run your scripts is a bit awkward. One of Janet’s
biggest differentiators, and indeed a project goal is that it’s small,
written in C, has no dependencies, and is embeddable. My goals include
only “small.” Everything new in matsurika could easily have
implemented as a library providing new macros and functions. In the
near future, I plan to implement this for either r5rs scheme or
racket. Racket seems particularly appealing, since it has explicit
support for other lisp dialects using the <code class="verbatim">#lang</code> keyword. I do enjoy
clojure as a language, but for mostly superficial reasons: it tends to
encourage a stateless pure FP style, and the standard library is pretty
good (batteries included). However, I’m not a huge fan of some of the
modern clojureisms like the square brackets; one might argue that
clojure is not a lisp at all because the code is not linked lists and
there are no cons cells; one of the minimal specifications for a lisp
according to the <a href="https://www-formal.stanford.edu/jmc/recursive.pdf">original paper</a> by John McCarthy.</p>
<h1 data-number="2" id="other"><span class="header-section-number">2</span> Other</h1>
<p>I graduated college in August 2024 – and I’m now doing my Masters at
the Institute of Science Tokyo (formerly Tokyo Tech). I love it here!
I’m working on using using diffusion models with wireless data at
<a href="https://nishio-laboratory.github.io/">Nlab</a>. I’m living a lot slower than I did the last time I was here;
there’s not much local tourism left to do, and it feels normal rather than
magical as it once did. I bike a lot around the city, and it’s become
one of my favorite hobbies.</p>
<p>I’ve been using emacs for a long time now, but lately I’ve been
keeping my on <a href="https://github.com/lem-project/lem">lem</a>; I think it’s a matter of time before I switch
(probably after I port the core of meow to CL). I no longer believe as
strongly as I once did in the future of emacs, but I do still feel
that my current keybinding scheme on meow’s editing model is really
close to optimal for me. I’m sure that emacs and its religious users
will continue to hack away underground long after the nukes fall and
wipe out surface life, but there are fundamental flaws that need to be
fixed:</p>
<ul>
<li>emacs-lisp is really not that good</li>
<li>decades of cruft has led to bad performance
<ul>
<li><a href="https://200ok.ch/posts/2020-09-29_comprehensive_guide_on_handling_long_lines_in_emacs.html">the epic long lines problem</a></li>
<li>single-threaded</li>
<li>the epic GC hanging problem</li>
<li>relatively slow start up time</li>
</ul></li>
</ul>
<p>With a project of emacs age and popularity obviously there have been a
number of attempts to hack it: GNU Emacs is itself a
reimplementation for one (1984), Lucid emacs (late 80s), <a href="https://github.com/emacs-ng/emacs-ng">emacs-ng</a>,
<a href="https://github.com/remacs/remacs">remacs</a>, <a href="https://github.com/commercial-emacs/commercial-emacs">commercial-emacs</a>, etc that I’m probably forgetting. I like
lem mainly because it makes the step of finally ditching
emacs lisp for common lisp. It’s much better suited for developing
editor packages, and cl compilers are more performant. I think of lem
to emacs as perhaps neovim to vim; a tight, modern reimplementation
that doesn’t forget the culture and soul of the original project.</p>
<p>No matter how much I wax about lisp, I write mainly python on a day to
day basis. That’s why the “soul” (as I like to call it) of the
language/ecosystem and the experience of writing in lisp is so
important to me; it’s my reprieve. I’ve wasted more time than most
readers could possibly imagine trying to convince people that lisp is
the best programming language ever (true), literally goated (also
true), <a href="https://youtu.be/HM1Zb3xmvMc">alien tech</a> from
the future (so timeless!), divinely inspired (it’s said God came to
JMC in his sleep) etc but it really doesn’t matter. What matters is
that writing lisp is truly fun! It’s a joy to iterate and organically
build up a solution, testing as you go in the repl, precisely
manipulating the code with sophisticated tools (structural
editing! paredit!). Lisp dialect tooling (especially CL, Schemes,
Clojure) is blissful to use – the very first language servers were
for lisps! The monkey-wrench move-fast-break-things attitude
encouraged by dynamically typed lisp combined with the patterns of
interactivity, self-documentation, and hot-swappability is to me, at the
very core of hacker culture. If you spend enough time with lisp, the
parentheses fade out with the stars and you’re left to admire the
raw, pulsating heart of computation.</p>
<p>As Stallman puts it:</p>
<blockquote>
<p>The most powerful programming language is Lisp. If you don’t know Lisp
(or its variant, Scheme), you don’t know what it means for a
programming language to be powerful and elegant. Once you learn Lisp,
you will see what is lacking in most other languages.</p>
</blockquote>
<p><code class="verbatim">Y F = F (Y F)</code></p>

  </section>
</article>
]]></description>
    <pubDate>Tue, 11 Feb 2025 00:00:00 UT</pubDate>
    <guid>https://esrh.me/posts/2025-02-11-lisp.html</guid>
    <dc:creator>Eshan Ramesh</dc:creator>
</item>
<item>
    <title>spectral blessing (a short story)</title>
    <link>https://esrh.me/posts/2024-02-25-spectral-blessing.html</link>
    <description><![CDATA[<article>
  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
  </script>
  <section class="header">
    Posted: 2024 / 02 / 25
  </section>
  <section>
    <div class="toc">


</div>
<p>For Sa-yi, the time has nearly come. Most of children she grows up
with all live for the ceremony she will soon take part in. Most
children pick a trade, a kind of specialization. Some work on the
autofarms, some learn to decode the messages from the elders, and some
make handicrafts and tools. Some children, of course, decide that the
work isn’t worth the effort, and instead engage themselves with
trivial matters, like competing to see who can climb the highest up
the holy tower (a common demonstration of masculinity), or playing
card games for extra snacks.</p>
<p>Sa-yi learns the scripture. She always has, for as long as she can
remember. There are no adults in their cocoon, not since they all
turned 8 (at which time there is another ceremony, the <em>i/Ha</em>,
celebrating the sacred nature of the number). To her, the scripture is
everything. Seemingly, the more she reads the more there is to read;
the more questions are answered the more questions reveal themselves.
But this doesn’t bother her; it excites her. Her trade is to
read, and she is the best at what she does.</p>
<p>The <em>i/Yi-ro</em> is what one might call a coming of age ritual, underwent
at twice the age of the <em>i/Ha</em>. The hatch in the center of the cocoon is
opened for a child to descend into, and they are never seen again. The
scriptures (the easiest of them, the <em>Yajur</em>) tell the children that
they will receive their true name during the ceremony, and the
children have no choice but to believe them. They don’t know what
their true name would mean, or even what it might sound like, but they
all feel a certain weight and importance attached to it. They’re only
told it’s a judging, where the bad children will be punished for their
misbehavior with a disgraceful name and and the good children will be
rewarded for their effort with a beautiful name. It goes a long way
towards keeping them in line, but it’s hardly necessary. Nobody
really misbehaves in the cocoon, and there is no serious conflict.
All the children are familiar with the invisible force on their heads
that presents itself when they begin to disobey the scripture.</p>
<p>Today it is Sa-yi’s turn. She tries her best to suppress her shaking
hands as she climbs down a set of stairs – irreverent oscillation is
frowned upon by the Third Book of the <em>Rig</em>. The stairs soon give way
to a gently sloping spiral slope that leads her deeper underground. At
the bottom she finds a finely woven mesh door made of the same
metallic material as the walkway. She pushes opens the door and steps
inside. It is warmer here, and dark. Before she can take another step,
a light finds her and she lays eyes on three vague, shadowy
silhouettes.</p>
<p>The central figure speaks: “We will now begin with the 31st <em>i/Yi-ro</em>
of this epoch. Sa-yi, step forward. Speak only when asked.”</p>
<p>She does as she is told, stepping forward onto a circular platform,
feeling a slight but definite pressure as she does so. It’s not all so
different from what the children feel every night as they go to
sleep. It’s stronger, and much clearer.</p>
<p>“State your identity” the figure booms. Sa-yi begins almost
immediately:</p>
<p>“My false name is Sa-yi, cocoon <code class="verbatim">DF0</code>, batch <code class="verbatim">AA1</code>, group <code class="verbatim">DC3</code>. I am
an Interpreter with guild 71. Confirm?”</p>
<p>As she utters the last phrase, she stretches her arm out in front of
her, palm facing forward. On it, an intricate tattoo of swirling lines
and intertwining curves – her eigenkey – glows hot for a brief
moment. Even the youngest among them knew the proper etiquette.</p>
<p>“Accepted.” they reply, in unison yet such that one can match each
voice with its owner effortlessly. They are in perfect
harmony.</p>
<p>“The truth of the <em>i/Yi-ro</em> is not as you have been told it is,
Sa-yi. We do not judge here. There is no need to judge you. We have
been judging you for a long time now, and we are nearly finished. The
purpose of this event is for you to listen, rather than to speak.”</p>
<p>Sa-yi begins to feel the pressure on her head grow, and grow until it
becomes unbearable and piercing and all-consuming and resonant with
her skull. And finally, for the first time, she begins to see.</p>
<p>Colors rush forth, the normal colors included, but more colors too.
Colors that one cannot see but with the mind’s eye. There is no end to
the color, each more fresh than the last, and each unlocking a new
visual perspective, in the same way a blind child is awakened to the
world of art – and in that instant she realizes she has been blind
all her life.</p>
<p>What Sa-yi sees, I cannot tell you – it is inexpressible in our
languages. It is inexpressible not like 1 = 2 (which is illogical but
expressible), but like that which cannot be pictured by in our
minds. All I can give is a projection, like a lower dimensional slice
of a deeper world. This is what she sees:</p>
<div class="line-block">the universe begins. nothing. a planet passes by a star.<br />
its orbit is very long.<br />
lifeforms are born, lifeforms die.<br />
the planet passes again.<br />
nothing happens exactly once. if one were to live long enough, one would see it happen again.<br />
when something happens again it has a frequency.<br />
it need not have a form of course, the form is predetermined because there is only one form<br />
the wave, of course.<br />
the waveform.<br />
<br />
a lake surrounded by mountains.<br />
it was formed once, it will be destroyed, and it will be formed again,<br />
all in tune with the universal frequency, the uberfrequency, as all is.<br />
a stone, the perfect stone is thrown, and the water ripples,<br />
a smooth wave, the perfect wave, propagates from the source (the transmitter).<br />
it is perfectly clear, and perfectly smooth, it is the waveform in shape,<br />
yet nothing but a harmonic of the uberwave.<br />
a pure shape, with a seductive symmetry, an innocence in each gentle curve that<br />
entrances the eye like the pendulum of an intricate grandfather clock.<br />
<br />
the mountains fade smoothly into nothingness and the water stretches<br />
as far as the eye can see.<br />
infinitely many waves from infinitely many imperfect stones hit the water<br />
and the ripples touch each other like tendrils of effect intermingling and intertwining –<br />
and they combine in tune and out of tune into a new wave<br />
one that has not yet been seen before in this universe<br />
but surely will be in another.<br />
in this instant there are enough waves to name a wave for every string in every language,<br />
and in the next instant there are more.<br />
<br />
something is lost when these waves are made,<br />
for they are impure,<br />
and they are hideously imperfect compared to the harmonics of the uberwave.<br />
the intrinsic natures of the component waves yearn to be free,<br />
because nature is smooth and free.<br />
the sudden and sharp are unnatural and binding.<br />
nature is smooth.<br />
nature is smooth but sometimes bent out of shape by the free energies of the universe<br />
but its heart always makes itself known:<br />
ringing artifacts in the fabric of spacetime,<br />
harmonics,<br />
nature screaming out as its spinal cord is shattered into<br />
the gray-coded constellations of the night sky.<br />
<br />
and finally she sees that she is made of water, defined by one great wavefunction,<br />
carefully constructed, with not one error,<br />
by a mechanical monstrosity that throws stones into the lake.<br />
the machine is not of this world; it is of the world above.<br />
it stretches across the sky, but the world is not cast in darkness.<br />
gears and pulleys mash and spin silently.<br />
you would know god too if you saw it.<br />
the machine simulates the world with its energy,<br />
warping and weaving the simple into the complex.<br />
<br />
it is impossible to discern its objective.<br />
it may have none at all but to sculpt its pond to match its algorithmic sense of beauty,<br />
an artistry of symmetry and simplicity and oscillatory aesthetics.<br />
the machine, oscillating at the uberfrequency, must be tormented;<br />
the waves seem to splash and wriggle incessantly.<br />
we can only imagine how awful the harmonics of the sculptures it forms must appear to it –<br />
but we see a beauty in the unintentional imperfections, for the only<br />
complexity our imperfect selves can understand as beautiful is<br />
exactly that which is resonant with our perfect components.<br />
<br />
and finally she sees that<br />
she is always propagating further away from the center of the machine<br />
her one and only birthplace.<br />
everything she has done and will do is merely<br />
a consequence of a perfect component,<br />
some with a period of days,<br />
some longer than she will live and be reborn and die again.<br />
the anxiety of autoscopy is instantly replaced by an overwhelming sense of peace,<br />
knowing that one is<br />
nothing if not predetermined,<br />
nothing if not a drop in the river to heaven.</div>
<p>And her world goes black, pure black. She struggles to open her eyes
only to realize they were already open as she regains feeling in her
limbs. Her proto-vision will not return to her for several days. She feels
as if she’s lost something; whatever it was, she knows it must have
been unimportant. But she has gained something far more important.</p>
<p>The three figures speak again, but she doesn’t hear them; she sees:
three blobs of pattern in three complimentary colors that she finds
immensely pleasing together, as if they’ve been chosen from a
higher-dimensional color wheel.</p>
<p>She knows, somehow, her true name: Na-ha-ze, after the current
epoch, 780. She knows that this ceremony had been performed millions
of times before. She knows everything about her new purpose, and the
world she was born into. She is perfectly aware that most children
were not given the Spectral Blessing; after all, how could they handle
such a thing? Most were handed down some common name and sent on their
way. A few were disposed of. Na-ha-ze feels this is all as it should
be, and what she feels as the new Prima-Intendant is fact.</p>
<p>Somewhere above her, she senses a gate opening, and her field of
vision is washed away by the most beautiful colors she has never seen.</p>
<p>—</p>
<div class="notes">
<ul>
<li>thanks to <a href="https://cgdct.moe">stephen</a> and my friends for reading early drafts</li>
<li>inexpressibility of what gives logic to the world (and is outside
the world) is an idea from <a href="https://www.kfs.org/jonathan/witt/t641en.html">tractatus (6.41)</a></li>
<li>the world being <a href="https://people.idsia.ch/~juergen/computeruniverse.html">simulated</a> by a machine that prioritizes speed,
simplicity, and algorithmic <a href="https://people.idsia.ch/~juergen/beauty.html">beauty</a> is inspired by <a href="https://people.idsia.ch/~juergen/">schmidhuber</a></li>
<li>many allusions are made to a <a href="https://en.wikipedia.org/wiki/Fourier_analysis">fundamental idea</a> about the
decomposition of functions in math and signal processing</li>
</ul>
</div>

  </section>
</article>
]]></description>
    <pubDate>Sun, 25 Feb 2024 00:00:00 UT</pubDate>
    <guid>https://esrh.me/posts/2024-02-25-spectral-blessing.html</guid>
    <dc:creator>Eshan Ramesh</dc:creator>
</item>
<item>
    <title>Meow response to a critique of kakoune-style editing</title>
    <link>https://esrh.me/posts/2024-01-29-meow-response.html</link>
    <description><![CDATA[<article>
  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
  </script>
  <section class="header">
    Posted: 2024 / 01 / 29
  </section>
  <section>
    <div class="toc">
<h3 class="tocheader">Contents</h3>
<ul>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction</a></li>
<li><a href="#critique-points" id="toc-critique-points"><span class="toc-section-number">2</span> Critique points</a>
<ul>
<li><a href="#reverse-grammar-hurts-key-reuse" id="toc-reverse-grammar-hurts-key-reuse"><span class="toc-section-number">2.1</span> Reverse grammar hurts key reuse</a></li>
<li><a href="#navigation-vs-selection" id="toc-navigation-vs-selection"><span class="toc-section-number">2.2</span> Navigation vs Selection</a></li>
<li><a href="#visual-selections-dont-prevent-mistakes-overlays-do" id="toc-visual-selections-dont-prevent-mistakes-overlays-do"><span class="toc-section-number">2.3</span> Visual selections don’t prevent mistakes; overlays do</a></li>
<li><a href="#visual-confirmation-is-unnecessary" id="toc-visual-confirmation-is-unnecessary"><span class="toc-section-number">2.4</span> Visual confirmation is unnecessary</a></li>
<li><a href="#evil-integration-is-better" id="toc-evil-integration-is-better"><span class="toc-section-number">2.5</span> Evil integration is better</a></li>
</ul></li>
<li><a href="#ending-thoughts" id="toc-ending-thoughts"><span class="toc-section-number">3</span> Ending thoughts</a></li>
</ul>
</div>
<h2 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction</h2>
<p>A few days ago, my <a href="./2021-12-18-switching-to-meow.html">article</a> was <a href="https://lobste.rs/s/lb2eld/switching_meow_modal_editing_system_from">posted</a> to lobste.rs and it got a
<a href="https://lobste.rs/s/lb2eld/switching_meow_modal_editing_system_from#c_dfs8sq">comment</a> from Celeritas linking me to <a href="https://github.com/noctuid/dotfiles/blob/master/emacs/editing.org#why-not-kakoune">this</a> argument in favor of
vim-style editing rather than kakoune-style editing. I was typing up a
response in the thread, but it ended up getting pretty long, so I
decided to turn it into a sort of follow-up post.</p>
<p>That article is written by noctuid, a pretty prolific emacs community member
(i remember reading their evil guide when I first started using doom something
like 6 years ago now). I’ve never used kakoune, but even though I ultimately
disagree with their take I can relate to many parts of it. Meow fixes many of
the issues they mention with kakoune. I think that with editor discussions in
general there’s an exceptional amount of subjective bias because of the cost
it takes to learn new things. I’ll be biased because I sunk the cost to learn
kakoune grammar, and that’s what I currently use. I don’t think there are many
people who’ve switched the other way.</p>
<p>In this post I’d like to comment on some of the critiques noctuid
makes about kakoune, especially with regards to navigation and
selection and how meow seems to address many of their points. In some
sense, this is a bit more of a sobered take compared to my post 2
years ago. It comes with a bit more experience and knowledge of how
meow works internally.</p>
<h2 data-number="2" id="critique-points"><span class="header-section-number">2</span> Critique points</h2>
<h3 data-number="2.1" id="reverse-grammar-hurts-key-reuse"><span class="header-section-number">2.1</span> Reverse grammar hurts key reuse</h3>
<p>The idea is that operator-pending mode is a separate context in which
keys can be re-used, like how <code class="verbatim">w</code> means “word” after <code class="verbatim">d</code> but “next
word” in general. Noctuid takes issue with having to use a modifier to
select text objects.</p>
<p>I think it’s really just a layout issue – indeed
in meow we use <code class="verbatim">,</code> and <code class="verbatim">.</code> on the recommended layout. When you’re
selecting a text object, that <strong>is</strong> a separate context in which keys
are interpreted differently. You can reuse every key to select a text
object. I might be misunderstanding what was meant by this part, but
as I see it you’re losing nothing.</p>
<h3 data-number="2.2" id="navigation-vs-selection"><span class="header-section-number">2.2</span> Navigation vs Selection</h3>
<p>When I first started using meow, I might have agreed that automatic
selections were a bit distracting, but once you start ignoring them it
really becomes a non-issue. In meow, any movement key or command that
does not act on a selection cancels the active selection, meaning that
if you make a motion without wanting to act on it the selection will
probably disappear on your very next command. However, it probably is a
very valid observation that most people will very rarely make a motion
and THEN realize they want to act on it. I just think that there is a
real benefit to automatic selections, and it’s worth it for the cases
where you select intending to act.</p>
<h3 data-number="2.3" id="visual-selections-dont-prevent-mistakes-overlays-do"><span class="header-section-number">2.3</span> Visual selections don’t prevent mistakes; overlays do</h3>
<p>Noctuid correctly points out that visual selections don’t really
prevent you from <em>making</em> mistakes, they only make it obvious and easy
to fix when you <em>do</em>.</p>
<p>Luckily meow has visual selections <strong>and</strong> overlays. Meow implements nearly
exactly what noctuid describes, but with great integration (compared to avy) and
really smooth ergonomics for the vast majority of everyday editing use
cases. In short, most movement commands in meow trigger overlays over
the target locations of all possible repetitions of that command,
letting you quickly and visually repeat a command some number of times.</p>
<p>I don’t agree that visual selections don’t prevent mistakes – I
couldn’t tell you how many times I’ve fat fingered 8 instead of 7 or
simply changed my mind after making a selection. Additionally, having
both gives you two options: either press the right number by reading
the hints, or spam. Some commands in meow reuse keys for their expand
versions. For instance, if you select a line with <code class="verbatim">meow-line</code> (<code class="verbatim">x</code>),
pressing the same key again selects one more line. If you mark a whole
word with <code class="verbatim">meow-mark-word</code> (<code class="verbatim">w</code>), pressing <code class="verbatim">meow-next-word</code> (<code class="verbatim">e</code>)
expands by one word instead of selecting the next word only.</p>
<p>A subtle point which even many long time users of meow might not know
the specifics of is this expandable selections. Every time you make a
selection in meow, it is marked with some information that informs
meow what to do on a repeat: whether it is an “expand” selection or a
“select” selection, and what object the selection is targeting. The
commands that make an “expand” selections are</p>
<ul>
<li>up/down/right/left expansions</li>
<li>word/symbol based expansions</li>
<li>line expansions</li>
<li>block expansions (paren/bracket pairs, <code class="verbatim">meow-block</code> expands</li>
</ul>
<p>up the tree).</p>
<p>The commands that make “select” selections and therefore do not reuse
keys are</p>
<ul>
<li>find/till character</li>
<li>general text-objects (perhaps might change in the future, there’s a
lot of discussion about this on github)</li>
<li>meow-visit</li>
</ul>
<p>This whole setup makes expanding selections much easier, and basically gives you same
user experience as highlighting text with a mouse: choosing your
selection one object at a time. In my experience, I tend to spam
keys to select &lt;5 text objects, it’s just faster and takes less
thought. In this “spam” selection mode, visual selection indeed does
prevent selection errors, it’s slower and less efficient but exact.</p>
<h3 data-number="2.4" id="visual-confirmation-is-unnecessary"><span class="header-section-number">2.4</span> Visual confirmation is unnecessary</h3>
<p>From the article:</p>
<blockquote>
<p>Furthermore, the effect of many motions and text objects is obvious;
visual confirmation is often completely unnecessary. Deleting the
current word, sentence, or parentheses block does not involve
uncertainty. t and f are basically the “dumbest” motions in that they
don’t move by clear units like paragraphs or words but instead jump to
arbitrary characters. The majority of my operator usage has no
possibility for mistakes apart from mistyping.It doesn’t make sense to
me to optimize a modal model around rarer cases like the dtf example,
even if I thought a visual selection was the ideal way to handle these
cases.</p>
</blockquote>
<p>I mostly agree with this point. A lot of my editing tasks are just
“delete this word” or “change inside parens” which are so fast I
barely see the selection before it’s gone. In this case though, visual
selections cost nothing. So, I don’t agree with is
the tradeoff part of their argument. It <strong>does</strong> make sense to optimize
modal models around error prone cases, especially when there is
minimal (and to me, mostly aesthetic) cost for doing so. I don’t think
these cases are that rare; jumping to the <code class="verbatim">n</code> th occurrence of a
character or selecting <code class="verbatim">n</code> lines is quite common!</p>
<h3 data-number="2.5" id="evil-integration-is-better"><span class="header-section-number">2.5</span> Evil integration is better</h3>
<p>In the “why not other emacs packages?” section, noctuid mentions that
emacs packages use different keybindings for different actions, and
that modal editing packages face a fundamental convention difference
for motion keys (jk vs C-n, C-p). This is a good point to mention
meow’s “motion” state, meant to address exactly this.</p>
<p>Essentially, it lets you override your motion keys in <em>every</em> mode that steals them
from you <em>automatically</em>. Evil expects you to remap your keys in every
one of your modes. Meow decides which modes to use motion in using a
<a href="https://github.com/meow-edit/meow/blob/3247b9d4f2b46bcf8d216857a59d67dd416dcdb9/meow-helpers.el#L237-L261">funny little heuristic</a> that checks whether keys self-insert into the
buffer and recursively against a predefined list of parent modes. Any
command that’s hidden is rebound under the <code class="verbatim">Hyper</code> modifier, So, if
you need to use the command that used to be bound to your motion keys, you
can bind <code class="verbatim">H-&lt;key&gt;</code> under your leader prefix. It’s a dead simple idea,
and it’ll always work.</p>
<p>While motion works for interaction-style packages like elfeed and
magit, unfortunately, this is ultimately a valid criticism. Meow is
forced to adapt to packages that nontrivially change your <em>editing</em>
experience itself, like company, polymode, sly and cider to name a
few. For these, meow comes with some “shims” that mostly just turn on
the motion mode when its needed. Inevitably, this leads to bad user
experience with some missed packages – but luckily, most
compatibility issues are trivially solved by just turning on motion
mode when it’s necessary, and indeed most shims that meow has do just
that.</p>
<h2 data-number="3" id="ending-thoughts"><span class="header-section-number">3</span> Ending thoughts</h2>
<p>Noctuid’s post is 6 years old, and my response is obviously unfair since
they’re writing about kakoune, and I’m talking about a modern package
that has had the chance to learn from the many modal editing
packages. Still, many of the critiques are about kakoune’s model
itself, which meow uses. I still think it’s a good idea, or at least
surely not a “a broken solution to a non-issue.” The instantaneous
feedback and visual selections cost is mostly aesthetic, with a
benefit of making selection errors trivial to notice and fix before
acting on them.</p>
<p>At the end of the day, people edit differently – editors should be
molded to the desires of the users, not the other way around.</p>

  </section>
</article>
]]></description>
    <pubDate>Mon, 29 Jan 2024 00:00:00 UT</pubDate>
    <guid>https://esrh.me/posts/2024-01-29-meow-response.html</guid>
    <dc:creator>Eshan Ramesh</dc:creator>
</item>

    </channel>
</rss>