<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://gosha.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://gosha.net/" rel="alternate" type="text/html" /><updated>2026-04-05T23:29:03+01:00</updated><id>https://gosha.net/feed.xml</id><title type="html">Gosha Tcherednitchenko</title><subtitle>Photography, design, writing, and software projects by Gosha Tcherednitchenko</subtitle><author><name>Gosha Tcherednitchenko</name></author><entry><title type="html">Friars, tigers, artichokes</title><link href="https://gosha.net/2026/lullabies/" rel="alternate" type="text/html" title="Friars, tigers, artichokes" /><published>2026-03-29T22:24:02+01:00</published><updated>2026-03-29T22:24:02+01:00</updated><id>https://gosha.net/2026/lullabies</id><content type="html" xml:base="https://gosha.net/2026/lullabies/"><![CDATA[<p>In our family, we have four languages between us: English, Mandarin Chinese, French, and Russian. When N. was born, I wanted to sing lullabies to her in all four.</p>

<p><em>Brother John</em>, a classic of the genre, has served us well.</p>

<p>The English version is well known:</p>

<div class="columns table">
  <div class="col">
    <header>EN</header>
    <div class="col-body">
      Are you sleeping,<br />
      Are you sleeping,<br />
      Brother John?<br />
      Brother John?<br />
      Morning bells are ringing,<br />
      Morning bells are ringing.<br />
      Ding ding dong,<br />
      Ding ding dong
    </div>
  </div>
</div>

<p>It’s basically an almost word-for-word adaptation of the French version, which is the original:</p>

<div class="columns table double">
  <div class="col">
    <header>FR</header>
    <div class="col-body">
      Frère Jacques,<br />
      Frère Jacques<br />
      Dormez-vous?<br />
      Dormez-vous?<br />
      Sonnez les matines,<br />
      Sonnez les matines!<br />
      Ding ding dong,<br />
      Ding ding dong
    </div>
  </div>
  <div class="col">
    <header>EN</header>
    <div class="col-body">
      Brother Jack,<br />
      Brother Jack,<br />
      Are you sleeping?<br />
      Are you sleeping?<br />
      Ring the matins bells,<br />
      Ring the matins bells!<br />
      Ding ding dong,<br />
      Ding ding dong
    </div>
  </div>
</div>

<p>The Russian version I use, suggested by my dad, is not the canonical translation (one does exist), but rather a cheeky reworking by Soviet music students, which cracks me up each time I really think about it:</p>

<div class="columns table double">
  <div class="col">
    <header>RU</header>
    <div class="col-body">
      Артишоки,<br />
      Артишоки,<br />
      И миндаль!<br />
      И миндаль!<br />
      Не растут на попе,<br />
      Не растут на попе.<br />
      Очень жаль.<br />
      Очень жаль.
    </div>
  </div>
  <div class="col">
    <header>EN</header>
    <div class="col-body">
      Artichokes,<br />
      Artichokes,<br />
      And almonds!<br />
      And almonds!<br />
      Don't grow on one's butt,<br />
      Don't grow on one's butt.<br />
      A great pity.<br />
      A great pity.
    </div>
  </div>
</div>

<p>And the Chinese version is really fun too – an adaptation of the melody with a completely different story, well known to kids growing up in Taiwan in the 90s:</p>

<div class="columns table triple">
  <div class="col">
    <header>ZH</header>
    <div class="col-body">
      兩隻老虎，<br />
      兩隻老虎，<br />
      跑得快，<br />
      跑得快！<br />
      一隻沒有眼睛！<br />
      一隻沒有尾巴！<br />
      真奇怪！<br />
      真奇怪！
    </div>
  </div>
  <div class="col">
    <header>Pinyin</header>
    <div class="col-body">
      Liǎng zhī lǎo hǔ,<br />
      Liǎng zhī lǎo hǔ,<br />
      Pǎo dé kuài,<br />
      Pǎo dé kuài!<br />
      Yī zhī méi yǒu yǎn jīng!<br />
      Yī zhī méi yǒu wěi bā!<br />
      Zhēn qí guài!<br />
      Zhēn qí guài!
    </div>
  </div>
  <div class="col">
    <header>EN</header>
    <div class="col-body">
      Two tigers,<br />
      Two tigers,<br />
      Running fast,<br />
      Running fast!<br />
      One doesn't have eyes!<br />
      One doesn't have a tail!<br />
      How strange!<br />
      How strange!
    </div>
  </div>
</div>

<p>N. loved the Chinese version especially when she was smaller, and now E. is enjoying the songs as well.</p>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="family" /><category term="kids" /><category term="personal" /><category term="parenting" /><category term="music" /><summary type="html"><![CDATA[In our family, we have four languages between us: English, Mandarin Chinese, French, and Russian. When N. was born, I wanted to sing lullabies to her in all four.]]></summary></entry><entry><title type="html">My Delica obsession</title><link href="https://gosha.net/2026/delica/" rel="alternate" type="text/html" title="My Delica obsession" /><published>2026-02-21T01:24:02+00:00</published><updated>2026-02-21T01:24:02+00:00</updated><id>https://gosha.net/2026/delica</id><content type="html" xml:base="https://gosha.net/2026/delica/"><![CDATA[<p>The Mitsubishi Delica is one of the most popular (if not <em>the</em> most popular) light trucks in Taiwan. The iconic L300 variant (aka the <a href="https://en.wikipedia.org/wiki/Mitsubishi_Delica#Third_generation_(1986)">Third Generation</a>)<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> has been manufactured here by China Motor Corporation (CMC), Mitsubishi’s local manufacturing partner, and is ubiquitous on the island. Even though the L300 has been discontinued in Japan in 1998, CMC has continued producing and modernising versions of the same design in Taiwan, and it is still possible to <a href="https://www.mitsubishi-motors.com.tw/delicapu">purchase it new</a><sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>.</p>

