<?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://clojure-diary.gitlab.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://clojure-diary.gitlab.io/" rel="alternate" type="text/html" /><updated>2026-07-10T14:39:03+05:30</updated><id>https://clojure-diary.gitlab.io/feed.xml</id><title type="html">Clojure Diary</title><subtitle>Hello, I am Karthikeyan A K, a software architect, for some reason I am getting hooked up with Clojure, and these writings are my experience with this language. One may contact me @ +91 8428050777 for Clojure consolation in weekends.</subtitle><entry><title type="html">Finding The Next Working Day, With Clojure</title><link href="https://clojure-diary.gitlab.io/2026/07/10/finding-the-next-working-day-with-clojure.html" rel="alternate" type="text/html" title="Finding The Next Working Day, With Clojure" /><published>2026-07-10T14:23:00+05:30</published><updated>2026-07-10T14:23:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/07/10/finding-the-next-working-day-with-clojure</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/07/10/finding-the-next-working-day-with-clojure.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/5sa-OhOzkuw" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<p><strong>Code:</strong></p>

<ul>
  <li><a href="https://gitlab.com/clojure-diary/code/miscellaneous/-/raw/master/next_working_day.clj">next_working_day.clj</a></li>
  <li><a href="https://gitlab.com/clojure-diary/code/miscellaneous/-/raw/master/next_working_day_2.clj">next_working_day_2.clj</a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">libl.in, &amp;amp; Injee, Thanks To Clojure Community. Updates in Clojure Book.</title><link href="https://clojure-diary.gitlab.io/2026/07/07/libl-in-injee-thanks-to-clojure-community-updates-in-clojure-book.html" rel="alternate" type="text/html" title="libl.in, &amp;amp; Injee, Thanks To Clojure Community. Updates in Clojure Book." /><published>2026-07-07T20:29:00+05:30</published><updated>2026-07-07T20:29:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/07/07/libl-in-injee-thanks-to-clojure-community-updates-in-clojure-book</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/07/07/libl-in-injee-thanks-to-clojure-community-updates-in-clojure-book.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/uGu7vNhQCDE" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<p><strong>Notes</strong></p>

<ul>
  <li>Injee
    <ul>
      <li><a href="https://tossconf26.kaniyam.com/">https://tossconf26.kaniyam.com/</a></li>
      <li>Tamil Linux
        <ul>
          <li>Telegram
            <ul>
              <li><a href="https://t.me/tamillinux">https://t.me/tamillinux</a></li>
            </ul>
          </li>
          <li>ilugc
            <ul>
              <li><a href="https://ilugc.in/">https://ilugc.in/</a></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>https://libl.in
    <ul>
      <li><a href="https://clojure-book.gitlab.io/book.html#_installing_stuff">https://clojure-book.gitlab.io/book.html#_installing_stuff</a>
        <ul>
          <li><a href="https://yu7.in/clj-installing-stuff">https://yu7.in/clj-installing-stuff</a>
            <ul>
              <li>Now it’s fixed :D</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Clojure Book
    <ul>
      <li>Proof read with A.I
        <ul>
          <li><a href="https://gitlab.com/clojure-book/clojure-book.gitlab.io/-/tree/proof_read">https://gitlab.com/clojure-book/clojure-book.gitlab.io/-/tree/proof_read</a></li>
        </ul>
      </li>
      <li>Release in all human languages</li>
    </ul>
  </li>
  <li>-ve’s
    <ul>
      <li>Video series about ring is stalled</li>
      <li>Stats with Clojure book is stalled
        <ul>
          <li><a href="https://scicloj.github.io/stats_with_clojure/">https://scicloj.github.io/stats_with_clojure/</a></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Deploying Ring App on Ubuntu 26.04</title><link href="https://clojure-diary.gitlab.io/2026/06/15/deploying-ring-app-on-ubuntu-26-04.html" rel="alternate" type="text/html" title="Deploying Ring App on Ubuntu 26.04" /><published>2026-06-15T13:42:00+05:30</published><updated>2026-06-15T13:42:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/06/15/deploying-ring-app-on-ubuntu-26-04</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/06/15/deploying-ring-app-on-ubuntu-26-04.html"><![CDATA[<p>Once you have coded a Ring app,</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>lein ring uberjar
</code></pre></div></div>

