<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>A few words from Agical</title>
    <link>https://blog.agical.se/en/authors/peter-stromberg/</link>
    <description>(Agical's blog)</description>
    <image>
      <url>https://blog.agical.se//apple-touch-icon.png</url>
      <title>A few words from Agical</title>
      <link>https://blog.agical.se/en/authors/peter-stromberg/</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-EN</language>
    <copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright>
    <lastBuildDate>Fri, 23 May 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.agical.se/en/authors/peter-stromberg/" rel="self" type="application/rss+xml" />
    
        
        
        <item>
          <title>A rich poor man&#39;s CSS hot reload</title>
          
          <link>https://blog.agical.se/en/posts/a-rich-poor-man-x-s-css-hot-reload/</link>
          <pubDate>Fri, 23 May 2025 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/a-rich-poor-man-x-s-css-hot-reload/</guid>
          <description>&lt;p&gt;Hot reloading CSS can be as easy as
&lt;code&gt;(require .. :reload-all)&lt;/code&gt; followed by
&lt;code&gt;(spit css-file css)&lt;/code&gt;, at least if you add a file watcher.
😀&lt;/p&gt;
&lt;p&gt;I’m using &lt;a
href=&#34;https://github.com/thheller/shadow-cljs&#34;&gt;&lt;u&gt;shadow-cljs&lt;/u&gt;&lt;/a&gt;
for almost everything I do. Its hot-reloading of code is so damn good
that I have grown addicted to it and I now need moar hot reloading
everywhere in my life. shadow-cljs also &lt;a
href=&#34;https://shadow-cljs.github.io/docs/UsersGuide.html#_css_reloading&#34;&gt;&lt;u&gt;hot-reloads
css files&lt;/u&gt;&lt;/a&gt;, did you know?&lt;/p&gt;
&lt;p&gt;However, unless you hand-code the actual &lt;code&gt;.css&lt;/code&gt; files,
what remains is something that will rebuild them when their source code
changes. A poor, poor man uses &lt;a
href=&#34;https://sass-lang.com/&#34;&gt;&lt;u&gt;SASS&lt;/u&gt;&lt;/a&gt; or some similar huge
dependency for this. But a rich, poor man uses data instead of text. As
a Clojurian rich man (but I am repeating myself) I use the &lt;a
href=&#34;https://github.com/noprompt/garden&#34;&gt;&lt;u&gt;Garden CSS library&lt;/u&gt;&lt;/a&gt;.
Garden gives me a way to express CSS in Hiccup-ish data. It also comes
with a bunch of nice CSS utilities such as unit conversion and color
manipulation, making me miss SASS even less.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/a-rich-poor-man-x-s-css-hot-reload/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>The programming language doesn&#39;t matter, until it does</title>
          
          <link>https://blog.agical.se/en/posts/the-programming-language-doesn-x-t-matter--until-it-does/</link>
          <pubDate>Fri, 27 Sep 2024 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/the-programming-language-doesn-x-t-matter--until-it-does/</guid>
          <description>&lt;p&gt;On LinkedIn, a recipe for raking home the likes and cheering-ons is
to post about that the tools do not matter at all, only the people
matter.&lt;/p&gt;
&lt;p&gt;“Yay!”&lt;/p&gt;
&lt;p&gt;“Thanks for sharing!”&lt;/p&gt;
&lt;p&gt;“So insightful!”&lt;/p&gt;
&lt;p&gt;I call bullshit.&lt;/p&gt;
&lt;p&gt;&lt;img
src=&#34;https://blog.agical.se/images/the-programming-language-doesn-x-t-matter--until-it-does/image1.jpg&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Well, maybe it is true for some, but not for all, and certainly not
for me! To me people matter a ton, and so do tools. The amount of matter
is on the same order of magnitude for both. This is because I work as a
programmer for a reason. I think there is nothing more fun, thrilling,
and rewarding to do than to code. It’s where that creative part of me
gets its nourishment. As a programmer I create things &lt;em&gt;ex
nihilo&lt;/em&gt;. My ideas come into existence from under my fingertips, and
it is the most wonderful feeling. Also in my spare time you’ll find me
coding.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/the-programming-language-doesn-x-t-matter--until-it-does/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>There can be only one!</title>
          
          <link>https://blog.agical.se/en/posts/there-can-be-only-one/</link>
          <pubDate>Sat, 01 Jun 2024 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/there-can-be-only-one/</guid>
          <description>&lt;p&gt;Here is a stupid simple way to easily manage those UI elements of
which there can be only one opened at a time, such as application menus.
I call them &lt;a
href=&#34;https://en.wikipedia.org/wiki/Highlander_(film)&#34;&gt;&lt;u&gt;Highlander&lt;/u&gt;&lt;/a&gt;s.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.agical.se/images/there-can-be-only-one!/image1.jpg&#34; /&gt;&lt;/p&gt;
&lt;p&gt;My requirements are that I want no extra DOM elements, nor any extra
CSS, plus that the user’s intent should be honored, either if it is
intentionally closing the element or starting to interact with some
other element. (Say the menu is open and the user starts to drag
something somewhere else. That dragging should happen and the menu
should also close.)&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/there-can-be-only-one/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Keeping the :arglists of Clojure functions DRY</title>
          
          <link>https://blog.agical.se/en/posts/keeping-the--arglists-of-clojure-functions-dry/</link>
          <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/keeping-the--arglists-of-clojure-functions-dry/</guid>
          <description>&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;: &lt;code&gt;function-a&lt;/code&gt; takes the same
arguments as &lt;code&gt;function-b&lt;/code&gt;. In fact, &lt;code&gt;function-a&lt;/code&gt;
calls &lt;code&gt;function-b&lt;/code&gt;. Without too much synchronized updating of
the function signatures, I want &lt;code&gt;(doc function-a)&lt;/code&gt; to show me
the same argument lists as &lt;code&gt;(doc function-b)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The solution&lt;/strong&gt;: Use &lt;code&gt;:arglists&lt;/code&gt; in the
metadata of the function.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;defn &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;function-b&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[{&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:keys&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;println &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;defn &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;function-a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:arglists&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([{&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:keys&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}])}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;function-b&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s the TL;DR. Read on for some rationale, and for some nerdy
diving into the worlds of static and dynamic analysis.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/keeping-the--arglists-of-clojure-functions-dry/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>15 second Netlify deploy of a Rust mdBook</title>
          
          <link>https://blog.agical.se/en/posts/15-second-netlify-deploy-of-a-rust-mdbook/</link>
          <pubDate>Wed, 03 Jan 2024 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/15-second-netlify-deploy-of-a-rust-mdbook/</guid>
          <description>&lt;p&gt;I have been enjoying learning some &lt;a
href=&#34;https://www.rust-lang.org/&#34;&gt;&lt;u&gt;Rust&lt;/u&gt;&lt;/a&gt; and some &lt;a
href=&#34;https://macroquad.rs/&#34;&gt;&lt;u&gt;Macroquad&lt;/u&gt;&lt;/a&gt; game development via
&lt;a href=&#34;https://macroquad-introduktion.agical.se/&#34;&gt;&lt;u&gt;Olle Wreede’s
tutorial&lt;/u&gt;&lt;/a&gt; (Swedish only so far, sorry!). When I sent some pull
requests towards the tutorial I lacked a deployed version attached to
the PR. I decided to add that, and my goto for such things is &lt;a
href=&#34;https://www.netlify.com/&#34;&gt;&lt;u&gt;Netlify&lt;/u&gt;&lt;/a&gt;. However, the
tutorial is authored with &lt;a
href=&#34;https://rust-lang.github.io/mdBook/&#34;&gt;&lt;u&gt;mdBook&lt;/u&gt;&lt;/a&gt;, and there
doesn’t seem to be a straightforward way to get Netlify to build
this.&lt;/p&gt;
&lt;p&gt;&lt;img
src=&#34;https://blog.agical.se/images/15-second-netlify-deploy-of-a-rust-mdbook/image1.jpg&#34; /&gt;&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/15-second-netlify-deploy-of-a-rust-mdbook/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Why you should try Clojure Interactive Programming</title>
          
          <link>https://blog.agical.se/en/posts/why-you-should-try-clojure-interactive-programming/</link>
          <pubDate>Wed, 27 Dec 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/why-you-should-try-clojure-interactive-programming/</guid>
          <description>&lt;p&gt;&lt;a href=&#34;https://clojure.org&#34;&gt;&lt;u&gt;Clojure&lt;/u&gt;&lt;/a&gt; has a lot of things
going for it. To name just a few: Functional programming is the default.
Clojure makes it easy to keep data immutable. The language is small and
simple, and the programs you create stay smaller and simpler than with
most programming language environments.&lt;/p&gt;
&lt;p&gt;Still, perhaps Clojure’s super power is Interactive Programming. I.e.
&lt;em&gt;using the REPL to connect to, inspect, and modify the running
program as you are developing it&lt;/em&gt;. As a Clojure developer you can
leverage this power for fun and for profit. The Clojure REPL will
quickly let you verify that your changes are in the right direction, or
give you early feedback that you need to think differently about the
problem.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/why-you-should-try-clojure-interactive-programming/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>VS Code runCommands for multi-commands keyboard shortcuts</title>
          
          <link>https://blog.agical.se/en/posts/vs-code-runcommands-for-multi-commands-keyboard-shortcuts/</link>
          <pubDate>Mon, 27 Nov 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/vs-code-runcommands-for-multi-commands-keyboard-shortcuts/</guid>
          <description>&lt;p&gt;&lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;&lt;u&gt;Visual Studio
Code&lt;/u&gt;&lt;/a&gt; has a command for stringing multiple commands together:
&lt;code&gt;runCommands&lt;/code&gt;. It’s designed to be used from keyboard
shortcuts. Here’s an example:&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/vs-code-runcommands-for-multi-commands-keyboard-shortcuts/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>To ChatGPT a picture says more than a thousand words</title>
          
          <link>https://blog.agical.se/en/posts/to-chatgpt-a-picture-says-more-than-a-thousand-words/</link>
          <pubDate>Thu, 26 Oct 2023 11:20:00 +0200</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/to-chatgpt-a-picture-says-more-than-a-thousand-words/</guid>
          <description>&lt;p&gt;One of the great usages I get from generative AI is to use it for
checking that my messages come across as I want them to do. ChatGPT,
Midjourney and their likes are trained from vast amounts of human
communication. To note how they interpret something gets to be a measure
on how it would be received by fellow human travelers. At least I
contend it is so.&lt;/p&gt;
&lt;p&gt;Additionally I can “carve out”, with pretty good precision, the
specific target group I want to reach with my article, picture, video,
email, or whatnot.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/to-chatgpt-a-picture-says-more-than-a-thousand-words/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>ImageMagick with Pango on MacOS Ventura</title>
          
          <link>https://blog.agical.se/en/posts/imagemagick-with-pango-on-macos-ventura/</link>
          <pubDate>Tue, 10 Oct 2023 22:13:00 +0200</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/imagemagick-with-pango-on-macos-ventura/</guid>
          <description>&lt;p&gt;In &lt;a
href=&#34;https://blog.agical.se/en/posts/imagemagick--x--pango--x--babashka--x---x--x-/&#34;&gt;&lt;u&gt;ImageMagick
+ Pango + Babashka = ❤️&lt;/u&gt;&lt;/a&gt; I told you about the Docker image &lt;a
href=&#34;https://hub.docker.com/r/cospaia/magick-pango-babashka&#34;&gt;&lt;u&gt;cospaia/magick+pango+babashka&lt;/u&gt;&lt;/a&gt;,
and that it allows for using &lt;a
href=&#34;https://docs.gtk.org/Pango/pango_markup.html&#34;&gt;&lt;u&gt;Pango
markup&lt;/u&gt;&lt;/a&gt; with &lt;a
href=&#34;https://imagemagick.org/&#34;&gt;&lt;u&gt;ImageMagick&lt;/u&gt;&lt;/a&gt; locally as well
as in CI. I also told you that I haven’t succeeded to install ImageMagic
with Pango support on my Mac.&lt;/p&gt;
&lt;p&gt;Since I wrote that I have tried to figure it out, and when compiling
ImageMagick from source failed in some opaque way, all too early in the
&lt;code&gt;make&lt;/code&gt;, I almost threw in the towel. But then I got an idea.
What if…&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/imagemagick-with-pango-on-macos-ventura/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>ImageMagick &#43; Pango &#43; Babashka = ♥️</title>
          
          <link>https://blog.agical.se/en/posts/imagemagick--x--pango--x--babashka--x---x--x-/</link>
          <pubDate>Tue, 10 Oct 2023 17:01:00 +0200</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/imagemagick--x--pango--x--babashka--x---x--x-/</guid>
          <description>&lt;p&gt;If you want to conveniently compose pictures and text
programmatically you may want to have a look at &lt;a
href=&#34;https://imagemagick.org/&#34;&gt;&lt;u&gt;ImageMagick&lt;/u&gt;&lt;/a&gt;. Especially when
powered by &lt;a
href=&#34;https://docs.gtk.org/Pango/pango_markup.html&#34;&gt;&lt;u&gt;Pango&lt;/u&gt;&lt;/a&gt;
markup. The markup is SGML and the resulting text line breaks and flows
automatically. It gets quite a lot easier to lay your text out this way,
than to use ImageMagic’s built in text facilities. And some things do
not only get easier, they become &lt;em&gt;possible&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;However, first you need to get the ImageMagick + Pango pair
installed. Depending on your machine this can get complicated. I still
haven’t figured out how to do it on my Mac. (&lt;a
href=&#34;https://blog.agical.se/en/posts/imagemagick-with-pango-on-macos-ventura/&#34;&gt;&lt;u&gt;See
here for how I worked around it.&lt;/u&gt;&lt;/a&gt;) As my real use case was to get
it to happen in a CI build step, I searched for ImageMagic + Pango
Docker images and couldn’t find one that actually worked.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/imagemagick--x--pango--x--babashka--x---x--x-/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Full source code: Newsletter automation using Buttondown &#43; Google Sheets</title>
          
          <link>https://blog.agical.se/en/posts/full-source-code--newsletter-automation-using-buttondown--x--google-sheets/</link>
          <pubDate>Mon, 02 Oct 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/full-source-code--newsletter-automation-using-buttondown--x--google-sheets/</guid>
          <description>&lt;p&gt;Here’s how I created a fully automated, weekly newsletter using only
RSS, &lt;a href=&#34;https://buttondown.email&#34;&gt;&lt;u&gt;Buttondown&lt;/u&gt;&lt;/a&gt;, and &lt;a
href=&#34;https://sheets.google.com&#34;&gt;&lt;u&gt;Google Sheets&lt;/u&gt;&lt;/a&gt;. Full source
code included!&lt;/p&gt;
&lt;p&gt;I run a hobby project (&lt;a
href=&#34;https://cospaia.se&#34;&gt;&lt;u&gt;Cospaia&lt;/u&gt;&lt;/a&gt;, mostly in Swedish, but
it’s not important for this article) together with some friends. We
wanted a weekly automated newsletter. When figuring out how to do this,
I compared it to a commercial project I’m involved with, where we use &lt;a
href=&#34;https://www.netlify.com/products/forms/&#34;&gt;&lt;u&gt;Netlify Forms&lt;/u&gt;&lt;/a&gt;
and &lt;a href=&#34;https://mailchimp.com/&#34;&gt;&lt;u&gt;Mailchimp&lt;/u&gt;&lt;/a&gt;, with &lt;a
href=&#34;https://zapier.com/apps/netlify/integrations/mailchimp&#34;&gt;&lt;u&gt;Zapier
as glue&lt;/u&gt;&lt;/a&gt;. As Mailchimp is pretty crappy, and has a history of
biting me really hard (deleting my subscriber database), and we are not
hosting the Cospaia site using Netlify, I looked around for other ways
to do this one. In the Cospaia project, instead of Netlify we are using
&lt;a href=&#34;https://vercel.com/&#34;&gt;&lt;u&gt;Vercel&lt;/u&gt;&lt;/a&gt;, so Vercel Functions
came to mind. I didn’t immediately find something however, like I did
with Netlify Forms. This doesn’t mean there isn’t an easy path here,
just that Brave Search found &lt;a
href=&#34;https://css-tricks.com/using-netlify-forms-and-netlify-functions-to-build-an-email-sign-up-widget/&#34;&gt;&lt;u&gt;something
else&lt;/u&gt;&lt;/a&gt; for me first. It was actually also involving Netlify Forms,
but instead of Mailchimp there was something else. It looked super
interesting and relevant to what I needed: &lt;strong&gt;Buttondown&lt;/strong&gt;!
But before digging into the solution, let’s have a look at my
requirements.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/full-source-code--newsletter-automation-using-buttondown--x--google-sheets/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>The Stone Soup is a Lie</title>
          
          <link>https://blog.agical.se/en/posts/the-stone-soup-is-a-lie/</link>
          <pubDate>Tue, 26 Sep 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/the-stone-soup-is-a-lie/</guid>
          <description>&lt;p&gt;Some 20 years ago I worked at a startup with a CEO who liked to cook
up various tricks to make potential customers think we were further
ahead than we were. I complained that he was setting us and the
customers up for failure. I suggested that at the next meeting we should
be completely open and honest about what they would buy into. We could
leverage it, even. We could tell the customers about the big opportunity
to be part of, and shape, our journey. Somewhat to my surprise, he
agreed. And to his big surprise, the next meeting landed us our first
contract. I was a bit disappointed that he then coined it “the trick of
honesty”. I suspect he might still be regarding it as just one of his
many tricks. ¯\&lt;em&gt;(ツ)&lt;/em&gt;/¯&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/the-stone-soup-is-a-lie/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Calva Maintenance is Exciting!</title>
          
          <link>https://blog.agical.se/en/posts/my-open-source-work-may-june-2023/</link>
          <pubDate>Thu, 29 Jun 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/my-open-source-work-may-june-2023/</guid>
          <description>&lt;p&gt;&lt;em&gt;The following is my report for the May - June, 2023 period of &lt;a
href=&#34;https://www.clojuriststogether.org/&#34;&gt;Clojurists Together&lt;/a&gt; long
term sponsoring.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As usual, the bulk of my open source energy is poured into &lt;a
href=&#34;https://calva.io/&#34;&gt;Calva&lt;/a&gt;, a &lt;a
href=&#34;https://clojure.org/&#34;&gt;Clojure&lt;/a&gt;/&lt;a
href=&#34;https://clojurescript.org/&#34;&gt;ClojureScript&lt;/a&gt;/&lt;a
href=&#34;https://github.com/clojure/clojure-clr&#34;&gt;ClojureCLR&lt;/a&gt;/&lt;a
href=&#34;https://github.com/Tensegritics/ClojureDart&#34;&gt;ClojureDart&lt;/a&gt;/&lt;a
href=&#34;https://babashka.org/&#34;&gt;Babashka&lt;/a&gt;/&lt;a
href=&#34;https://github.com/babashka/nbb&#34;&gt;nbb&lt;/a&gt;/&lt;a
href=&#34;https://marketplace.visualstudio.com/items?itemName%253Dbetterthantomorrow.joyride&#34;&gt;Joyride&lt;/a&gt;/etcetera
development environment that &lt;a
href=&#34;https://www.youtube.com/watch?v%253DL0-yDtVUWMQ&#34;&gt;takes Interactive
Programming seriously&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also got to contribute to Clojure related starter projects + was
interviewed for &lt;a href=&#34;https://flexiana.com/&#34;&gt;Flexiana&lt;/a&gt;’s new
&lt;strong&gt;Clojure Corner&lt;/strong&gt; series: &lt;a
href=&#34;https://flexiana.com/2023/06/clojure-corner-with-pez&#34;&gt;Clojure
Corner with Peter Strömberg&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;calva&#34;&gt;Calva&lt;/h2&gt;
&lt;p&gt;Over at Twitter someone asked me if I was up to something exciting.
Implicitly wondering if Calva was about to get some cool new big thing
(I think). My answer was that it is mostly about maintenance currently.
However,&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/my-open-source-work-may-june-2023/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Changing my mind: Converting a script from bash to Babashka</title>
          
          <link>https://blog.agical.se/en/posts/changing-my-mind--converting-a-script-from-bash-to-babashka/</link>
          <pubDate>Tue, 16 May 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/changing-my-mind--converting-a-script-from-bash-to-babashka/</guid>
          <description>&lt;p&gt;Here, a description of one of my many rewrites of shell scripts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;From&lt;/strong&gt;: bash-plus-a-lot-of-Unix-tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To&lt;/strong&gt;: &lt;a
href=&#34;https://babashka.org/&#34;&gt;&lt;u&gt;Babashka&lt;/u&gt;&lt;/a&gt;-plus-fewer-Unix-tools
(zero Unix tools in this case).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://clojure.org/&#34;&gt;&lt;u&gt;Clojure&lt;/u&gt;&lt;/a&gt; reaches wherever I
want to code something. For shell scripting it is a great choice because
Babashka. By old habit I still often start out with bash. I paste a
piece of my command line history in a file and go from there. Then when
my script stops behaving like I intend it to, and resists my attempts to
make it: I regret not doing it with Babashka.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/changing-my-mind--converting-a-script-from-bash-to-babashka/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>How to create a really simple ClojureCLR dependency tool</title>
          
          <link>https://blog.agical.se/en/posts/how-to-create-a-really-simple-clojureclr-dependency-tool/</link>
          <pubDate>Sun, 14 May 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/how-to-create-a-really-simple-clojureclr-dependency-tool/</guid>
          <description>&lt;p&gt;I just published &lt;a
href=&#34;https://github.com/PEZ/clojure-clr-starter&#34;&gt;clojure-clr-starter&lt;/a&gt;
– &lt;em&gt;A Dockerized CLojureCLR Starter Project&lt;/em&gt;, that makes it easy
to create a &lt;a
href=&#34;https://github.com/clojure/clojure-clr&#34;&gt;ClojureCLR&lt;/a&gt; project,
start it and connect a &lt;a href=&#34;https://clojure.org/&#34;&gt;Clojure&lt;/a&gt;
editor. This article describes how the project is set up. Surprisingly
little glue was needed once &lt;a href=&#34;https://github.com/dmiller&#34;&gt;David
Miller&lt;/a&gt; had created &lt;a
href=&#34;https://github.com/clojure/clr.tools.nrepl&#34;&gt;clr.tools.nrepl&lt;/a&gt; (a
few weeks ago).&lt;/p&gt;
&lt;p&gt;&lt;img
src=&#34;https://blog.agical.se/images/how-to-create-a-really-simple-clojureclr-dependency-tool/ClojureCLR.jpg&#34; /&gt;&lt;/p&gt;
&lt;p&gt;There is no dependency tooling for ClojureCLR yet (it’s &lt;a
href=&#34;https://github.com/dmiller/clr.tools.deps&#34;&gt;being worked on&lt;/a&gt;) so
we have to solve a few things ourselves. We need to get ClojureCLR
to:&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/how-to-create-a-really-simple-clojureclr-dependency-tool/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Extend VS Code in user space, without invented restrictions</title>
          
          <link>https://blog.agical.se/en/posts/extend-vs-code-in-user-space--without-invented-restrictions/</link>
          <pubDate>Sun, 02 Apr 2023 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/extend-vs-code-in-user-space--without-invented-restrictions/</guid>
          <description>&lt;p&gt;Let’s break out of an imaginary jail. Let’s hack &lt;a
href=&#34;https://code.visualstudio.com/&#34;&gt;&lt;u&gt;Visual Studio Code&lt;/u&gt;&lt;/a&gt; in
all ways it allows for being modified by extensions, but without leaving
user space. User space as in “a user of VS Code”, to contrast with “a
developer of VS Code extensions”. The imaginary jail being that I
thought some extensibility cases are closed to &lt;a
href=&#34;https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.joyride&#34;&gt;&lt;u&gt;Joyride&lt;/u&gt;&lt;/a&gt;
and need &lt;a
href=&#34;https://marketplace.visualstudio.com/search?target=VSCode&amp;amp;category=Programming%20Languages&amp;amp;sortBy=Rating&#34;&gt;&lt;u&gt;an
extension&lt;/u&gt;&lt;/a&gt; to be implemented. It is not so!&lt;/p&gt;
&lt;p&gt;&lt;img
src=&#34;https://blog.agical.se/images/extend-vs-code-in-user-space--without-invented-restrictions/image1.jpg&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;bliss-in-a-universe-of-vast-possibilities&#34;&gt;Bliss in a universe
of vast possibilities&lt;/h1&gt;
&lt;p&gt;With &lt;a
href=&#34;https://github.com/BetterThanTomorrow/joyride&#34;&gt;&lt;u&gt;Joyride&lt;/u&gt;&lt;/a&gt;
a whole world of possibilities opens for programmers who want to
customize their development environment of choice from user space, as
long as that choice is VS Code. Joyride scripts allow us to add those
tiny features we miss, or large features, or fully automate our specific
workflows, or script our use of ChatGPT, or just about anything. If we
can imagine it, Joyride makes it so that we can make it happen.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/extend-vs-code-in-user-space--without-invented-restrictions/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>ChatGPT: Are you holding it wrong?</title>
          
          <link>https://blog.agical.se/en/posts/chatgpt--are-you-holding-it-wrong-x-/</link>
          <pubDate>Sat, 10 Dec 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/chatgpt--are-you-holding-it-wrong-x-/</guid>
          <description>&lt;p&gt;As far as productivity boosts go, ChatGPT (which calls itself
Assistant), represents the biggest leap in a long time. Especially if
our work involves writing. Correctly used, that is. Incorrectly used,
ChatGPT can produce pure garbage, although it might look very similar to
the valuable help we could have gotten if we had wielded this new tool
rightly.&lt;/p&gt;
&lt;p&gt;Whether it boosts our productivity, by quickly helping us fill in the
blanks, or wastes our time with garbage we need to identify and clean
up, it will do so using the same engine. ChatGPT is the latest famous
and infamous installation of OpenAI’s aligned large language models. At
its core the model uses its training data to predict the next word. Much
like the help phone keyboards offer us when we are typing.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/chatgpt--are-you-holding-it-wrong-x-/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>A conversation with ChatGPT about ChatGPT</title>
          
          <link>https://blog.agical.se/en/posts/a-conversation-with-chatgpt-about-chatgpt/</link>
          <pubDate>Wed, 07 Dec 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/a-conversation-with-chatgpt-about-chatgpt/</guid>
          <description>&lt;p&gt;I blurted out ”How are you?” at the start of a session with &lt;a
href=&#34;https://chat.openai.com/&#34;&gt;ChatGPT&lt;/a&gt; and it turned into a
conversation where I really tried to get the AI to answer this question.
It gets appearant that ChatGPT is a good writer, even if it can get
stuck and repeat things a bit too often. That the chatbot ”remembers”
the conversation and can use it for its answers is very powerful and
reveals to me some about how useful this technology is and can
become.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/a-conversation-with-chatgpt-about-chatgpt/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Why I Shrugged the Agile Yoke</title>
          
          <link>https://blog.agical.se/en/posts/why-i-shrugged-the-agile-yoke/</link>
          <pubDate>Wed, 28 Sep 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/why-i-shrugged-the-agile-yoke/</guid>
          <description>&lt;p&gt;“Agile workplace” is a red flag to me. I immediately start to worry
if it implies that I am expected to participate in a lot of meetings and
rituals, even though I might be on pins and needles to get some bug
fixed, or to tweak this or that feature.&lt;/p&gt;
&lt;p&gt;Is it just me?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.agical.se/images/why-i-shrugged-the-agile-yoke/image1.jpg&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Actually, I like the idea of making it easy and cheap to adjust and
to correct directions. I’ve been working with software development in
one form or the other for 35 years. I know full well that it is possible
to do it in a rigid, heavy, and awful way, ensuring that as many people
as possible suffer from anxiety. When I have been given enough
influence, I have even nimbly arranged for things to be that way.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/why-i-shrugged-the-agile-yoke/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>shadow-cljs &#43; Clojure with Calva: The basics</title>
          
          <link>https://blog.agical.se/en/posts/shadow-cljs-clojure-cljurescript-calva-nrepl-basics/</link>
          <pubDate>Tue, 13 Sep 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/shadow-cljs-clojure-cljurescript-calva-nrepl-basics/</guid>
          <description>&lt;p&gt;This &lt;strong&gt;How to use &lt;a
href=&#34;https://github.com/thheller/shadow-cljs&#34;&gt;shadow-cljs&lt;/a&gt; with
Calva in a fullstack project&lt;/strong&gt; guide will not take the short path
of presenting some steps and then ”BOOM there it is!” Instead we are
going to look at the pieces involved and how they are composed to create
Calva’s connection with the ClojureScript app being developed. The point
with this is to give you the knowledge to get yourself past obstacles
that a short 1-2-3 step guide might land you in.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/shadow-cljs-clojure-cljurescript-calva-nrepl-basics/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Be aware of NUMA when your application needs to run very fast</title>
          
          <link>https://blog.agical.se/en/posts/be-numa-aware-for-the-sake-of-performance/</link>
          <pubDate>Wed, 09 Feb 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/be-numa-aware-for-the-sake-of-performance/</guid>
          <description>&lt;p&gt;With &lt;a href=&#34;../java-bitset-performance-mystery/&#34;&gt;the article about
a performance mystery involving Java and BitSets&lt;/a&gt;, I got &lt;a
href=&#34;https://news.ycombinator.com/item?id=30226083&#34;&gt;help from Hacker
News&lt;/a&gt; (and a lot of other sources as well) to investigate and also
solve the mystery.&lt;/p&gt;
&lt;p&gt;However, I haven’t managed to solve the problem that this &lt;a
href=&#34;https://en.wikipedia.org/wiki/Non-uniform_memory_access&#34;&gt;NUMA&lt;/a&gt;
(+ Docker, in my case) issue is causing me.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;I&amp;#39;m very happy I could find the solution to this mystery. But the solution is quite unsatisfactory for my particular problem, since I can&amp;#39;t use `numctl --membind=0` in the drag-racing environment. Have a look at my bitset solution&amp;#39;s results here: &lt;a href=&#34;https://t.co/qPakybLMAw&#34;&gt;https://t.co/qPakybLMAw&lt;/a&gt; 😭&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/be-numa-aware-for-the-sake-of-performance/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>Help solve this Java BitSet performance-flicker mystery</title>
          
          <link>https://blog.agical.se/en/posts/java-bitset-performance-mystery/</link>
          <pubDate>Sat, 05 Feb 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/java-bitset-performance-mystery/</guid>
          <description>&lt;p&gt;&lt;strong&gt;UPDATE February 6, 2022&lt;/strong&gt;: The behaviour seems to be
triggered by that the JVM process sometimes gets scheduled on a
different NUMA node from where the heap is allocated. I tested this by
using this command to run the sieve:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode sh&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;numactl&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--cpunodebind&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;0 &lt;span class=&#34;at&#34;&gt;--membind&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;0 java PrimeSieve&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On my first try this gave me the error message
&lt;code&gt;setting membind: Operation not permitted&lt;/code&gt;. The workaround I
used was to run the docker container in privileged mode:&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/java-bitset-performance-mystery/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>A Calva workflow for quil drawing</title>
          
          <link>https://blog.agical.se/en/posts/calva-quil-workflow/</link>
          <pubDate>Wed, 05 Jan 2022 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/calva-quil-workflow/</guid>
          <description>&lt;p&gt;&lt;a href=&#34;https://github.com/quil/quil&#34;&gt;Quil&lt;/a&gt; is a &lt;a
href=&#34;https://clojure.org&#34;&gt;Clojure&lt;/a&gt; and &lt;a
href=&#34;https://clojurescript.org&#34;&gt;ClojureScript&lt;/a&gt; wrapper around &lt;a
href=&#34;https://processing.org&#34;&gt;Processing&lt;/a&gt;. Quil takes &lt;em&gt;learning
how to code within the context of the visual arts&lt;/em&gt; and applies 10X
to it. (I say being a passionate Clojurian.)&lt;/p&gt;
&lt;p&gt;With Clojure and its REPL comes the promise that you dynamically can
tweak and form your sketches, as they are running. That’s what this is
article is about. There is a Calva context, but things generally apply
accross all Clojure editors/IDEs. I will assume you know some Clojure,
but you should be able to follow pretty well regardless, because I also
will try to keep this at a beginner’s level. My aim is to leverage Quil
to try to explain things in a way that could help you ”see” how the
Clojure editor relates to the Clojure REPL. (In case you haven’t yet
”seen” this.)&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/calva-quil-workflow/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
        
        
        <item>
          <title>How to mix Clojure and Java code in the same tools-deps project</title>
          
          <link>https://blog.agical.se/en/posts/mixed-clojure-and-java/</link>
          <pubDate>Thu, 30 Dec 2021 00:00:00 +0000</pubDate>
          <author> </author>
          <guid>https://blog.agical.se/en/posts/mixed-clojure-and-java/</guid>
          <description>&lt;p&gt;For whatever reasons, you might sometimes want to develop your
program in a mix of &lt;a href=&#34;https://clojure.org&#34;&gt;Clojure&lt;/a&gt; and &lt;a
href=&#34;https://www.java.com/&#34;&gt;Java&lt;/a&gt;. (Or some other language that
compiles to &lt;code&gt;.class&lt;/code&gt; files.)&lt;/p&gt;
&lt;p&gt;This is actually so easy that nobody has bothered with writing up an
article on how to do it. At least not for non-Leiningen projects. Until
now, because in processing a pull request on &lt;a
href=&#34;https://calva.io&#34;&gt;Calva&lt;/a&gt;, I had reasons to try create a project
like this, and I’d like to help you walk a bit straighter of a path than
I did.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;a href=&#39;https://blog.agical.se/en/posts/mixed-clojure-and-java/&#39;&gt;Read this ↗️&lt;/a&gt;</description>
        </item>
        
        
    
  </channel>
</rss>