<p>I’ve started noticing the Delicas on our last trip, but this time around, hunting for them has become a bit of an obsession: I’ve been collecting different variants and liveries (my favourite is the very colourful school bus version!), which I’m sharing below.</p>

<p>This might yet turn into a proper project with time, but for now, enjoy the photos!</p>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_09.jpg" alt="A white Delica truck with a green tarp on a parking lot in Tainan" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_19.jpg" alt="Driver side front view of a classic blue Delica truck" />
  </div>
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_21.jpg" alt="Detail of the cab of a clasic blue Delica truck loaded with cardboard" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_17.jpg" alt="A 2022 Delica van used as a kindergarten school bus in Taichun" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_03.jpg" alt="A white pick up truck Delica variant participating in some road works in New Taipei City" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_07.jpg" alt="A modern dark blue pick up truck variant parked in a building in Tainan" />
  </div>
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_02.jpg" alt="A vintage van variant in silver, with a busted passenger side turn signal parked in New Taipei City" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_14.jpg" alt="A white and orange van version in Jiayi" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_10.jpg" alt="A modern van version with a roof rack in Tainan" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_15.jpg" alt="An older white refrigerated cab version on the streets of Jiayi" />
  </div>
</div>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2026/delica/delica_16.jpg" alt="A van serving as a kindergarten school bus in central Taichung" />
  </div>