<p>This will create a standalone JAR file in the <code class="language-plaintext highlighter-rouge">target</code> directory. Let’s renameit to <code class="language-plaintext highlighter-rouge">my-app.jar</code> for convenience.</p>

<p>Here’s how to host your Clojure Ring app on an Ubuntu VPS:</p>

<h2 id="1-install-java">1. Install Java</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update
<span class="nb">sudo </span>apt <span class="nb">install </span>openjdk-25-jre-headless
java <span class="nt">-version</span>  <span class="c"># verify</span>
</code></pre></div></div>

<h2 id="2-upload-the-jar">2. Upload the JAR</h2>

<p>From your local machine:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp my-app.jar user@your-vps-ip:/home/user/
</code></pre></div></div>

<h2 id="3-run-it-manually-first-sanity-check">3. Run it manually first (sanity check)</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java <span class="nt">-jar</span> my-app.jar
</code></pre></div></div>

<p>Your app likely starts on port 3000 by default. You can override it:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">PORT</span><span class="o">=</span>8080 java <span class="nt">-jar</span> my-app.jar
</code></pre></div></div>

<p>You can use browser to test your app at <code class="language-plaintext highlighter-rouge">http://your-vps-ip:3000</code>, or <code class="language-plaintext highlighter-rouge">http://your-vps-ip:8080</code> if you set a custom port.</p>

<h2 id="4-set-up-a-systemd-service-so-it-runs-forever">4. Set up a systemd service (so it runs forever)</h2>

<p>Create a service file:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>nano /etc/systemd/system/my-app.service
</code></pre></div></div>

<p>Paste this:</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
<span class="py">Description</span><span class="p">=</span><span class="s">My Clojure Ring App</span>
<span class="py">After</span><span class="p">=</span><span class="s">network.target</span>

<span class="nn">[Service]</span>
<span class="py">User</span><span class="p">=</span><span class="s">user</span>
<span class="py">WorkingDirectory</span><span class="p">=</span><span class="s">/home/user</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/java -jar /home/user/my-app.jar</span>
<span class="py">Restart</span><span class="p">=</span><span class="s">always</span>
<span class="py">RestartSec</span><span class="p">=</span><span class="s">5</span>
<span class="py">Environment</span><span class="p">=</span><span class="s">PORT=3000</span>

<span class="nn">[Install]</span>
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
</code></pre></div></div>

<p>Enable and start it:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl daemon-reload
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>my-app
<span class="nb">sudo </span>systemctl start my-app
<span class="nb">sudo </span>systemctl status my-app
</code></pre></div></div>

<h2 id="5-set-up-nginx-as-a-reverse-proxy">5. Set up Nginx as a reverse proxy</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install</span> <span class="nt">-y</span> nginx
</code></pre></div></div>

<p>Create a config:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>nano /etc/nginx/sites-available/my-app
</code></pre></div></div>

<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
    <span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
    <span class="kn">server_name</span> <span class="s">your-domain.com</span><span class="p">;</span>  <span class="c1"># or your VPS IP</span>

    <span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
        <span class="kn">proxy_pass</span> <span class="s">http://localhost:3000</span><span class="p">;</span>
        <span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
        <span class="kn">proxy_set_header</span> <span class="s">X-Real-IP</span> <span class="nv">$remote_addr</span><span class="p">;</span>
        <span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
        <span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-Proto</span> <span class="nv">$scheme</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Enable it:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo ln</span> <span class="nt">-s</span> /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
<span class="nb">sudo </span>nginx <span class="nt">-t</span>
<span class="nb">sudo </span>systemctl reload nginx
</code></pre></div></div>

<h2 id="6-open-the-firewall">6. Open the firewall</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>ufw allow <span class="s1">'Nginx Full'</span>
<span class="nb">sudo </span>ufw allow OpenSSH
<span class="nb">sudo </span>ufw <span class="nb">enable</span>
</code></pre></div></div>

<h2 id="7-add-https-with-lets-encrypt-optional-but-recommended">7. Add HTTPS with Let’s Encrypt (optional but recommended)</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>snap <span class="nb">install</span> <span class="nt">--classic</span> certbot <span class="c"># install certbot</span>
<span class="nb">sudo ln</span> <span class="nt">-s</span> /snap/bin/certbot /usr/local/bin/certbot <span class="c"># Prepare the Certbot command </span>
<span class="nb">sudo </span>certbot <span class="nt">--nginx</span> <span class="c"># follow the prompts to set up HTTPS</span>
</code></pre></div></div>

<p>Certbot will auto-edit your Nginx config and set up auto-renewal.</p>

<hr />

<p><strong>Useful commands after deployment:</strong></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl restart my-app       <span class="c"># restart after uploading new jar</span>
<span class="nb">sudo </span>journalctl <span class="nt">-u</span> my-app <span class="nt">-f</span>        <span class="c"># tail logs</span>
<span class="nb">sudo </span>systemctl status my-app        <span class="c"># check status</span>
</code></pre></div></div>

<p>When you deploy a new version, just <code class="language-plaintext highlighter-rouge">scp</code> the new jar over and <code class="language-plaintext highlighter-rouge">sudo systemctl restart my-app</code>.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Once you have coded a Ring app,]]></summary></entry><entry><title type="html">clj.rs Clojure implemented on Rust</title><link href="https://clojure-diary.gitlab.io/2026/06/07/clj-rs-clojure-implemented-on-rust.html" rel="alternate" type="text/html" title="clj.rs Clojure implemented on Rust" /><published>2026-06-07T15:09:00+05:30</published><updated>2026-06-07T15:09:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/06/07/clj-rs-clojure-implemented-on-rust</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/06/07/clj-rs-clojure-implemented-on-rust.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/WXTGL6v23Ew" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<p><strong>Notes</strong></p>

<ul>
  <li><a href="https://clj.rs/">clj.rs</a> could be a big thing
    <ul>
      <li><a href="https://clofer.codeberg.page/">Clofer</a>
collapsed:: true
        <ul>
          <li>Why it started
            <ul>
              <li>file -&gt; jar -&gt; output
                <ul>
                  <li>Lot’s of files
                    <ul>
                      <li><a href="https://www.gnu.org/software/parallel/">GNU Parallel</a></li>
                      <li><a href="https://www.graalvm.org/">GraalVM</a>
                        <ul>
                          <li>NOOOOOOOOO</li>
                          <li>Oracle</li>
                        </ul>
                      </li>
                    </ul>
                  </li>
                </ul>
              </li>
            </ul>
          </li>
          <li><a href="https://github.com/clojure-rs/ClojureRS">clojurers</a></li>
          <li>I don’t know a lot