</div>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>The L300 also has a 4WD campervan version, the <a href="https://sabukaru.online/articles/a-versatile-beast-the-mitsubishi-delica-star-wagon-l300">StarWagon</a>, which is very popular in the west with a certain outdoorsy crowd, but this is not what we’re going to be talking about here. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>Although Mitsubishi and <a href="https://www.cmc-motor.com/layout3.php?name=D260">CMC</a> both sell the car under their respective brands, both are manufactured by CMC! <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="taiwan" /><category term="photography" /><category term="delica" /><category term="motoring" /><category term="infrastructure" /><category term="ethnography" /><category term="stuff I like" /><summary type="html"><![CDATA[The Mitsubishi Delica is one of the most popular (if not the most popular) light trucks in Taiwan. The iconic L300 variant (aka the Third Generation)1 has been manufactured here by China Motor Corporation (CMC), Mitsubishi’s local manufacturing partner, and is ubiquitous on the island. Even though the L300 has been discontinued in Japan in 1998, CMC has continued producing and modernising versions of the same design in Taiwan, and it is still possible to purchase it new2. The L300 also has a 4WD campervan version, the StarWagon, which is very popular in the west with a certain outdoorsy crowd, but this is not what we’re going to be talking about here. &#8617; Although Mitsubishi and CMC both sell the car under their respective brands, both are manufactured by CMC! &#8617;]]></summary></entry><entry><title type="html">K-Pop Demon Hunters is super cool</title><link href="https://gosha.net/2026/kpdh/" rel="alternate" type="text/html" title="K-Pop Demon Hunters is super cool" /><published>2026-01-31T01:24:02+00:00</published><updated>2026-01-31T01:24:02+00:00</updated><id>https://gosha.net/2026/kpdh</id><content type="html" xml:base="https://gosha.net/2026/kpdh/"><![CDATA[<figure>
  <img src="/assets/images/posts/2026/kpdh/kpdh.jpg" alt="Mira, Rumi, and Zoey in the epilogue" />
  <figcaption>Mira, Rumi, and Zoey, the protagonists, in the epilogue (Image &copy; Netflix)</figcaption>
</figure>

<p><a href="https://en.wikipedia.org/wiki/KPop_Demon_Hunters"><em>K-Pop Demon Hunters</em></a> (aka KPDH) sneaked up on me via my daughter: she’s heard the songs at her nursery, and started requesting them in the car. The songs were catchy; I ended up watching the film a few weeks later.</p>

<p>And wow, the film was really great! I became a fan.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>I love a good found family narrative, and KPDH is a great example of one. Rumi, Mira, and Zoey come together for a shared purpose (being pop stars! hunting demons!), and find community and acceptance with each other, despite each bearing the burden of trauma. Is it the nerdy immigrant kid in me that loves this kind of narrative? Probably. It feels super warm, and comforting.</p>

<p>Trauma comes hands in hand with shame, which is another central topic of the film, and it’s beautifully handled. The best analysis I’ve seen is this video from <a href="https://www.youtube.com/@CinemaTherapyShow">Cinema Therapy</a>, which I wholeheartedly recommend you watch:</p>

<div class="video-container">
  <iframe class="yt-embed" src="https://www.youtube.com/embed/-Moo6eTKkZM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
</div>

<p>(The channel also has <a href="https://www.youtube.com/watch?v=zzJ1Httk78c">another video</a>, focused on the HUNTR/X girls specifically, which is also really great)</p>

<p>It’s also clear that the film is made by people who care very much about their work.</p>

<p>The visuals are top notch: some of the <a href="https://www.instagram.com/mingjuechen/">artists</a> have <a href="https://www.instagram.com/p/DNold3dSahu/">posted</a> <a href="https://www.celine-kim.com/455831477825">their</a> <a href="https://www.scottwatanabeart.com/kpop-demon-hunters">production</a> <a href="https://www.instagram.com/p/DLIIeyGxVkk/">work</a>, and there’s <a href="https://theartofkpopdemonhunters.com/">a whole artbook online!</a>. Exploring all that actually led to me rekindling a very old interest in drawing and painting, and I’ve since started sketching with ink and colour pencils, which feels really great after many years.</p>

<p>The music plays a very important role in the film, and is exceptionally made, too. The songs have been stuck at the top of the global charts for months, and it’s no wonder: the soundtrack had some of k-pop’s biggest names working on it, just one example being Teddy Park of Black Label. This led me into an <a href="https://merveilles.town/tags/GoshaDoesKpop">ongoing deep dive into k-pop</a>, which has been fun and rewarding<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>.</p>

<p>I’ve also been reading tons of KPDH fanfiction, via randomly discovering <a href="https://en.wikipedia.org/wiki/Archive_of_Our_Own">the incredible project</a> that is <a href="https://archiveofourown.org/">An Archive Of Our Own</a> (aka AO3) in a random Fedi post. I haven’t read fanfic since my teenage years, and while the overall quality can vary, some works are very well written, and worth exploring. A favourite example is <a href="https://archiveofourown.org/works/68306256/chapters/176747176">the first chapter of Hindsight</a>, by <a href="https://archiveofourown.org/users/BigFigNewton/pseuds/BigFigNewton">BigFigNewton</a>, which is a really fun take on an important scene of the film.</p>

<p>I’m grateful KPDH found me when it did, and I’m grateful for the expanded worldview it brought me. The sequel has already <a href="https://variety.com/2025/film/news/kpop-demon-hunters-2-2029-release-1236570536/">been announced for 2029</a>, and I’m sure there will be other stories told in the same universe by the same crew in the meantime (after all, KPDH has been nominated for an Oscar!). I’m looking forward to that!</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>When I was a teenager, it wasn’t unusual for me to be a real, die-hard fan of stuff. I was a fan of Star Wars and the Lord of the Rings, I knew all the lore there was to know about both franchises. Later, I was a fan of Neon Genesis Evangelion, and Cowboy Bebop. But it’s been many years since it’s hit me this hard! <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>For those in the know, I’m more BLINK than ARMY, though I’ve also enjoyed Le Sserafim, Aespa, EXID, and of course PSY! <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="kpop demon hunters" /><category term="art" /><category term="drawing" /><category term="animation" /><category term="media" /><category term="kpop" /><category term="music" /><category term="personal" /><category term="stuff I like" /><summary type="html"><![CDATA[Mira, Rumi, and Zoey, the protagonists, in the epilogue (Image &copy; Netflix)]]></summary></entry><entry><title type="html">Now page update</title><link href="https://gosha.net/2025/now-v5/" rel="alternate" type="text/html" title="Now page update" /><published>2025-11-05T22:00:00+00:00</published><updated>2025-11-05T22:00:00+00:00</updated><id>https://gosha.net/2025/now-v5</id><content type="html" xml:base="https://gosha.net/2025/now-v5/"><![CDATA[<p>Updated the <a href="/now">Now page</a>, archiving the contents below for posterity.</p>

<hr />

<h2 id="looking-for-work">Looking for work</h2>

<p>After a 4-months stint at Clausebase where I worked on really interesting natural language processing projects and some LLM-powered workflows, I am once again looking for work.</p>

<p>I would like to spend the next few years at a stable, friendly team where I could work on hard problems, be they technical or organisational.</p>

<p>I’ve added <a href="/hire">a page to this website</a> to show off my skills and experience, please take a look and <a href="mailto:gosha@gosha.net">reach out</a> if your team could use my expertise.</p>

<h2 id="parenting">Parenting</h2>

<p>E. was born in June, and has been delighting us ever since. It’s been a lot of fun to get to know him, and we’re slowly getting used to being a family of four. It’s a big change for all of us, but especially for N., who is now three years old, and has been adapting to her new identity as a big sister. It hasn’t always been easy for her, but she’s been brilliant.</p>

<p>Same as I have done with N., I’m documenting the first year of E.’s life with daily instant photographs.</p>

<h2 id="making-progress-on-parts">Making progress on Parts</h2>

<p>Together with my partner, an <a href="https://en.wikipedia.org/wiki/Internal_Family_Systems_Model">Internal Family Systems</a> therapist, we’re building <a href="https://parts.ifs.tools">Parts</a>, a parts mapping tool for IFS therapists and their clients.</p>

<p>Progress has been slow with the birth of our son and the previous job hunt, but I’m slowly starting to work on it again, and have actually started building <a href="https://github.com/apossiblespace/minigraph">Minigraph</a>, our own interactive graph editor, which is the piece of UI that’s at the very core of Parts.</p>

<h2 id="trying-to-get-good-at-clojure">Trying to get good at Clojure</h2>

<p>At the suggestion of my friend BG, I’ve been doing the <a href="https://4clojure.oxal.org/">4ever-clojure exercises</a>, looking only at the official Clojure docs and the Clojure source code. It’s been slow going (like everything else these days), but I’m about 35% through, and it’s been great fun.</p>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="now" /><category term="meta" /><summary type="html"><![CDATA[Updated the Now page, archiving the contents below for posterity.]]></summary></entry><entry><title type="html">The family grows</title><link href="https://gosha.net/2025/son/" rel="alternate" type="text/html" title="The family grows" /><published>2025-09-13T23:24:02+01:00</published><updated>2025-09-13T23:24:02+01:00</updated><id>https://gosha.net/2025/son</id><content type="html" xml:base="https://gosha.net/2025/son/"><![CDATA[<figure>
  <img src="/assets/images/posts/2025/son/hand.jpg" alt="A baby's hand curled into a tiny fist" />
  <figcaption>A tiny fist</figcaption>
</figure>

<p>Our son, E., was born in June; the sweetest, happiest baby I’ve ever seen. We are now parents of two.</p>

<p>I’ve been trying, and failing, to write something meaningful on the occasion of his birth: it’s hard to find the free time, and the focus, to go as deep into this topic as I want.</p>

<p>So I’m putting this up as a placeholder for now: E. was born, he’s healthy, and grows well. It’s all we could ask for. I’m sure I will have much more to say later.</p>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="parenting" /><category term="placeholder" /><category term="e" /><category term="family" /><summary type="html"><![CDATA[A tiny fist]]></summary></entry><entry><title type="html">Effect: using effect-language-service in Emacs</title><link href="https://gosha.net/2025/effect-ls-emacs/" rel="alternate" type="text/html" title="Effect: using effect-language-service in Emacs" /><published>2025-07-16T13:31:13+01:00</published><updated>2025-07-16T13:31:13+01:00</updated><id>https://gosha.net/2025/effect-ls-emacs</id><content type="html" xml:base="https://gosha.net/2025/effect-ls-emacs/"><![CDATA[<p>In my last <a href="/2025/sorbet-emacs">lsp-related post</a>, I wrote that I wasn’t a huge fan of static type checking. Well, that’s changed: I’ve tried Haskell (by building <a href="https://github.com/goshatch/ploy">a simple Scheme implementation</a>), and more recently, as part of a series of job interviews, I learned about <a href="https://effect.website">Effect</a>.</p>

<p>The JavaScript Extended Universe has never been my favourite part of the programming world, but Effect has forced me to reconsider. The library (think missing stdlib for TypeScript, or Haskell-but-make-it-TypeScript) is taking the TypeScript world by storm, and if you’re frustrated with JS/TS, it’s worth a look.</p>

<h2 id="preparation">Preparation</h2>

<p>Effect comes with a <a href="https://github.com/Effect-TS/language-service">Language Service</a>, packaged as a plugin to <code class="language-plaintext highlighter-rouge">typescript-language-server</code>. Getting it to work is straightforward in VSCode, but needs some extra steps in Emacs.</p>

<p>Follow that project README by installing the <code class="language-plaintext highlighter-rouge">@effect/language-service</code> package to your dev dependencies, and adding the relevant plugin configuration to your <code class="language-plaintext highlighter-rouge">tsconfig.json</code> file.</p>

<h2 id="getting-it-to-work-in-emacs">Getting it to work in Emacs</h2>

<p>The Emacs typescript LSP unfortunately doesn’t load its plugins configuration directly from <code class="language-plaintext highlighter-rouge">tsconfig.json</code> (why?), but instead looks into a variable called <code class="language-plaintext highlighter-rouge">lsp-clients-typescript-plugins</code>, which contains a plist of plugins to load.</p>

<p>It’s possible to configure this on a per-project basis by adding a <code class="language-plaintext highlighter-rouge">.dir-locals.el</code> file at the root of your project. For <code class="language-plaintext highlighter-rouge">effect-language-service</code>, it would contain something like this:</p>

<div class="language-elisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">((</span><span class="nv">typescript-mode</span>
  <span class="o">.</span> <span class="p">((</span><span class="nb">eval</span> <span class="o">.</span>
           <span class="p">(</span><span class="nv">setq-local</span>
            <span class="nv">lsp-clients-typescript-plugins</span>
            <span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">root</span> <span class="p">(</span><span class="nv">project-root</span> <span class="p">(</span><span class="nv">project-current</span><span class="p">))))</span>
              <span class="p">(</span><span class="nb">when</span> <span class="nv">root</span>
                <span class="p">(</span><span class="nb">vector</span>
                 <span class="p">(</span><span class="nb">list</span> <span class="ss">:name</span> <span class="s">"@effect/language-service"</span>
                       <span class="ss">:location</span> <span class="p">(</span><span class="nv">expand-file-name</span>
                                  <span class="s">"node_modules/@effect/language-service"</span>
                                  <span class="nv">root</span><span class="p">))))))))))</span>
</code></pre></div></div>

<p>What’s happening here:</p>

<ol>
  <li>When the <code class="language-plaintext highlighter-rouge">typescript-mode</code> is activated in this project,</li>
  <li>We set the buffer-local version of the <code class="language-plaintext highlighter-rouge">lsp-clients-typescript-plugins</code> variable</li>
  <li>To a vector that contains one plist that specifies the name of the plugin and its location</li>
</ol>

<p>After adding this <code class="language-plaintext highlighter-rouge">.dir-locals.el</code> file to your project, revert a project buffer (<code class="language-plaintext highlighter-rouge">M-x revert-buffer</code>) for the file to be picked up by Emacs, then restart the LSP workspace (<code class="language-plaintext highlighter-rouge">M-x lsp-workspace-restart</code>).</p>

<p>Enjoy the <a href="https://github.com/Effect-TS/language-service?tab=readme-ov-file#provided-functionalities">Effect-specific features</a> in Emacs!</p>

<figure>
<img src="/assets/images/posts/2025/effect-ls-emacs/emacs-screenshot.png" alt="The effect-language-service in action in Emacs" />
<figcaption><code>effect-language-service</code> picking up a botched Effect</figcaption>
</figure>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="programming" /><category term="emacs" /><category term="doom" /><category term="effect" /><category term="effect-ts" /><category term="effect-language-service" /><category term="lsp" /><category term="typescript" /><summary type="html"><![CDATA[In my last lsp-related post, I wrote that I wasn’t a huge fan of static type checking. Well, that’s changed: I’ve tried Haskell (by building a simple Scheme implementation), and more recently, as part of a series of job interviews, I learned about Effect.]]></summary></entry><entry><title type="html">Now page update</title><link href="https://gosha.net/2025/now-v4/" rel="alternate" type="text/html" title="Now page update" /><published>2025-06-12T07:10:00+01:00</published><updated>2025-06-12T07:10:00+01:00</updated><id>https://gosha.net/2025/now-v4</id><content type="html" xml:base="https://gosha.net/2025/now-v4/"><![CDATA[<p>Updated the <a href="/now">Now page</a>, archiving the contents below for posterity.</p>

<hr />

<h2 id="waiting-for-our-family-to-grow">Waiting for our family to grow</h2>

<p>My partner and I are expecting our second child to be born any day now :) To say I’m thrilled is an understatement.</p>