collapsed:: true
            <ul>
              <li><a href="https://kanipaan.codeberg.page/">Kanipaan</a></li>
            </ul>
          </li>
          <li><a href="https://www.reddit.com/r/Clojure/comments/1txohat/comment/opzal8j/?screen_view_count=2">Reddit comment</a></li>
        </ul>
      </li>
      <li>clj.rs
        <ul>
          <li>Gives me breathing space</li>
          <li>https://clj.rs</li>
          <li><a href="https://mstdn.social/@rsdio@me.dm">Casey Marshall</a>
            <ul>
              <li><img src="https://avatars.githubusercontent.com/u/39441?v=4" alt="" /></li>
              <li><img src="https://media.mstdn.social/cache/accounts/headers/110/040/885/465/558/228/original/7a6c6ed3545c61dc.jpeg" alt="" /></li>
            </ul>
          </li>
          <li>Freedom from Java / Oracle</li>
          <li>Actively Maintained!!
            <ul>
              <li>Will Clojure community will ensure active maintenance?</li>
            </ul>
          </li>
          <li><a href="https://jank-lang.org/">Jank</a>
            <ul>
              <li>Clojure on C++</li>
              <li>LLVM</li>
              <li>Pointers</li>
            </ul>
          </li>
          <li>The Garbage collection
            <ul>
              <li>In Ruby it was a big topic</li>
            </ul>
          </li>
          <li>Fast</li>
          <li>Huge set of libraries</li>
          <li>GPU!
            <ul>
              <li><a href="https://rust-gpu.github.io/">Rust GPU</a></li>
            </ul>
          </li>
          <li>No more JavaScript?
            <ul>
              <li>I hate JavaScript</li>
            </ul>
          </li>
          <li>Embedded Systems</li>
          <li>OS programming</li>
          <li>Data Science</li>
          <li>Clojure on <a href="https://zed.dev/">Zed</a> editor?
            <ul>
              <li><a href="https://jupyter.org/">Jpyter Lab</a></li>
              <li>VSCode is slow
                <ul>
                  <li>Take up resources</li>
                </ul>
              </li>
              <li>M$ - common who really trusts them?</li>
            </ul>
          </li>
          <li>Less nightmare for Rust dev’s
            <ul>
              <li>Imagine the productivity gain!!!!</li>
            </ul>
          </li>
          <li>Please rally behind this project</li>
          <li>No more Clofer, grow, and long live https://clj.rs/</li>
          <li>-ve’s
            <ul>
              <li>Claude is used
                <ul>
                  <li>A closed model</li>
                </ul>
              </li>
              <li>Only 1 person project</li>
              <li>Maybe the world does not know</li>
              <li>Underwhelming reaction</li>
            </ul>
          </li>
          <li>What I will do
            <ul>
              <li>Try to write some Clojure programs with clojurust</li>
              <li><img src="https://codeberg.org/rustforbeginners/design/raw/branch/main/Rust%20for%20beginners.png" alt="" />
                <ul>
                  <li>Learn Rust, make it learnable.</li>
                </ul>
              </li>
              <li>Watch https://clj.rs , report about it
                <ul>
                  <li>Contribute to it if I can (it’s a big if)</li>
                </ul>
              </li>
              <li>Update my <a href="https://clojure-book.gitlab.io/">Clojure Book</a>
                <ul>
                  <li><img src="https://clojure-book.gitlab.io/images/clojure-book-cover-2001-space-odyssey-10_small.png" alt="" /></li>
                </ul>
              </li>
              <li>Write a Lisp compiler in Rust, just for Hobby</li>
              <li>Contribute to <a href="https://scicloj.github.io/stats_with_clojure/">Stats With Clojure</a>
                <ul>
                  <li><img src="https://scicloj.github.io/stats_with_clojure/notebooks/images/stats_with_clojure.png" alt="" /></li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li>Clojure should keep moving
collapsed:: true
        <ul>
          <li>Rust is a great idea now</li>
          <li>Who knows what next?</li>
          <li>Clojure foundation
            <ul>
              <li>Official Clojure implementation on various runtimes</li>
              <li>Standard Clojure API</li>
              <li>Target many platforms
                <ul>
                  <li>Migrate / compile to many platforms</li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Configure Calva Result Display</title><link href="https://clojure-diary.gitlab.io/2026/06/06/configure-calva-result-display.html" rel="alternate" type="text/html" title="Configure Calva Result Display" /><published>2026-06-06T11:43:00+05:30</published><updated>2026-06-06T11:43:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/06/06/configure-calva-result-display</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/06/06/configure-calva-result-display.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/l3jA0BZM_zk" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<p><strong>Notes</strong></p>

<p>VSCode <code class="language-plaintext highlighter-rouge">settings.json</code></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"calva.outputDestinations"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"evalResults"</span><span class="p">:</span><span class="w"> </span><span class="s2">"repl-window"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"evalOutput"</span><span class="p">:</span><span class="w"> </span><span class="s2">"repl-window"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li><a href="https://gitlab.com/clojure-diary/code/configure_calva_result_display">Code</a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Finding File’s MIME Type, Using Apache Tika, in Clojure</title><link href="https://clojure-diary.gitlab.io/2026/05/22/finding-file-s-mime-type-using-apache-tika-in-clojure.html" rel="alternate" type="text/html" title="Finding File’s MIME Type, Using Apache Tika, in Clojure" /><published>2026-05-22T09:08:00+05:30</published><updated>2026-05-22T09:08:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/05/22/finding-file-s-mime-type-using-apache-tika-in-clojure</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/05/22/finding-file-s-mime-type-using-apache-tika-in-clojure.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/l69Mz06u0S4" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<p><strong>Notes</strong></p>

<ul>
  <li><a href="https://codeberg.org/injee/injee/src/commit/e4a937f8d43f5bcc6478af3823caee0db24a7cd6">Code</a></li>
  <li><a href="https://injee.codeberg.page">https://injee.codeberg.page</a></li>
  <li><code class="language-plaintext highlighter-rouge">curl -I http://localhost:4125/files/something</code></li>
  <li><code class="language-plaintext highlighter-rouge">curl -X GET http://localhost:4125/ops/files | jq</code>
    <ul>
      <li><a href="https://jqlang.org/">https://jqlang.org/</a></li>
    </ul>
  </li>
  <li>h&lt;ttps://tika.apache.org/&gt;</li>
  <li><a href="https://mvnrepository.com/artifact/org.apache.tika/tika-core/3.3.0">https://mvnrepository.com/artifact/org.apache.tika/tika-core/3.3.0</a></li>
  <li>Tika in Action
    <ul>
      <li><img src="https://m.media-amazon.com/images/I/71DEwVYkqBL._SL1500_.jpg" alt="" /></li>
      <li><a href="https://www.amazon.com/dp/1935182854">https://www.amazon.com/dp/1935182854</a></li>
    </ul>
  </li>
  <li>Chicken Tika
    <ul>
      <li><img src="https://upload.wikimedia.org/wikipedia/commons/b/bd/Tandoorimumbai.jpg" alt="" /></li>
      <li>Chicken Tiken Masala
        <ul>
          <li><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Chicken_tikka_masala_%28cropped%29.jpg/1920px-Chicken_tikka_masala_%28cropped%29.jpg" alt="" /></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Alex Bedner proof read my Clojure Book</title><link href="https://clojure-diary.gitlab.io/2026/05/19/alex-bedner-proof-read-my-clojure-book.html" rel="alternate" type="text/html" title="Alex Bedner proof read my Clojure Book" /><published>2026-05-19T09:46:00+05:30</published><updated>2026-05-19T09:46:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/05/19/alex-bedner-proof-read-my-clojure-book</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/05/19/alex-bedner-proof-read-my-clojure-book.html"><![CDATA[<p><img src="https://clojure-book.gitlab.io/images/clojure-book-cover-2001-space-odyssey-10_small.png" alt="" /></p>

<p>Hello Clojurians,</p>

<p>I’m happy to announce that the Clojure book has gotten a bit better! A few days ago, I received an email from someone named Alex Bedner. He read my Clojure book from start to finish and was kind enough to share some corrections. I’ve implemented them, and you can find the updated book here: <a href="https://clojure-book.gitlab.io/">https://clojure-book.gitlab.io/</a></p>

<p>I did try to upload the print copy to Amazon, but for some reason they require additional verification from my side — and I’m not entirely sure what that entails. I’m not great with bureaucracy, so getting the Amazon listing sorted will take some time. In the meantime, Alex Bedner’s proofread version of the Clojure book is available at the link above. I’m deeply grateful to him.</p>

<p>There’s still a lot to do, and I remain committed to Clojure. Here are the things I’d like to finish in the book:</p>