<h2 id="looking-for-work">Looking for work</h2>

<p>My contract got caught in a round of layoffs, so I am now hunting for a new job. I’ve put together a <a href="https://hire.gosha.net">Hire Gosha!</a> website for job hunting purposes, check it out, spread the word, and please <a href="mailto:mail@gosha.net">let me know</a> if you (or anyone you know) need a senior full-stack engineer who can ship fast.</p>

<h2 id="making-progress-on-parts">Making progress on Parts</h2>

<p>Together with my partner, an <a href="https://en.wikipedia.org/wiki/Internal_Family_Systems_Model">Internal Family Systems</a> therapist, we’re building <a href="https://parts.ifs.tools">Parts</a>, a parts mapping tool for IFS therapists and their clients. We have made a lot of progress on Parts, and we are going to be asking the people who have signed up to the waiting list to start testing it soon.</p>

<p>I’m excited to see if this project will fly!</p>

<h2 id="exploring-programming-languages">Exploring programming languages</h2>

<p>In addition to getting comfortable with Clojure and ClojureScript, I’ve been poking at some other programming languages recently, mostly of the functional and strongly typed variety. The most fun of those has been <a href="https://www.haskell.org/">Haskell</a>. I’ve written a little <a href="https://github.com/goshatch/ploy">Scheme interpreter</a> in it, which has been a really enjoyable experience. I’d like to get a chance to use Haskell more!</p>