<p><strong>Creating Your Own Libraries</strong> (<a href="https://clojure-book.gitlab.io/book.html#_creating_your_own_libraries">https://clojure-book.gitlab.io/book.html#_creating_your_own_libraries</a>) — this section currently has no accompanying video. I’ve been meaning to make one, but haven’t gotten around to it yet — I can’t quite explain why.</p>

<p><strong>Debugging with Calva</strong> (<a href="https://clojure-book.gitlab.io/book.html#_debugging_with_calva">https://clojure-book.gitlab.io/book.html#_debugging_with_calva</a>) — I need to write this section, with plenty of screenshots so readers know how to debug with Calva. At the very least, I’d like to link to the Calva website, where the creator has put together some excellent videos.</p>

<p>I’d also like to add a section on Paredit at some point — we’ll see how that goes.</p>

<p>Finally, I’d love to use LLMs to help proofread and polish the book further. English isn’t my first language, and I’ve found that AI tools have been genuinely helpful in improving the quality of my writing lately.</p>

<p>Once again, thank you to everyone who has said kind words about the book, pointed out corrections, offered criticism, or praised it. All of it is valuable input, and I’ll make the most of every bit of it.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Learn Ring - 13. CSS</title><link href="https://clojure-diary.gitlab.io/2026/05/07/learn-ring-13-css.html" rel="alternate" type="text/html" title="Learn Ring - 13. CSS" /><published>2026-05-07T14:32:00+05:30</published><updated>2026-05-07T14:32:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/05/07/learn-ring-13-css</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/05/07/learn-ring-13-css.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/eHI2V0S0E4A" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<h2 id="notes">Notes</h2>

<ul>
  <li><a href="https://codeberg.org/learnring/little_ring_things/src/branch/009_css">CSS</a></li>
  <li><a href="https://codeberg.org/learnring/little_ring_things/src/branch/010_css_in_hiccup">CSS in Hiccup</a></li>
  <li><a href="https://codeberg.org/learnring/little_ring_things/src/branch/011_css_with_garden">CSS with garden</a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Learn Ring - Session Vs Cookie</title><link href="https://clojure-diary.gitlab.io/2026/05/06/session-vs-cookie.html" rel="alternate" type="text/html" title="Learn Ring - Session Vs Cookie" /><published>2026-05-06T08:59:00+05:30</published><updated>2026-05-06T08:59:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/05/06/session-vs-cookie</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/05/06/session-vs-cookie.html"><![CDATA[<p><strong>Cookies</strong> and <strong>sessions</strong> are both ways to persist data across HTTP requests, but they work differently:</p>

<h3 id="cookie">Cookie</h3>
<ul>
  <li>Stored <strong>on the client</strong> (browser)</li>
  <li>Data is sent with every HTTP request in the request header</li>
  <li>Can persist for a set expiration time (even after the browser closes)</li>
  <li>Limited to about <strong>4KB</strong> of data</li>
  <li>Can be read by JavaScript (unless <code class="language-plaintext highlighter-rouge">HttpOnly</code> flag is set)</li>
  <li>Examples: remembering a user’s theme preference, tracking analytics</li>
</ul>

<h3 id="session">Session</h3>
<ul>
  <li>Stored <strong>on the server</strong></li>
  <li>The browser only holds a small <strong>session ID</strong> (usually in a cookie)</li>
  <li>Typically expires when the browser is closed (or after a server-defined timeout)</li>
  <li>Can hold <strong>much larger</strong> amounts of data</li>
  <li>More secure since the actual data never leaves the server</li>
  <li>Examples: storing login state, shopping cart contents</li>
</ul>

<h3 id="how-they-work-together">How they work together</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Browser                          Server
  |                                |
  |--- Request (with session ID) -&gt;|
  |                                |--- Looks up session ID in store
  |                                |--- Retrieves session data
  |&lt;-- Response -------------------|
</code></pre></div></div>

<p>A common pattern is: the server creates a session, stores the session ID in a cookie, and on each request the browser sends that cookie so the server can find the right session data.</p>

<h3 id="quick-comparison">Quick comparison</h3>

<table>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Cookie</th>
      <th>Session</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Storage location</td>
      <td>Client (browser)</td>
      <td>Server</td>
    </tr>
    <tr>
      <td>Size limit</td>
      <td>~4KB</td>
      <td>No strict limit</td>
    </tr>
    <tr>
      <td>Lifetime</td>
      <td>Configurable</td>
      <td>Usually browser session</td>
    </tr>
    <tr>
      <td>Security</td>
      <td>Less secure</td>
      <td>More secure</td>
    </tr>
    <tr>
      <td>Performance</td>
      <td>Faster (no server lookup)</td>
      <td>Slightly slower</td>
    </tr>
    <tr>
      <td>Use case</td>
      <td>Preferences, tracking</td>
      <td>Auth, sensitive data</td>
    </tr>
  </tbody>
</table>

<p><strong>Rule of thumb:</strong> Use cookies for small, non-sensitive data you’re okay storing client-side. Use sessions for sensitive data or anything that shouldn’t be exposed to the client.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Cookies and sessions are both ways to persist data across HTTP requests, but they work differently:]]></summary></entry><entry><title type="html">Learn Ring - 12. Navbar</title><link href="https://clojure-diary.gitlab.io/2026/05/05/learn-ring-12-navbar.html" rel="alternate" type="text/html" title="Learn Ring - 12. Navbar" /><published>2026-05-05T18:34:00+05:30</published><updated>2026-05-05T18:34:00+05:30</updated><id>https://clojure-diary.gitlab.io/2026/05/05/learn-ring-12-navbar</id><content type="html" xml:base="https://clojure-diary.gitlab.io/2026/05/05/learn-ring-12-navbar.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

<div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/ql7qK5xDgPI" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
  </div>

<p><strong>Notes</strong></p>

<ul>
  <li><a href="https://codeberg.org/learnring/little_ring_things/src/branch/008_common_nav">Code</a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry></feed>