<h2 id="studying-computer-science-and-math">Studying computer science and math</h2>

<p>I’ve been very slowly making my way through the legendary computer science textbook, <a href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs">Structure and Interpretation of Computer Programs</a> (2nd ed.), by Abelson, Sussman, and Sussman. Although my progress is slow, it is also immensely satisfying, and I hope that brushing up on comp-sci fundamentals (and math — I’ve been going through fundamental courses on Khan Academy) will in the future allow me to tackle harder, more interesting problems in computing.</p>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="now" /><category term="meta" /><summary type="html"><![CDATA[Updated the Now page, archiving the contents below for posterity.]]></summary></entry><entry><title type="html">reClojure 2025</title><link href="https://gosha.net/2025/reclojure/" rel="alternate" type="text/html" title="reClojure 2025" /><published>2025-05-27T09:48:53+01:00</published><updated>2025-05-27T09:48:53+01:00</updated><id>https://gosha.net/2025/reclojure</id><content type="html" xml:base="https://gosha.net/2025/reclojure/"><![CDATA[<figure>
<img src="/assets/images/posts/2025/reclojure/badge.jpg" alt="A conference attendee badge on a desk" />
<figcaption>My reClojure 2025 badge</figcaption>
</figure>

<p>I went to my first Clojure conference yesterday — my first tech conference since Rails Conf 2012. It was <a href="https://www.reclojure.org/">reClojure</a> in London, and it made me <em>think</em>.</p>

<p>Talks were generally really good, but a couple landed particularly well.</p>

<p><a href="https://replicant.fun">Replicant</a> creator Christian Johansen’s talk hit close to home: I’m building <a href="https://parts.ifs.tools">Parts</a>, and he demoed what UI development (with Replicant) can look like when one takes functional programming seriously<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>. He also introduced a couple of interesting tools, including <a href="https://github.com/cjohansen/portfolio">Portfolio</a>, a Storybook-like tool for Clojure, letting you test components visually and separately from each other.</p>

<p>I can’t use Replicant or Portfolio <em>yet</em>, as Parts is deep in the React ecosystem with <a href="https://reactflow.dev">React Flow</a> holding the whole thing together, but the talk was a needed reminder: modern UI doesn’t have to mean React and its complexities. Simplicity and testability can win.</p>

<p>Another talk I liked was on brain/computer interfaces, by <a href="https://lorelailyons.me/">Lorelai Lyons</a>, who cracked open a field that felt like sci-fi to me via an impressive growth mindset. “You can just do things”, was my takeaway, “and share what you do, and be open about what you don’t know, and be excited about it all”. I wasn’t expecting to leave thinking about brain/computer interfaces, but Lorelai’s talk put them on my radar. She made the field feel accessible, like something weird and wonderful I could just start engaging with. That felt rare and freeing!</p>

<hr />

<p>On the way home from the conference, I made this post on my socials:</p>

<blockquote lang="en" cite="https://merveilles.town/@gosha/114574818156410355" data-source="fediverse">
  <p>A day at <a href="https://merveilles.town/tags/reClojure" class="mention hashtag" rel="tag">#<span>reClojure</span></a>, listening to inspiring talks &amp; talking to inspiring nerds, made me realise just how burnt out I am on the whole field of CRUD-adjacent webdev. I feel I need some kind of reset, to start working on more challenging, more meaningful problems 🤔</p>
  <footer>
     — gosha 🏴‍☠️ (@gosha@merveilles.town) <a href="https://merveilles.town/@gosha/114574818156410355"><time datetime="2025-05-26T15:23:02.125Z">26/05/2025, 16:23:02</time></a>
  </footer>
</blockquote>

<p>This wasn’t nothing. Everyone who gave talks (or just showed up) brought this infectious kind of energy, the energy of people who care about their work, deeply. It made me realise that I need a lot more of this energy in my own life.</p>

<p>I’ve been circling this particular kind of burnout for a few years now, trying not to name it. Attending reClojure wasn’t a magic fix for all my problems, but it nudged me in what feels like a positive direction. Maybe that’s the start of doing some things differently.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>A benefit of a truly functional way to build UI is that everything is a function, and so everything can be tested as such. And indeed, this is a big focus of Replicant and a big part of the appeal to me, as UI testing is often rather brittle. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="clojure" /><category term="conference" /><category term="programming" /><category term="socialising" /><category term="’reflection’" /><category term="london" /><summary type="html"><![CDATA[My reClojure 2025 badge]]></summary></entry><entry><title type="html">Ruby: sane sorbet-ls setup in Emacs</title><link href="https://gosha.net/2025/sorbet-emacs/" rel="alternate" type="text/html" title="Ruby: sane sorbet-ls setup in Emacs" /><published>2025-05-14T21:43:13+01:00</published><updated>2025-05-14T21:43:13+01:00</updated><id>https://gosha.net/2025/sorbet-emacs</id><content type="html" xml:base="https://gosha.net/2025/sorbet-emacs/"><![CDATA[<p>I’m generally not a huge fan of static type checking, so I do not use <a href="https://sorbet.org/">Sorbet</a> in my personal Ruby and Rails projects. At work, however, we do use it: our project includes Sorbet in its <code class="language-plaintext highlighter-rouge">Gemfile</code>.</p>

<p>This creates a situation where I would sometimes have two projects open in Emacs: one with Sorbet, and one without. When working on the project that does not use Sorbet, each new open buffer would try to start <code class="language-plaintext highlighter-rouge">sorbet-ls</code>, and fail, complaining about not being able to find the <code class="language-plaintext highlighter-rouge">srb</code> executable in the project bundle.</p>

<p>It’s of course possible to disable the <code class="language-plaintext highlighter-rouge">lsp-mode</code> client for <code class="language-plaintext highlighter-rouge">sorbet-ls</code> entirely, by adding it to <code class="language-plaintext highlighter-rouge">lsp-disabled-clients</code>, but this will also disable it in the project that does use Sorbet.</p>

<p>Below is the workaround I’ve come up with, I publish it here in the hopes it will be useful for someone else.</p>

<ol>
  <li>We disable the default <code class="language-plaintext highlighter-rouge">lsp-mode</code> client config for <code class="language-plaintext highlighter-rouge">sorbet-ls</code> so it won’t auto-start everywhere.</li>
  <li>We create a function that checks whether the project associated with the current buffer uses Sorbet. It checks for the presence of a <code class="language-plaintext highlighter-rouge">sorbet</code> directory, and for any mention of Sorbet in the <code class="language-plaintext highlighter-rouge">Gemfile.lock</code> file.</li>
  <li>We register a new LSP client that will start in all ruby buffers, but only if that buffer belongs to a project that uses Sorbet.</li>
</ol>

<p>Please note that I’m using Doom Emacs (which provides the <code class="language-plaintext highlighter-rouge">after!</code> macro), and <code class="language-plaintext highlighter-rouge">lsp-mode</code> rather than <code class="language-plaintext highlighter-rouge">eglot</code>.</p>

<div class="language-elisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nv">after!</span> <span class="nv">lsp-mode</span>
  <span class="p">(</span><span class="nb">require</span> <span class="ss">'lsp-sorbet</span><span class="p">)</span>
  <span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'lsp-disabled-clients</span> <span class="ss">'sorbet-ls</span><span class="p">)</span>

  <span class="p">(</span><span class="nb">defun</span> <span class="nv">gt/project-has-sorbet-p</span> <span class="p">()</span>
    <span class="s">"Does this project use Sorbet?"</span>
    <span class="p">(</span><span class="nb">or</span> <span class="p">(</span><span class="nv">locate-dominating-file</span> <span class="nv">default-directory</span> <span class="s">"sorbet"</span><span class="p">)</span>
        <span class="p">(</span><span class="nv">when-let*</span> <span class="p">((</span><span class="nv">root</span> <span class="p">(</span><span class="nv">locate-dominating-file</span> <span class="nv">default-directory</span> <span class="s">"Gemfile.lock"</span><span class="p">))</span>
                    <span class="p">(</span><span class="nv">gemfile-lock</span> <span class="p">(</span><span class="nv">expand-file-name</span> <span class="s">"Gemfile.lock"</span> <span class="nv">root</span><span class="p">)))</span>
          <span class="p">(</span><span class="nv">with-temp-buffer</span>
            <span class="p">(</span><span class="nv">insert-file-contents</span> <span class="nv">gemfile-lock</span><span class="p">)</span>
            <span class="p">(</span><span class="nv">search-forward-regexp</span> <span class="s">"^ *sorbet \\|^ *sorbet-static "</span> <span class="no">nil</span> <span class="no">t</span><span class="p">)))))</span>

  <span class="p">(</span><span class="nv">lsp-register-client</span>
   <span class="p">(</span><span class="nv">make-lsp-client</span>
    <span class="ss">:new-connection</span> <span class="p">(</span><span class="nv">lsp-stdio-connection</span>
                     <span class="p">(</span><span class="k">lambda</span> <span class="p">()</span>
                       <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nv">gt/project-has-sorbet-p</span><span class="p">)</span>
                         <span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nv">file-exists-p</span> <span class="s">"Gemfile"</span><span class="p">)</span>
                             <span class="o">'</span><span class="p">(</span><span class="s">"bundle"</span> <span class="s">"exec"</span> <span class="s">"srb"</span> <span class="s">"tc"</span> <span class="s">"--lsp"</span><span class="p">)</span>
                           <span class="o">'</span><span class="p">(</span><span class="s">"srb"</span> <span class="s">"tc"</span> <span class="s">"--lsp"</span><span class="p">)))))</span>
    <span class="ss">:activation-fn</span> <span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="nv">filename</span> <span class="nv">_mode</span><span class="p">)</span>
                     <span class="p">(</span><span class="nb">and</span> <span class="p">(</span><span class="nb">eq</span> <span class="nv">major-mode</span> <span class="ss">'ruby-mode</span><span class="p">)</span> <span class="p">(</span><span class="nv">gt/project-has-sorbet-p</span><span class="p">)))</span>
    <span class="ss">:priority</span> <span class="mi">-1</span>
    <span class="ss">:add-on?</span> <span class="no">t</span>
    <span class="ss">:server-id</span> <span class="ss">'gt/sorbet-ls</span><span class="p">)))</span>
</code></pre></div></div>

<p>Please adapt as needed, and do let me know if you’ve come up with a simpler and/or more elegant solution for this problem.</p>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="programming" /><category term="emacs" /><category term="doom" /><category term="sorbet" /><category term="sorbet-ls" /><category term="lsp" /><category term="ruby" /><category term="rails" /><summary type="html"><![CDATA[I’m generally not a huge fan of static type checking, so I do not use Sorbet in my personal Ruby and Rails projects. At work, however, we do use it: our project includes Sorbet in its Gemfile.]]></summary></entry><entry><title type="html">Simplifying how I work with photos</title><link href="https://gosha.net/2025/photo-workflow/" rel="alternate" type="text/html" title="Simplifying how I work with photos" /><published>2025-05-03T02:50:21+01:00</published><updated>2025-05-03T02:50:21+01:00</updated><id>https://gosha.net/2025/photo-workflow</id><content type="html" xml:base="https://gosha.net/2025/photo-workflow/"><![CDATA[<p>One thing that’s a lot on my mind these days is finding ways to <a href="/2025/out-with-ci-in-with-a-makefile">reduce complexity in my life</a>, and as we are now on our yearly visit to Taiwan, I’ve had the chance to do the same with my photographic life.</p>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2025/photo-workflow/taichung.jpg" alt="A small electronic goods shop in central Taichung, Taiwan." />
  </div>
  <div class="photo">
    <img src="/assets/images/posts/2025/photo-workflow/dongshi.jpg" alt="A rural scene in central Taiwan." />
  </div>
</div>

<p>Once upon a time, I had the ambition to become a Real Professional Photographer™, and built myself a workflow to match. It goes like this: all my raw files went into one giant Capture One library<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> that has everything neatly arranged into albums, with a 1-5 star rating for pictures. When I travelled, I created <a href="https://support.captureone.com/hc/en-us/articles/360003115137-The-Complete-Guide-to-Sessions-in-Capture-One">a new session</a> in Capture One, I’d download photos from my cameras every day, and I’d import the session into my giant library once we got back home. I’d export JPEGs to post on socials and this blessed website from Capture One.</p>

<p>I no longer hold this ambition, but I was still using this workflow pretty religiously, until recently.</p>

<hr />

<p>Nowadays, I shoot mainly with a <a href="https://www.ricoh-imaging.co.jp/english/products/gr-3/">Ricoh GR III</a> (a perfect camera for parents, but that’s a topic for another post), and mainly in programme (P) mode, in which the camera sets the shutter speed and aperture automatically.<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> I have also started saving JPEGs in addition to raw files, mainly because when we first got the camera, I couldn’t create a good colour profile for it to use in Capture One. These days, I’m trialing shooting JPEGs only, and I have a feeling it is going to stick.</p>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2025/photo-workflow/snack-shop.jpg" alt="A late night snack shop in New Taipei City, Taiwan." />
  </div>
</div>

<p>The GR3 JPEGs look <strong>good</strong>, and I found myself basically storing the raw files, untouched, and using the JPEGs for my needs. My needs are not that advanced: I’m not making massive prints, and I’m not spending hours fixing stuff in photoshop — the height of my ambition is to, one day, make <a href="/projects/publishing">some more books</a>. JPEG files are definitely good enough for this!</p>

<p>So this is what my setup looks like for this trip:</p>

<figure>
<img src="/assets/images/posts/2025/photo-workflow/setup.jpg" alt="A Ricoh GR III camera next to an iPhone running the GR Linker app" />
<figcaption>The current setup: Ricoh GR III + GR Linker on iPhone</figcaption>
</figure>

<p>I download JPEGs from the camera to my phone using the <a href="https://apps.apple.com/gb/app/gr-linker-image-sync/id1600925588">GR Linker</a> app. This app has a huge benefit over Ricoh’s own Image Sync app in that it makes downloading photos Not A Pain: it lets you use your phone to browse photos on your camera, and when you like one, a single tap will add it to a queue of items to download. This downloading happens in the background, and by the time you’re done browsing, usually your selects have already downloaded.</p>

<p>Ricoh’s app, by contrast, freezes the UI while photos download, so you have to first make the perfect selection of what you want to download from thumbnails, and then sit there like an idiot, remembering to tap the screen at regular intervals so that your phone doesn’t fall asleep and disconnect from the camera’s wifi.</p>

<p>I do still need to have the Ricoh app installed, because it keeps a Bluetooth connection active to the camera which enables geotagging, but that’s the only purpose it serves for me now.</p>

<hr />

<p>Once the photos have been downloaded to my phone, I work with them in Apple’s default Photos app. Instead of the 1-5 star rating, I just add the photos I like to the Favourites, and it’s more than enough to be able to quickly find them later. While the editing functionality is not as powerful as in Capture One, it’s also plenty good enough — the perspective correction tools deserving a special mention for how nice they are. The facial recognition and search engine are also very helpful for navigation.</p>

<p>A benefit of shooting only JPEGs is that photos take up much less space. Storage is affordable these days, and the SD card I have in the GR has a 128 GB capacity<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup>, which translates to about 7000 photos. This is more photos than I’m likely to take over the course of the trip, making bringing the laptop optional altogether, since I will not need to download photos to make space on the card.</p>

<div class="full-width-photos">
  <div class="photo">
    <img src="/assets/images/posts/2025/photo-workflow/taipei.jpg" alt="A family walking through the streets of central Taipei, Taiwan." />
  </div>
  <div class="photo">
    <img src="/assets/images/posts/2025/photo-workflow/3d-scan.jpg" alt="A toddler holding up the 3D scan photos of her future sibling" />
  </div>
</div>

<p>I’m very happy with this setup: I spend much less time messing around with tools, and much more time taking photos, and enjoying the results. I’m looking forward to seeing where this drive for simplification will take me next.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>The library’s grown in size to terabytes of data by now, so it lives on a NAS at home, that’s backed up into Amazon’s Glacier storage service. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>I was going to write here about how this is great for parents who need to pay attention to a toddler more than to fiddling with a camera, but the truth is that it’s just plain fun to point and shoot. I do use exposure compensation while shooting, and from time to time switch between 400 and 1600 ISO depending on the light conditions, but that’s the extent of it. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p>I am old enough to remember a time where this was an absolutely massive size for a computer’s hard drive, so an affordable SD card of this capacity feels, to me, like living in the future. Not flying cars, but close. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Gosha Tcherednitchenko</name></author><category term="photography" /><category term="taiwan" /><category term="travel" /><category term="captureone" /><category term="ricoh gr III" /><category term="’simplify’" /><summary type="html"><![CDATA[One thing that’s a lot on my mind these days is finding ways to reduce complexity in my life, and as we are now on our yearly visit to Taiwan, I’ve had the chance to do the same with my photographic life.]]></summary></entry></feed>