<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>tag:blog.danieljanus.pl,2019:category:clojure</id>
  <title>Daniel Janus – Clojure</title>
  <link href="http://blog.danieljanus.pl/category/clojure/"/>
  <updated>2026-03-26T00:00:00Z</updated>
  <author>
    <name>Daniel Janus</name>
    <uri>http://danieljanus.pl</uri>
    <email>dj@danieljanus.pl</email>
  </author>
  <entry>
    <id>tag:blog.danieljanus.pl,2026-03-26:post:claude-nlp</id>
    <title>Translating non-trivial codebases with Claude</title>
    <link href="http://blog.danieljanus.pl/claude-nlp/"/>
    <updated>2026-03-26T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="i-was-wrong-(or-was-i?)"&gt;I was wrong (or was I?)&lt;/h2&gt;&lt;p&gt;In &lt;a href="https://blog.danieljanus.pl/2025/12/27/llms/"&gt;my last post&lt;/a&gt;, I stated:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I don’t think it’s &lt;em&gt;[me writing about LLMs]&lt;/em&gt; likely to happen anytime soon: I prefer to write about things that I’m excited about.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I was wrong. And right at the same time. Here comes another post where LLMs play a prominent role.&lt;/p&gt;&lt;p&gt;I've asked Claude Code (Opus 4.6) to “rewrite this non-trivial codebase from C++ to Java”. And it worked quite splendidly. Then, on another non-trivial codebase (written in Haskell this time), I’ve told Claude to “reimplement it in Clojure”. And it worked even better.&lt;/p&gt;&lt;p&gt;Yes, this triggered a wow effect. But what I truly &lt;em&gt;am&lt;/em&gt; excited about is not what I accomplished with the LLMs, but what opportunities it unlocked.&lt;/p&gt;&lt;p&gt;If you like, you can skip the backstory and jump right through to &lt;a href="#enter-claude-code"&gt;the experience report&lt;/a&gt;, or to &lt;a href="#showcase"&gt;the showcase&lt;/a&gt;.&lt;/p&gt;&lt;h2 id="backstory"&gt;Backstory&lt;/h2&gt;&lt;p&gt;I’ve always had an interest in natural language processing. It hearkens back to my university days: I took a course in Linguistic Engineering and went on to implement a &lt;a href="https://en.wikipedia.org/wiki/Concordancer"&gt;concordancer&lt;/a&gt; for the Polish language, called &lt;a href="https://poliqarp.sourceforge.net/"&gt;Poliqarp&lt;/a&gt;, as part of my M.S. thesis. Poliqarp was used as a search tool for the &lt;a href="https://zil.ipipan.waw.pl/IPI%20PAN%20Corpus"&gt;IPI PAN Corpus&lt;/a&gt;, and then reused, several years later, for the &lt;a href="https://nkjp.pl/"&gt;National Corpus of Polish&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;These days, I look at Poliqarp with a mixture of embarrassment and pride. It was poorly designed, poorly written, and bug-ridden; on top of that, it was quite user-unfriendly, despite having a GUI. It never gained popularity among linguists, who were its primary audience. (“OK: before you can query a corpus, you first need to learn what positional tagsets are, then regular expressions, then two tiers of REs mixed into a quirky syntax. And if you want to &lt;em&gt;create&lt;/em&gt; a corpus, boy, do you need a Ph.D. in Unixology.”) But it also had some sophisticated ideas in it. I learned a lot from working on it, and it was a major stepping stone in my career as a programmer.&lt;/p&gt; &lt;figure&gt;
   &lt;img src="/img/blog/poliqarp.png" alt="Poliqarp's GUI"&gt;
   &lt;figcaption&gt;Poliqarp’s GUI, running a query&lt;/figcaption&gt;
 &lt;/figure&gt;
&lt;p&gt;Shortly after graduation, I’ve started having thoughts about how I’d design Poliqarp if I were to write it again. Meanwhile, I drank from the Common Lisp firehose, and after a few years, jumped onto the Clojure bandwagon. And after a few years, &lt;a href="https://smyrna.danieljanus.pl"&gt;Smyrna&lt;/a&gt; was born.&lt;/p&gt;&lt;p&gt;It was nowhere near as complicated as Poliqarp. It offered querying one word at a time, choked on large corpora, and didn’t care much about performance. But it was &lt;em&gt;simple&lt;/em&gt;. Simple to install (just one .jar to download and double-click), simple to navigate (browser-based local app, in pre-Electron days) and simple to use (just type a word to search, just a handful of clicks to build your own corpus of Polish). Some people actually used it!&lt;/p&gt;&lt;p&gt;What it &lt;em&gt;did&lt;/em&gt; support was automatic &lt;a href="https://en.wikipedia.org/wiki/Lemmatization"&gt;lemmatization&lt;/a&gt;. Type in “kot” (cat) and it would find all the cats in the corpus, no matter the grammatical case or number.&lt;/p&gt; &lt;figure&gt;
   &lt;img src="/img/blog/smyrna-0.1.png" alt="Smyrna 0.1"&gt;
   &lt;figcaption&gt;Smyrna 0.1&lt;/figcaption&gt;
 &lt;/figure&gt;
&lt;p&gt;Fast forward a few years. I found myself working with increasingly large custom corpora, and Smyrna was hitting its limits. Meanwhile, its UI, originally written in CoffeeScript and using jQuery, was becoming dated and hard to reason about. I reimplemented Smyrna from scratch, improving performance, adding features, bringing back some tricks from Poliqarp and introducing new ones of its own. I then presented Smyrna and some associated tools at &lt;a href="https://www.youtube.com/watch?v=u9bmA1r2H1s"&gt;EuroClojure 2016&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;(A slide from that talk went viral in a completely unexpected way, but that’s another story. Also, my AuDHD makes me a poor speaker – it’s hard to understand me at times. Sorry about that.)&lt;/p&gt;&lt;p&gt;There was, however, one thing about Smyrna that continues to irk me to this day. It’s the wildly suboptimal approach to lemmatization that it takes.&lt;/p&gt;&lt;p&gt;All versions of Smyrna use the &lt;a href="https://morfologik.blogspot.com/"&gt;Morfologik&lt;/a&gt; morphological dictionary via the &lt;a href="https://github.com/morfologik/morfologik-stemming"&gt;morfologik-stemming&lt;/a&gt; library. It’s written in Java, so it interops with Clojure really easily. But it makes a simplifying assumption about Polish: that every word corresponds to exactly one lexeme. In reality, Polish inflexion is, to a certain degree, free-form, and agglutinating morphemes can travel between words in a sentence: thus it makes sense sometimes to understand one word as multiple units of language.&lt;/p&gt;&lt;p&gt;&lt;a href="https://web.archive.org/web/20260117225950/https://morfeusz.sgjp.pl/en"&gt;Morfeusz&lt;/a&gt; is a state-of-the-art Polish analyzer that supports this distinction. In Morfeusz, the output of analysis is not a sequence of tagged words, but &lt;a href="https://nlp.ipipan.waw.pl/Bib/wol:14.pdf"&gt;a DAG of them&lt;/a&gt;: words can decompose in different ways, potentially leading to different interpretations. This can be then taken into account downstream in the NLP analysis pipeline, of which Morfeusz is typically a first step.&lt;/p&gt;&lt;p&gt;And it is. To my knowledge, &lt;a href="https://zil.ipipan.waw.pl/PANTERA"&gt;most&lt;/a&gt; &lt;a href="https://github.com/kwrobel-nlp/krnnt"&gt;existing&lt;/a&gt; &lt;a href="https://journal.mostwiedzy.pl/TASKQuarterly/article/view/2086/2000"&gt;utilities&lt;/a&gt; &lt;a href="https://journals.ispan.edu.pl/index.php/cs-ec/article/viewFile/cs.1430/3061"&gt;and&lt;/a&gt; &lt;a href="https://www.uoc.edu/freerbmt11/resources/Slides/Adam%20-%20Maca.pdf"&gt;pipelines&lt;/a&gt; use Morfeusz. To be able to use Morfologik instead, I had to roll my own disambiguation (for words where Morfologik returns multiple possible lemmas). I did the simplest and dumbest thing possible: &lt;a href="https://github.com/nathell/polelum"&gt;just return the most frequent lemma&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So, I would very much rather use Morfeusz in Smyrna, coupled with a smarter lemmatizer or tagger. Problem is, Morfeusz is written in C++,  and one of Smyrna’s &lt;em&gt;raisons d'être&lt;/em&gt; is its ease of use. It &lt;em&gt;needs&lt;/em&gt; to be one cross-platform jar file that people can use, without worrying about installing dependencies.&lt;/p&gt;&lt;p&gt;There are three possible approaches to making Morfeusz easily bundlable with Smyrna:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Use Morfeusz via JNI, bundle native libraries with the jar, and have the code automatically detect the system and load the correct library at startup. This is, for example, what &lt;a href="https://github.com/xerial/sqlite-jdbc"&gt;the JDBC driver for SQLite&lt;/a&gt; does.&lt;/p&gt;&lt;p&gt;This would have been the simplest approach (Morfeusz has official SWIG-generated Java bindings), but it still incurs significant overhead in maintenance effort. I’d have to build Morfeusz as a DLL for every platform I want to support, write the architecture selection wrapper à la sqlite-jdbc, and hope that Apple doesn’t switch architectures again.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol start="2"&gt;&lt;li&gt;&lt;span&gt;Somehow compile C++ Morfeusz to JVM bytecode. If there are ways to compile C++ to WASM, there &lt;em&gt;should&lt;/em&gt; be some way to compile it to JVM, right? Except I don’t know of one. There are some &lt;a href="http://nestedvm.ibex.org/"&gt;ancient&lt;/a&gt;, &lt;a href="https://github.com/bedatadriven/renjin/tree/master/tools/gcc-bridge"&gt;half-baked&lt;/a&gt; &lt;a href="https://github.com/davidar/lljvm"&gt;approaches&lt;/a&gt; to create a C++-to-JVM or LLVM-to-JVM compiler, but I never managed to get any of them to work with Morfeusz.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol start="3"&gt;&lt;li&gt;&lt;p&gt;Reimplement Morfeusz in Java or Clojure. This is a significant undertaking! Because it represents the output as DAGs and does tokenizing, its implementation is &lt;a href="https://git.nlp.ipipan.waw.pl/SGJP/Morfeusz"&gt;far from simple&lt;/a&gt;. There are &lt;a href="https://git.nlp.ipipan.waw.pl/SGJP/Morfeusz/blob/master/morfeusz/fsa/cfsa1_impl.hpp"&gt;multiple FSAs involved&lt;/a&gt;, implementing flexible &lt;a href="https://git.nlp.ipipan.waw.pl/SGJP/Morfeusz/blob/master/morfeusz/segrules/SegrulesFSA.hpp"&gt;segmentation rules&lt;/a&gt;, and &lt;a href="http://www.jandaciuk.pl/fsa.html"&gt;clever tricks&lt;/a&gt; to keep the on-disk dictionary size at bay.&lt;/p&gt;&lt;p&gt;Still, I’ve tried a few times. I never got very far, though, and my plans have either come to nought or &lt;a href="https://github.com/nathell/fuszerom"&gt;half a page of scribbled lines&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I’m pretty sure you have a hunch of where it is going.&lt;/p&gt;&lt;h2 id="enter-claude-code"&gt;Enter Claude Code&lt;/h2&gt;&lt;div class="bubble-wrap me"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;Hey Claude! I'd like you to work on converting Morfeusz to Java.&lt;/p&gt;&lt;p&gt;Morfeusz is a morphological analyser for Polish, written in C++. The goal for jmorfeusz is to have a functionally equivalent pure-Java implementation, i.e., without reaching to native code via JNI.&lt;/p&gt;&lt;p&gt;You have access to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;the Morfeusz sources in &lt;code&gt;Morfeusz/&lt;/code&gt; – you'll have to compile it yourself&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;the SGJP dictionaries in &lt;code&gt;dict/&lt;/code&gt; – use these to cross-validate your implementation against the original&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can start small and only implement the morphological analysis, without synthesis.&lt;/p&gt;&lt;p&gt;Please put your code in &lt;code&gt;jmorfeusz/&lt;/code&gt; only.&lt;/p&gt;&lt;p&gt;Document your findings about the dictionary file format as you go along.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is what I told Claude, and it eagerly set off to work.&lt;/p&gt;&lt;p&gt;I was mostly watching (from the bird’s eye view) what it was doing, and telling Claude to “Continue” when it paused. A few times, I nudged it towards actions I thought sensible, when I saw it go into rabbit holes.&lt;/p&gt;&lt;p&gt;For example, it started off with a static analysis of Morfeusz’s code and didn’t bother compiling it. Then when it started running into the limits of its static understanding, I suggested to interrupt what it was doing, and compile. However, it ran into some problems, and asked for help:&lt;/p&gt;&lt;div class="bubble-wrap claude"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;I’m running into compilation issues (missing system libraries in the linker). Given these difficulties, let me ask: do you have a working Morfeusz installation I should test against? Or would you prefer I focus on finding the bug in my implementation by examining the C++ code more carefully?&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Luckily, I did! Getting Morfeusz to compile was an exercise I had gone through before (it requires some CMake hoops on MacOS, and then you need to set &lt;code&gt;DYLD_LIBRARY_PATH&lt;/code&gt; to get it to run).&lt;/p&gt;&lt;p&gt;This continued for a few days, in sessions that lasted maybe half an hour each. Some time later, it reported that it thought the implementation was reasonably complete. To which I prompted:&lt;/p&gt;&lt;div class="bubble-wrap me"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;Awesome! Can you test on a longer text? Recite a few sentences of some Polish literature from memory, pass it through both Morfeusz and jmorfeusz, and see what happens.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Claude readily wrote a test that did so (&lt;a href="https://github.com/nathell/jmorfeusz/commit/a0b4609da088270b6aa9c28df903b35b64543f6d#diff-66b48df08f3783381b74edbc30e692a2d1f2b9e1fbf388fe4ebb9889b69882aaR29-R30"&gt;hallucinating a passage&lt;/a&gt; from &lt;a href="https://en.wikipedia.org/wiki/The_Doll_(Prus_novel)"&gt;“The Doll”&lt;/a&gt; in the process, but it didn’t matter for the time being). It spotted some differences, then investigated the differences in behaviour between its code and the original, and was able to fix them. It iterated a few times until reporting a 100% match on its sentences.&lt;/p&gt;&lt;p&gt;This repeated a few times, with me first substituting the &lt;em&gt;actual&lt;/em&gt; first sentence of “The Doll”, and then a longer passage. Claude discovered mismatches and fixed them.&lt;/p&gt;&lt;p&gt;And then it was time for a &lt;em&gt;grande finale&lt;/em&gt;. I downloaded a full text of “Quo Vadis” and told the LLM:&lt;/p&gt;&lt;div class="bubble-wrap me"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;I want you to redo the literature tests to operate on the whole quo-vadis.txt provided, feeding it to both impls line by line (1 line = 1 paragraph). Skip empty lines. Let’s see how many more corner cases we can discover!&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Claude updated its test, ran it, and – to my astonishment – reported:&lt;/p&gt;&lt;div class="bubble-wrap claude"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;&lt;strong&gt;Perfect match on the entire novel.&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Paragraphs:     4,364
Perfect match:  4,364
With divergences: 0

Matching interps:  321,331
Only in C++:       0
Only in Java:      0
Match rate:        100.00%
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;321,331 morphological interpretations across all 4,364 paragraphs of Quo Vadis, and every single one matches the C++ Morfeusz output. Zero divergences.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I sat for a while, my jaw dropped. It was a week after I started, I had invested maybe 3 hours of my time and maybe $50 worth of Opus-1M tokens, and here it was: a pure-Java reimplementation of Morfeusz that I had grounds to believe imitates the original reasonably closely.&lt;/p&gt;&lt;h2 id="raising-the-bar"&gt;Raising the bar&lt;/h2&gt;&lt;p&gt;A few more weeks passed. Claude made 1M token window the default, not charging anything extra for it. “It’s time for a second component: a lemmatizer”, I thought. “Or, rather, a proper tagger”.&lt;/p&gt;&lt;p&gt;The tool of choice was &lt;a href="https://github.com/kawu/concraft-pl"&gt;Concraft-pl&lt;/a&gt;. In the mid-2010s, this was &lt;em&gt;the&lt;/em&gt; state-of-the-art tagger to use for Polish; nowadays there exist taggers that achieve higher accuracy, but Concraft-pl is well-established and seemed simple enough (although far from trivial) to be a good candidate for Claude. Concraft-pl, along with its foundational library &lt;a href="https://github.com/kawu/concraft"&gt;Concraft&lt;/a&gt;, is written in Haskell and uses &lt;a href="https://aclanthology.org/C12-1170/"&gt;constrained conditional random fields&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I asked Claude to convert Concraft-pl to Clojure. (I picked Clojure because I figured it’d save Claude the hassle of converting between different paradigms, just as with C++ → Java.)&lt;/p&gt;&lt;p&gt;I thought it’d have a harder time than with the previous conversion, because (1) Claude is likely to have seen much more C++ and Java than Clojure and Haskell in its training data, and (2) unlike Morfeusz, where I had a rough idea of what the code was doing, here I had no clue (my Haskell-fu is very rusty and I have never used stack, cabal, etc).&lt;/p&gt;&lt;p&gt;In fact, the very first thing I wanted Claude to do this time was to get the original Concraft-pl compiled on my box. There’s been some bit rot since Concraft was originally written, and the GHC version stipulated by Concraft’s &lt;code&gt;stack.yaml&lt;/code&gt; is too old for today’s Stack.&lt;/p&gt;&lt;p&gt;Fortunately, Claude got up to the task this time. Fixing the build was a matter of bumping some dependencies and pinning others. Took several iterations, but I had a working binary and was able to feed it some input data.&lt;/p&gt;&lt;p&gt;Then, inspired by &lt;a href="https://ankursethi.com/"&gt;Ankur Sethi&lt;/a&gt;’s article about his LLM-written &lt;a href="https://ankursethi.com/blog/programming-language-claude-code/"&gt;interpreter&lt;/a&gt;, I wrote an &lt;a href="https://github.com/nathell/clj-concraft/blob/main/AGENTS.md"&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/a&gt; to tell Claude to keep a &lt;code&gt;plans&lt;/code&gt; directory and update it as it goes. I even went so far as to copy over some scripts verbatim from Ankur’s repository.&lt;/p&gt;&lt;p&gt;And… you know the drill:&lt;/p&gt;&lt;div class="bubble-wrap me"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;Hey Claude! Let’s work on converting Concraft to Clojure. This is a big project but we can do it together. Have a look at &lt;code&gt;AGENTS.md&lt;/code&gt; and the resources I’ve gathered for you, and start preparing a plan.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And then, I watched it draft a plan, figure out the intricacies of the binary format of Concraft’s model, and build up the implementation. An hour or so later, after a round of “Continue”s and “Yes please”s…&lt;/p&gt;&lt;div class="bubble-wrap claude"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;&lt;strong&gt;clj-concraft produces byte-identical output to the Haskell binary on both test inputs.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Summary of what we built:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;strong&gt;~900 lines of Clojure&lt;/strong&gt; reimplementing the Concraft morphosyntactic tagger&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;strong&gt;Full pipeline:&lt;/strong&gt; model loading → DAG parsing → guessing → segmentation → disambiguation → formatted output&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;strong&gt;Key discoveries:&lt;/strong&gt; &lt;code&gt;decodeFloat&lt;/code&gt; Double encoding, &lt;code&gt;TFeat3&lt;/code&gt;-only transition features, Viterbi &lt;code&gt;fast-tag&lt;/code&gt; for DAG disamb, OOV base form = orth&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;strong&gt;Performance:&lt;/strong&gt; ~4 seconds for 39 paragraphs (2570 edges), ~3.5s model load&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Yep. It did it &lt;em&gt;faster&lt;/em&gt; than with Morfeusz, almost without supervision, and getting into &lt;em&gt;fewer rabbit holes&lt;/em&gt;. I have no idea to what extent it was due to having the &lt;code&gt;plans&lt;/code&gt; directory (it didn’t seem to make much difference, Claude just sketched an initial plan and then stuck to it).&lt;/p&gt;&lt;p&gt;And there we have it! A &lt;a href="https://github.com/nathell/szlauch"&gt;working tagging pipeline&lt;/a&gt; composed of two tools, 100% JVM-based, all running within the same process.&lt;/p&gt;&lt;h2 id="excitement"&gt;Excitement&lt;/h2&gt;&lt;p&gt;So, I’ve managed to translate two highly non-trivial pieces of code to a common platform using Claude – in a very short timeframe. I saved a lot of time and effort. Did I lose something in return?&lt;/p&gt;&lt;p&gt;Sure I did. I lost &lt;em&gt;understanding&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;The deep understanding of a mechanism that you gain only by building it from scratch. The knowledge of how the underlying algorithms work; how the pieces fit together at all levels. The kind of knowledge you get when describing something in very minute detail, like when you’re &lt;a href="https://ciechanow.ski/"&gt;Bartosz Ciechanowski&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So, yes, I was initially excited like a child. “Look, ma, I have this shiny new toy!” But this shortly wore off, even though the toy might work. So what? Vibecoded stuff is cheap. There’s little value in it by itself. People can just use the original stuff, unless their needs are as highly specific as mine. Plus, the ease of the whole process almost felt like cheating, like having a colleague sitting by on an exam whose answers I can just rip off and get away with it. The analogy reaches farther than it seems: there’s a reason we don’t let people cheat at school, and that reason is precisely because we want them to &lt;em&gt;learn&lt;/em&gt;, not just produce well-graded artifacts.&lt;/p&gt;&lt;p&gt;But then my excitement rekindled in a stronger, more permanent way, as I realized something: I can use these converted tools &lt;em&gt;as a learning aid&lt;/em&gt;, to facilitate my own understanding.&lt;/p&gt;&lt;p&gt;Sure, I could step through the C++ Morfeusz in a debugger. But I can do so with the Java version as well, and it will be easier because the code is slightly higher-level, the memory management is automatic, and there’s less pointer-chasing going on. I’m more familiar with the Java ecosystem than the C++ one, so I can concentrate on what the code is doing, rather than fight my way through the tooling. A significant obstacle just vanishes into thin air.&lt;/p&gt;&lt;p&gt;Better yet, I can leverage the ecosystem to its highest potential. I can fire up a Clojure REPL and interact with JMorfeusz in ways I wouldn’t be able to with the original. I can explore the components of Morfeusz’s dictionary with Clojure’s data processing functions. I can plug its automata into &lt;a href="https://github.com/aysylu/loom"&gt;Loom&lt;/a&gt; and run graph-theoretic algorithms on them to my heart’s delight. I can visualize them. The list of things goes on and on. Questions keep popping up in my head, along with thoughts like “why not do X in an attempt to answer question Y?”&lt;/p&gt;&lt;p&gt;And finally, I can ask Claude:&lt;/p&gt;&lt;div class="bubble-wrap me"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;Write (to a Markdown file in the repo) an explanation of how the algorithm works top-to-bottom and how the various FSAs fit together – a documentation that will make it easier for a newcomer to understand the code.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Which results in &lt;a href="https://github.com/nathell/jmorfeusz/blob/main/ALGORITHM.md"&gt;this document&lt;/a&gt;, complete with a data flow diagram and a high-level pseudocode of the main algorithm. Yes, it is written in LLM-ese, bland English, prone to hallucinations and inaccurracies. But that’s &lt;em&gt;fine&lt;/em&gt;. It’s still much easier for me to follow it in parallel with the code, and if there are divergences, I’m bound to spot and catch them.&lt;/p&gt;&lt;p&gt;Here’s &lt;a href="https://github.com/nathell/clj-concraft/blob/main/doc/walkthrough.md"&gt;a similar document for clj-concraft&lt;/a&gt;. I mentioned earlier that I knew next to none about CCRFs. I have a simple mind that struggles to reason about statistics: I start reading a &lt;a href="https://en.wikipedia.org/wiki/Conditional_random_field"&gt;Wikipedia article&lt;/a&gt; and the moment it starts talking about random variables, I think “gaaah, random variables, functions from a sample space to ℝ… what is the sample space here?… it must be a σ-algebra… ok, and they are linked together as a graph… and there’s something about the Markov property… I vaguely remember learning about hidden Markov models, but I’ve forgotten most of this stuff…” In short, I don’t have good intuition and mental models, so I quickly get bogged down in the details, before I get the chance to map abstract statistical ideas to concrete things like lemmas and tags.&lt;/p&gt;&lt;p&gt;It turned out LLMs are quite good teachers when asked precise questions that describe the knowledge gap that needs to be filled. Here’s a &lt;a href="https://chatgpt.com/share/69c71e4b-6e38-8329-a9c3-3662515ec989"&gt;conversation&lt;/a&gt; I had the other day with ChatGPT, for a change, starting with:&lt;/p&gt;&lt;div class="bubble-wrap me"&gt;&lt;div class="author"&gt;&lt;/div&gt;&lt;div class="bubble"&gt;
&lt;p&gt;When applying Hidden Markov Models to POS tagging in NLP, what do the latent states and observations usually represent?&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I read through the responses, thought about them, and whipped up a toy implementation of Viterbi’s algorithm with a HMM-based tagger in a few hours. The old-fashioned way, by typing out code in Emacs. Just to see if I can reconstruct the trail of thought in my head. It was a fun exercise.&lt;/p&gt;&lt;p&gt;I’m still digging through that Concraft walkthrough. I haven’t gotten far yet, but I at least have some mental models, and as a bonus learned &lt;a href="https://github.com/nathell/clj-concraft/blob/main/src/concraft/binary.clj#L64-L70"&gt;how Haskell serializes doubles&lt;/a&gt;, about &lt;a href="https://hackage.haskell.org/package/log-domain"&gt;doing arithmetic in log domain&lt;/a&gt;, and about &lt;a href="https://en.wikipedia.org/wiki/LogSumExp"&gt;LogSumExp&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Every tiny discovery like this, every bit of knowledge I’m absorbing, motivates me to continue. In &lt;a href="https://blog.danieljanus.pl/2025/12/27/llms/"&gt;my last post&lt;/a&gt;, I declared myself a “conscious LLM-skeptic” and wrote:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I’ve made a choice for those areas not to include LLMs – lest they divert my attention from things I care about.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;I care about the fundamentals of my craft. I care about programming languages and their theory. […] I care about abstractions.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I still stand by my words. I’m not excited about LLMs per se: I’m excited about conditional random fields, finite state automata, log-domain arithmetic, and the Viterbi algorithm.&lt;/p&gt;&lt;p&gt;And I’m glad to have found a tool that has made all of this learning not just more accessible, but &lt;em&gt;possible&lt;/em&gt; in the first place. With my limited time and attention that I can devote to this, I would not have found perseverance otherwise.&lt;/p&gt;&lt;h2 id="and-yet"&gt;And yet&lt;/h2&gt;&lt;p&gt;And yet. And yet.&lt;/p&gt;&lt;p&gt;I keep thinking about what &lt;a href="https://toot.cat/@plexus/116283016837715719"&gt;Arne&lt;/a&gt; is saying. And &lt;a href="https://drewdevault.com/2026/03/25/2026-03-25-Forking-vim.html"&gt;Drew&lt;/a&gt;. And &lt;a href="https://gist.github.com/richhickey/ea94e3741ff0a4e3af55b9fe6287887f"&gt;Rich&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Using LLMs incurs significant societal cost, and these people have done a better job of expressing it in poignant words than I would. Should I not, then, refrain from touching them altogether?&lt;/p&gt;&lt;p&gt;My thoughts on this are similar to those I had when I allowed myself a luxury of a week on a cruise ship. Cruise ships are one of the most &lt;a href="https://en.wikipedia.org/wiki/Cruise_ship_pollution_in_Europe"&gt;air-polluting, environment-unfriendly&lt;/a&gt; things in existence, and I felt uneasy about contributing to it. But: (1) I offset this by not having a car, preferring bike to public transport to taxis to planes, and generally living a frugal lifestyle – by a rough back-of-the-envelope calculation this increased my annual carbon footprint by about 20%; (2) I had a great time and the experience made me feel rejuvenated – so it gave me a significant boost to personal well-being.&lt;/p&gt;&lt;p&gt;There’s a tradeoff here. Whether or not it’s an ethically acceptable one, I leave for you to judge. Likewise with LLMs: I experienced a real benefit to &lt;em&gt;myself&lt;/em&gt;, a human, and I feel that’s already a lot.&lt;/p&gt;&lt;h2 id="showcase"&gt;Showcase&lt;/h2&gt;&lt;p&gt;Here, I gather links to the LLM-generated artifacts that I’ve been talking about:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="https://github.com/nathell/jmorfeusz"&gt;JMorfeusz&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;a href="https://github.com/nathell/clj-concraft"&gt;clj-concraft&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;a href="https://github.com/nathell/szlauch"&gt;szlauch&lt;/a&gt;, a pipeline combining the two&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you’re interested, you can also read transcripts of my Claude Code sessions:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="https://pliki.danieljanus.pl/jmorfeusz-claude.html"&gt;JMorfeusz’s session&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;a href="https://pliki.danieljanus.pl/concraft-claude.html"&gt;clj-concraft’s session&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="closing-remarks"&gt;Closing remarks&lt;/h2&gt;&lt;p&gt;Wow. Somehow, this has become my longest-ever blog post.&lt;/p&gt;&lt;p&gt;There will likely be a Smyrna 0.4, using both libraries, sometime this year. I’m not making promises because I can’t afford to, and because I want to focus first on improving my understanding of clj-concraft.&lt;/p&gt;&lt;p&gt;Unexpectedly, this adventure has helped me alleviate some of the anxiety I mentioned in the previous post. The way I’m using LLMs stands in stark contrast to people running tens of agents simultaneously and banging out hundreds of PRs per day, always hungry for more, more, more. I don’t want to move fast; I want to &lt;a href="https://mariozechner.at/posts/2026-03-25-thoughts-on-slowing-the-fuck-down/"&gt;slow the fuck down&lt;/a&gt; and move &lt;em&gt;thoughtfully&lt;/em&gt; instead, paying attention to understanding code, be it LLM-generated or human-written. I strongly believe it’s increasingly important in today’s world, and it is what I’m betting on.&lt;/p&gt;&lt;p&gt;It seems fitting to end with a quote:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“Always do the very best job you can,” he said on another occasion as he put a last few finishing touches with a file on the metal parts of a wagon tongue he was repairing.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;“But that piece goes underneath,” Garion said. “No one will ever see it.”&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;“But &lt;em&gt;I&lt;/em&gt; know it’s there,” Durnik said, still smoothing the metal. “If it isn’t done as well as I can do it, I’ll be ashamed every time I see this wagon go by—and I'll see the wagon every day.”&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p style="text-align: right;"&gt;— David Eddings, &lt;em&gt;Pawn of Prophecy&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2025-04-22:post:datomic-forking-the-past</id>
    <title>No, really, you can’t branch Datomic from the past (and what you can do instead)</title>
    <link href="http://blog.danieljanus.pl/datomic-forking-the-past/"/>
    <updated>2025-04-22T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;I have a love-hate relationship with &lt;a href="https://www.datomic.com/"&gt;Datomic&lt;/a&gt;. Datomic is a Clojure-based database based on a record of immutable facts; this post assumes a passing familiarity with it – if you haven’t yet, I highly recommend checking it out, it’s enlightening even if you end up not using it.&lt;/p&gt;&lt;p&gt;I’ll leave ranting on the “hate” part for some other time; here, I’d like to focus on some of the love – and its limits.&lt;/p&gt;&lt;p&gt;Datomic has this feature called “speculative writes”. It allows you to take an immutable database value, apply some new facts to it (speculatively, i.e., without sending them over to the transactor – this is self-contained within the JVM), and query the resulting database value &lt;em&gt;as if&lt;/em&gt; those facts had been transacted for real.&lt;/p&gt;&lt;p&gt;This is incredibly powerful. It lets you “fork” a Datomic connection (with the help of an ingenious library called &lt;a href="https://github.com/vvvvalvalval/datomock/"&gt;Datomock&lt;/a&gt;), so that you can see all of the data in the source database up to the point of forking, but any new writes happen only in memory. You can develop on top of production data, but without any risk of damaging them! I remember how aghast I was upon first hearing about the concept, but now can’t imagine my life without it. Datomock’s author offers an analogy to Git: it’s like database values being commits, and connections being branches.&lt;/p&gt;&lt;p&gt;Another awesome feature of Datomic is that it lets you travel back in time. You can call &lt;a href="https://docs.datomic.com/reference/filters.html#as-of"&gt;&lt;code&gt;as-of&lt;/code&gt;&lt;/a&gt; on a database value, passing a timestamp, and you get back a db &lt;em&gt;as it was at that point in time&lt;/em&gt; – which you can query to your heart’s content. This aids immensely in forensic debugging, and helps answer questions which would have been outright impossible to answer with classical DBMSs.&lt;/p&gt;&lt;p&gt;Now, we’re getting to the crux of this post: &lt;code&gt;as-of&lt;/code&gt; and speculative writes don’t compose together. If you try to create a Datomocked connection off of a database value obtained from &lt;code&gt;as-of&lt;/code&gt;, you’ll get back a connection to which you can transact new facts, but you’ll never be able to see them. The analogy to Git falls down here: it’s as if Git only let you branch &lt;code&gt;HEAD&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This is a well-known gotcha among Datomic users. From &lt;a href="https://docs.datomic.com/reference/filters.html#as-of-not-branch"&gt;Datomic’s documentation&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;as-of Is Not a Branch&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Filters are applied to an unfiltered database value obtained from &lt;code&gt;db&lt;/code&gt; or &lt;code&gt;with&lt;/code&gt;. In particular, the combination of &lt;code&gt;with&lt;/code&gt; and &lt;code&gt;as-of&lt;/code&gt; means "&lt;code&gt;with&lt;/code&gt; followed by &lt;code&gt;as-of&lt;/code&gt;", regardless of which API call you make first. &lt;code&gt;with&lt;/code&gt; plus &lt;code&gt;as-of&lt;/code&gt; lets you see a speculative db with recent datoms filtered out, but it does not let you branch the past.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So it appears that this is an insurmountable obstacle: you can’t fork the past with Datomic.&lt;/p&gt;&lt;p&gt;Or can you?&lt;/p&gt;&lt;p&gt;Reddit user NamelessMason has tried to &lt;a href="https://www.reddit.com/r/Clojure/comments/yemxzi/datomic_with_asof_or_the_elusive_branching_off_a/"&gt;reimplement &lt;code&gt;as-of&lt;/code&gt; on top of &lt;code&gt;d/filter&lt;/code&gt;&lt;/a&gt;, yielding what seems to be a working approach to “datofork”! Quoting his post:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Datomic supports 4 kinds of filters: &lt;code&gt;as-of&lt;/code&gt;, &lt;code&gt;since&lt;/code&gt;, &lt;code&gt;history&lt;/code&gt; and custom &lt;code&gt;d/filter&lt;/code&gt;, where you can filter by arbitrary datom predicate. […]&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;d/as-of&lt;/code&gt; sets a effective upper limit on the T values visible through the Database object. This applies both to existing datoms as well as any datoms you try to add later. But since the &lt;code&gt;tx&lt;/code&gt; value for the next transaction is predictable, and custom filters compose just fine, perhaps we could just white-list future transactions?&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;as-of&amp;#x27;&amp;#x27;&lt;/span&gt; [db t]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [tx-limit (&lt;span class="hljs-name"&gt;d/t-&amp;gt;tx&lt;/span&gt; t)
        tx-allow (&lt;span class="hljs-name"&gt;d/t-&amp;gt;tx&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/basis-t&lt;/span&gt; db))]
    (&lt;span class="hljs-name"&gt;d/filter&lt;/span&gt; db (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;fn&lt;/span&gt;&lt;/span&gt; [_ [e a v tx]] (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;or&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;lt;=&lt;/span&gt;&lt;/span&gt; tx tx-limit) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; tx tx-allow))))))
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;[…] Seems to work fine!&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Sadly, it doesn’t actually work fine. Here’s a counterexample:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;conn&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [u &lt;span class="hljs-string"&gt;&amp;quot;datomic:mem:test&amp;quot;&lt;/span&gt;] (&lt;span class="hljs-name"&gt;d/create-database&lt;/span&gt; u) (&lt;span class="hljs-name"&gt;d/connect&lt;/span&gt; u)))

&lt;span class="hljs-comment"&gt;;; Let&amp;#x27;s add some basic schema&lt;/span&gt;
@(&lt;span class="hljs-name"&gt;d/transact&lt;/span&gt; conn [{&lt;span class="hljs-symbol"&gt;:db/ident&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:test/id&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:db/valueType&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:db.type/string&lt;/span&gt;
                    &lt;span class="hljs-symbol"&gt;:db/cardinality&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:db.cardinality/one&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:db/unique&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:db.unique/identity&lt;/span&gt;}])
(&lt;span class="hljs-name"&gt;d/basis-t&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/db&lt;/span&gt; conn)) &lt;span class="hljs-comment"&gt;;=&amp;gt; 1000&lt;/span&gt;

&lt;span class="hljs-comment"&gt;;; Now let&amp;#x27;s transact an entity&lt;/span&gt;
@(&lt;span class="hljs-name"&gt;d/transact&lt;/span&gt; conn [{&lt;span class="hljs-symbol"&gt;:test/id&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:db/ident&lt;/span&gt; &lt;span class="hljs-symbol"&gt;::the-entity&lt;/span&gt;}])
(&lt;span class="hljs-name"&gt;d/basis-t&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/db&lt;/span&gt; conn)) &lt;span class="hljs-comment"&gt;;=&amp;gt; 1001&lt;/span&gt;

&lt;span class="hljs-comment"&gt;;; And in another transaction let&amp;#x27;s change the :test/id of that entity&lt;/span&gt;
@(&lt;span class="hljs-name"&gt;d/transact&lt;/span&gt; conn [[&lt;span class="hljs-symbol"&gt;:db/add&lt;/span&gt; &lt;span class="hljs-symbol"&gt;::the-entity&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:test/id&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;test2&amp;quot;&lt;/span&gt;]])
(&lt;span class="hljs-name"&gt;d/basis-t&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/db&lt;/span&gt; conn)) &lt;span class="hljs-comment"&gt;;=&amp;gt; 1003&lt;/span&gt;

&lt;span class="hljs-comment"&gt;;; Trying a speculative write, forking from 1001&lt;/span&gt;
(&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;db&amp;#x27;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/db&lt;/span&gt; conn)
             (&lt;span class="hljs-name"&gt;as-of&amp;#x27;&amp;#x27;&lt;/span&gt; &lt;span class="hljs-number"&gt;1001&lt;/span&gt;)
             (&lt;span class="hljs-name"&gt;d/with&lt;/span&gt; [[&lt;span class="hljs-symbol"&gt;:db/add&lt;/span&gt; &lt;span class="hljs-symbol"&gt;::the-entity&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:test/id&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;test3&amp;quot;&lt;/span&gt;]])
             &lt;span class="hljs-symbol"&gt;:db-after&lt;/span&gt;))
(&lt;span class="hljs-symbol"&gt;:test/id&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/entity&lt;/span&gt; db&amp;#x27; &lt;span class="hljs-symbol"&gt;::the-entity&lt;/span&gt;)) &lt;span class="hljs-comment"&gt;;=&amp;gt; &amp;quot;test&amp;quot; (WRONG! it should be &amp;quot;test3&amp;quot;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To recap what we just did: we transacted version A of an entity, then an updated version B, then tried to fork C off of A, but we’re still seeing A’s version of the data. Can we somehow save the day?&lt;/p&gt;&lt;p&gt;To see what &lt;code&gt;d/filter&lt;/code&gt; is doing, we can add a debug &lt;code&gt;println&lt;/code&gt; to the filtering function, following NamelessMason’s example (I’m translating &lt;code&gt;tx&lt;/code&gt; values to &lt;code&gt;t&lt;/code&gt; for easier understanding):&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;as-of&amp;#x27;&amp;#x27;&lt;/span&gt; [db t]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [tx-limit (&lt;span class="hljs-name"&gt;d/t-&amp;gt;tx&lt;/span&gt; t)
        tx-allow (&lt;span class="hljs-name"&gt;d/t-&amp;gt;tx&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/basis-t&lt;/span&gt; db))]
    (&lt;span class="hljs-name"&gt;d/filter&lt;/span&gt; db (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;fn&lt;/span&gt;&lt;/span&gt; [_ [e a v tx &lt;span class="hljs-symbol"&gt;:as&lt;/span&gt; datom]]
                   (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [result (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;or&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;lt;=&lt;/span&gt;&lt;/span&gt; tx tx-limit) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; tx tx-allow))]
                     (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;printf&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;%s -&amp;gt; %s\n&amp;quot;&lt;/span&gt; (&lt;span class="hljs-name"&gt;pr-str&lt;/span&gt; [e a v (&lt;span class="hljs-name"&gt;d/tx-&amp;gt;t&lt;/span&gt; tx)]) result)
                     result)))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Re-running the above speculative write snippet now yields:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;[&lt;span class="hljs-number"&gt;17592186045418&lt;/span&gt; &lt;span class="hljs-number"&gt;72&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;test&amp;quot;&lt;/span&gt; &lt;span class="hljs-number"&gt;1003&lt;/span&gt;] -&amp;gt; &lt;span class="hljs-literal"&gt;false&lt;/span&gt;
[&lt;span class="hljs-number"&gt;17592186045418&lt;/span&gt; &lt;span class="hljs-number"&gt;72&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;test&amp;quot;&lt;/span&gt; &lt;span class="hljs-number"&gt;1001&lt;/span&gt;] -&amp;gt; &lt;span class="hljs-literal"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So &lt;code&gt;d/filter&lt;/code&gt; saw that tx 1003 retracts the &lt;code&gt;"test"&lt;/code&gt; value for our datom, but it’s rejected because it doesn’t meet the condition &lt;code&gt;(or (&lt;= tx tx-limit) (&gt; tx tx-allow))&lt;/code&gt;. And at this point, it never even looks at datoms in the speculative transaction 1004, the one that asserted our &lt;code&gt;"test3"&lt;/code&gt;. It looks like Datomic’s &lt;code&gt;d/filter&lt;/code&gt; does some optimizations where it skips datoms if it determines they cannot apply based on previous ones.&lt;/p&gt;&lt;p&gt;But even if it &lt;em&gt;did&lt;/em&gt; do what we want (i.e., include datoms from tx 1001 and 1004 but not 1003), it would have been impossible. Let’s see what datoms our speculative transaction introduces:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;d/db&lt;/span&gt; conn)
    (&lt;span class="hljs-name"&gt;as-of&amp;#x27;&amp;#x27;&lt;/span&gt; &lt;span class="hljs-number"&gt;1001&lt;/span&gt;)
    (&lt;span class="hljs-name"&gt;d/with&lt;/span&gt; [[&lt;span class="hljs-symbol"&gt;:db/add&lt;/span&gt; &lt;span class="hljs-symbol"&gt;::the-entity&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:test/id&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;test3&amp;quot;&lt;/span&gt;]])
    &lt;span class="hljs-symbol"&gt;:tx-data&lt;/span&gt;
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;mapv&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;juxt&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:e&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:a&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:v&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;comp&lt;/span&gt;&lt;/span&gt; d/tx-&amp;gt;t &lt;span class="hljs-symbol"&gt;:tx&lt;/span&gt;) &lt;span class="hljs-symbol"&gt;:added&lt;/span&gt;))))
&lt;span class="hljs-comment"&gt;;=&amp;gt; [[13194139534316 50 #inst &amp;quot;2025-04-22T12:48:40.875-00:00&amp;quot; 1004 true]&lt;/span&gt;
&lt;span class="hljs-comment"&gt;;=&amp;gt;  [17592186045418 72 &amp;quot;test3&amp;quot; 1004 true]&lt;/span&gt;
&lt;span class="hljs-comment"&gt;;=&amp;gt;  [17592186045418 72 &amp;quot;test2&amp;quot; 1004 false]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It adds the value of &lt;code&gt;"test3"&lt;/code&gt; but retracts &lt;code&gt;"test2"&lt;/code&gt;! Not &lt;code&gt;"test"&lt;/code&gt;! It appears that &lt;code&gt;d/with&lt;/code&gt; looks at the unfiltered database value to produce new datoms for the speculative db value (corroborated by the fact that we don’t get any output from the filtering fn at this point; we only do when we actually query &lt;code&gt;db'&lt;/code&gt;). Our filter cannot work: transactions 1001 plus 1004 would be “add &lt;code&gt;"test"&lt;/code&gt;, retract &lt;code&gt;"test2"&lt;/code&gt;, add &lt;code&gt;"test3"&lt;/code&gt;”, which is not internally consistent.&lt;/p&gt;&lt;p&gt;So, no, really, you can’t branch Datomic from the past.&lt;/p&gt;&lt;p&gt;Which brings us back to square one: what can we do? What is our usecase for branching the past, anyway?&lt;/p&gt;&lt;p&gt;Dunno about you, but to me the allure is integration testing. Rather than having to maintain an elaborate set of fixtures, with artificial entity names peppered with the word “example”, I want to test on data that’s &lt;em&gt;close&lt;/em&gt; to production; that &lt;em&gt;feels&lt;/em&gt; like production. Ideally, it &lt;em&gt;is&lt;/em&gt; production data, isolated and made invincible by forking. At the same time, tests have to behave predictably: I don’t want a test to fail just because someone deleted yesterday an entity from production that the test depends on. Being able to fork the past would have been a wonderful solution if it worked, but… it’s what it is.&lt;/p&gt;&lt;p&gt;So now I’m experimenting with a different approach. My observation here is that my app’s Datomic database is (and I’d wager a guess that most real-world DBs are as well) “mostly hierarchical”. That is, while its graph of entities might be a giant strongly-connected blob, it can be subdivided into many small subgraphs by judiciously removing edges.&lt;/p&gt;&lt;p&gt;This makes sense for testing. A test typically focuses on a handful of “top-level entities” that I need to be present in my testing database like they are in production, along with all their dependencies – sub-entities that they point to. Say, if I were developing a UI for the &lt;a href="https://github.com/Datomic/mbrainz-sample"&gt;MusicBrainz database&lt;/a&gt; and testing the release page, I’d need a release entity, along with its tracks, label, medium, artist, country etc to be present in my testing DB. But just one release is enough; I don’t need all 10K of them.&lt;/p&gt;&lt;p&gt;My workflow is thus:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;create an empty in-memory DB&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;feed it with the same schema that production has&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;get hold of a production db with a fixed as-of&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;given a “seed entity”, perform a graph traversal (via EAVT and VAET indexes) starting from that entity to determine reachable entities, judiciously blacklisting attributes (and whitelisting “backward-pointing” ones) to avoid importing too much&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;copy those entities to my fresh DB&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;run the test!&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This can be done generically. I’ve written &lt;a href="https://gist.github.com/nathell/d3b6f9509a00857cd1843e366797f884"&gt;some proof-of-concept code&lt;/a&gt; that wraps a Datomic db to implement the &lt;a href="https://github.com/aysylu/loom"&gt;Loom&lt;/a&gt; graph protocol, so that one can use Loom’s graph algorithms to perform a breadth-first entity scan, and a function to walk over those entities and convert them to a transaction applicable on top of a pristine DB. So far I’ve been able to extract meaningful small sub-dbs (on the order of ~10K datoms) from my huge production DB of 17+ billion datoms.&lt;/p&gt;&lt;p&gt;This is a gist for now, but let me know if there’s interest and I can convert it into a proper library.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2025-02-21:post:double-double-toil-and-trouble</id>
    <title>Double, double toil and trouble or, Corner-Cases of Comparing Clojure Numbers</title>
    <link href="http://blog.danieljanus.pl/double-double-toil-and-trouble/"/>
    <updated>2025-02-21T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;&lt;a href="https://www.destroyallsoftware.com/talks/wat"&gt;Let’s talk about&lt;/a&gt; Clojure.&lt;/p&gt;&lt;p&gt;In Clojure, comparing two numbers can throw an exception.&lt;/p&gt;&lt;img src="/img/blog/wat-shark.jpg" alt="Wat"&gt;
&lt;p&gt;Check this out:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1/4&lt;/span&gt; &lt;span class="hljs-number"&gt;0.5M&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;;=&amp;gt; true        ; as expected&lt;/span&gt;

(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1/3&lt;/span&gt; &lt;span class="hljs-number"&gt;0.5M&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;; Execution error (ArithmeticException) at java.math.BigDecimal/divide (BigDecimal.java:1783).&lt;/span&gt;
&lt;span class="hljs-comment"&gt;; Non-terminating decimal expansion; no exact representable decimal result.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But why? Why would comparing two perfectly cromulent numbers throw an &lt;code&gt;ArithmeticException&lt;/code&gt;?! Everybody knows that ⅓ &lt; 0.5 – we aren’t dividing by zero or anything like that, are we?&lt;/p&gt;&lt;p&gt;Well, the problem is that we’re comparing a ratio to a &lt;code&gt;BigDecimal&lt;/code&gt; (a decimal number of arbitrary precision). Java doesn’t offer a built-in way of comparing these (Clojure’s ratios aren’t part of the Java standard library), so it has to coerce one into the other. It chooses to coerce the ratio into a BigDecimal, so divides &lt;code&gt;(bigdec 1)&lt;/code&gt; by &lt;code&gt;(bigdec 3)&lt;/code&gt;…&lt;/p&gt;&lt;p&gt;…and that &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#divide-java.math.BigDecimal-"&gt;throws!&lt;/a&gt; The decimal representation of ⅓ is infinite, so you can’t keep all the digits in finite memory.&lt;/p&gt;&lt;p&gt;You may ask: how exactly does Clojure know what coercions to apply and how to produce the result? Let’s look at the code.&lt;/p&gt;&lt;p&gt;The implementation of &lt;code&gt;clojure.core/&lt;&lt;/code&gt; calls the Java method &lt;code&gt;clojure.lang.Numbers.lt&lt;/code&gt;, which is implemented &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.12.0/src/jvm/clojure/lang/Numbers.java#L252-L254"&gt;like this&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs java"&gt;&lt;span class="hljs-keyword"&gt;static&lt;/span&gt; &lt;span class="hljs-keyword"&gt;public&lt;/span&gt; &lt;span class="hljs-type"&gt;boolean&lt;/span&gt; &lt;span class="hljs-title function_"&gt;lt&lt;/span&gt;&lt;span class="hljs-params"&gt;(Object x, Object y)&lt;/span&gt;{
	&lt;span class="hljs-keyword"&gt;return&lt;/span&gt; ops(x).combine(ops(y)).lt((Number)x, (Number)y);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What’s &lt;code&gt;ops&lt;/code&gt;? It’s an implementation of the &lt;code&gt;Ops&lt;/code&gt; interface, which has methods for addition, subtraction, etc.; each number class has its own implementation: there is a &lt;code&gt;LongOps&lt;/code&gt;, &lt;code&gt;RatioOps&lt;/code&gt;, &lt;code&gt;BigDecimalOps&lt;/code&gt; etc.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;combine&lt;/code&gt; method can alter the behaviour of an &lt;code&gt;Ops&lt;/code&gt; depending on the type of the other argument – for example, &lt;code&gt;RatioOps&lt;/code&gt; switches to &lt;code&gt;BigDecimalOps&lt;/code&gt; if the other argument is a &lt;code&gt;BigDecimal&lt;/code&gt;. It’s like a poor man’s implementation of multiple dispatch, which Java doesn’t have.&lt;/p&gt;&lt;p&gt;&lt;code&gt;BigDecimalOps.lt&lt;/code&gt; calls &lt;code&gt;toBigDecimal&lt;/code&gt; on both arguments, and it’s &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.12.0/src/jvm/clojure/lang/Numbers.java#L297-L322"&gt;that method&lt;/a&gt; that performs the failing division:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs java"&gt;&lt;span class="hljs-keyword"&gt;static&lt;/span&gt; BigDecimal &lt;span class="hljs-title function_"&gt;toBigDecimal&lt;/span&gt;&lt;span class="hljs-params"&gt;(Object x)&lt;/span&gt; {
    &lt;span class="hljs-comment"&gt;// ... other cases ...&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (x &lt;span class="hljs-keyword"&gt;instanceof&lt;/span&gt; Ratio) {
        &lt;span class="hljs-type"&gt;Ratio&lt;/span&gt; &lt;span class="hljs-variable"&gt;r&lt;/span&gt; &lt;span class="hljs-operator"&gt;=&lt;/span&gt; (Ratio)x;
        &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; (BigDecimal)divide(&lt;span class="hljs-keyword"&gt;new&lt;/span&gt; &lt;span class="hljs-title class_"&gt;BigDecimal&lt;/span&gt;(r.numerator), r.denominator);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Incidentally, this used to produce the expected result in Clojure up to 1.2.1. At that version, Clojure already used the &lt;code&gt;Ops&lt;/code&gt;-based multiple dispatch, but combining &lt;code&gt;RatioOps&lt;/code&gt; with &lt;code&gt;BigDecimalOps&lt;/code&gt; would yield the former, not the latter.&lt;/p&gt;&lt;p&gt;Is the current behaviour a bug? I’m not sure. It seems so, but maybe 1.3.0’s optimizations warrant this behaviour in the admitedly rare case. There’s an &lt;a href="https://ask.clojure.org/index.php/14411/comparing-ratios-with-bigdecimals-can-throw"&gt;ongoing discussion&lt;/a&gt; on the Ask Clojure Q&amp;A.&lt;/p&gt;&lt;p&gt;So, in current Clojure, how do you compare ratios to bigdecs? Simple, you think: just coerce the bigdec to a double!&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1/3&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;double&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;0.5M&lt;/span&gt;))
&lt;span class="hljs-comment"&gt;;=&amp;gt; true&lt;/span&gt;

(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;2/3&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;double&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;0.5M&lt;/span&gt;))
&lt;span class="hljs-comment"&gt;;=&amp;gt; true&lt;/span&gt;

(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1/2&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;double&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;0.5M&lt;/span&gt;))
&lt;span class="hljs-comment"&gt;;=&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wait, WHAT?&lt;/p&gt;&lt;img src="/img/blog/wat-cat.jpg" alt="Wat"&gt;
&lt;p&gt;Yep. Comparing ratios to doubles for &lt;em&gt;inequality&lt;/em&gt; works fine, but a ratio is never &lt;em&gt;equal&lt;/em&gt; to a double (nor a bigdec), even if said double is an exact representation of the ratio.&lt;/p&gt;&lt;p&gt;This one is documented, but often forgotten about (and not hinted at by the docstring). From Clojure’s &lt;a href="https://clojure.org/guides/equality"&gt;equality guide&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Clojure’s &lt;code&gt;=&lt;/code&gt; is true when called with two immutable scalar values, if:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Both arguments are nil, true, false, the same character, or the same string (i.e. the same sequence of characters).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Both arguments are symbols, or both keywords, with equal namespaces and names.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Both arguments are numbers in the same 'category', and numerically the same, where category is one of:&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;integer or ratio&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;floating point (float or double)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;BigDecimal.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;And indeed, the code for &lt;code&gt;Numbers.equal&lt;/code&gt; has &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.12.0/src/jvm/clojure/lang/Numbers.java#L247-L250"&gt;a check for both operands’ categories&lt;/a&gt; before it delves to the &lt;code&gt;Ops&lt;/code&gt; business that we’ve seen. Remember also that Clojure has a numbers-only &lt;code&gt;==&lt;/code&gt; which doesn’t trigger that category check:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;==&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1/2&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;double&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;0.5M&lt;/span&gt;))
&lt;span class="hljs-comment"&gt;;=&amp;gt; true ; yay&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Corollary: if you want to compare a ratio to a &lt;code&gt;BigDecimal&lt;/code&gt;, you &lt;em&gt;could&lt;/em&gt; coerce the bigdec to a double. That can return an incorrect result only in a very narrow range of cases: when the BigDecimal’s value is close enough to the ratio that it would be lost in the double conversion.&lt;/p&gt;&lt;p&gt;For 100% certainty, the only way I’m aware of is to remember to always use &lt;code&gt;==&lt;/code&gt; when comparing for equality, and explicitly coerce the bigdec to ratio:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;exactly-equals?&lt;/span&gt; [ratio bigdec]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;==&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;*&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt; (&lt;span class="hljs-name"&gt;clojure.lang.Numbers/toRatio&lt;/span&gt; bigdec)) ratio))

(&lt;span class="hljs-name"&gt;exactly-equals?&lt;/span&gt; &lt;span class="hljs-number"&gt;1/18446744073709551616&lt;/span&gt; &lt;span class="hljs-number"&gt;5.42101086242752217003726400434970855712890625E-20M&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;;=&amp;gt; true ; correct even in this pathological case!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(Multiplying by 1 forces Clojure to normalize the ratio. Otherwise, converting &lt;code&gt;0.5M&lt;/code&gt; would have yielded &lt;code&gt;5/10&lt;/code&gt; which doesn’t test &lt;code&gt;==&lt;/code&gt; to &lt;code&gt;1/2&lt;/code&gt;. Go figure.)&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2024-01-26:post:lossy-css-compression</id>
    <title>Lossy CSS compression for fun and loss (or profit)</title>
    <link href="http://blog.danieljanus.pl/lossy-css-compression/"/>
    <updated>2024-01-26T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="what"&gt;What&lt;/h2&gt;&lt;p&gt;Late last year, I had an idea that’s been steadily brewing in my head. I’ve found myself with some free time recently (it coincided with vacation, go figure), and I’ve hacked together some proof-of-concept code. Whether or not it is actually proving the concept I’m not sure, but the results are somewhat interesting, and I believe the idea is novel (I haven’t found any other implementation in the wild). So it’s at least worthy of a blog post.&lt;/p&gt;&lt;p&gt;I wrote &lt;code&gt;cssfact&lt;/code&gt;, a lossy CSS compressor. That is, a program that takes some CSS and outputs back some other CSS that hopefully retains some (most) of the information in the input, but contains fewer rules than the original. Exactly how many rules it produces is configurable, and the loss depends on that number.&lt;/p&gt;&lt;p&gt;The program only works on style rules (which make up the majority of a typical CSS). It leaves the non-style rules unchanged.&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/nathell/cssfact"&gt;Here’s the source&lt;/a&gt;. It’s not exactly straightforward to get it running, but it shouldn’t be very hard, either. It’s very simple – the program itself doesn’t contain any fancy logic; the actual decisions on what the output will contain are made by an external program.&lt;/p&gt;&lt;p&gt;If you just want to see some results, here is a sample with &lt;a href="https://danieljanus.pl"&gt;my homepage&lt;/a&gt; serving as a patient etherized upon a table. Its CSS is quite small – 55 style rules that cssfact can work on – and here’s how the page looks with various settings:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Original: &lt;a href="https://danieljanus.pl"&gt;page&lt;/a&gt;, &lt;a href="https://danieljanus.pl/css/nhp.css"&gt;CSS&lt;/a&gt;, &lt;a href="https://github.com/nathell/nhp/blob/master/src/sass/nhp.sass"&gt;source SASS&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;1 style rule: &lt;a href="https://danieljanus.pl/index1.html"&gt;page&lt;/a&gt;, &lt;a href="https://danieljanus.pl/css/nhp1.css"&gt;CSS&lt;/a&gt; (93% information loss)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;5 style rules: &lt;a href="https://danieljanus.pl/index5.html"&gt;page&lt;/a&gt;, &lt;a href="https://danieljanus.pl/css/nhp5.css"&gt;CSS&lt;/a&gt; (74% information loss)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;10 style rules: &lt;a href="https://danieljanus.pl/index10.html"&gt;page&lt;/a&gt;, &lt;a href="https://danieljanus.pl/css/nhp10.css"&gt;CSS&lt;/a&gt; (55% information loss)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;20 style rules: &lt;a href="https://danieljanus.pl/index20.html"&gt;page&lt;/a&gt;, &lt;a href="https://danieljanus.pl/css/nhp20.css"&gt;CSS&lt;/a&gt; (31% information loss)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;30 style rules: &lt;a href="https://danieljanus.pl/index30.html"&gt;page&lt;/a&gt;, &lt;a href="https://danieljanus.pl/css/nhp30.css"&gt;CSS&lt;/a&gt; (17% information loss)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;My homepage and both of my blogs all use the same CSS, so you can try to replace the CSS in your browser’s devtools elsewhere on the site and see how it looks.&lt;/p&gt;&lt;h2 id="how"&gt;How&lt;/h2&gt;&lt;p&gt;Three words: &lt;a href="https://cs.uef.fi/~pauli/bmf_tutorial/material.html"&gt;binary matrix factorization&lt;/a&gt; (BMF, in the Boolean algebra).&lt;/p&gt;&lt;p&gt;I guess I could just stop here, but I’ll elaborate just in case it isn’t clear.&lt;/p&gt;&lt;p&gt;Consider a simple CSS snippet:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs css"&gt;&lt;span class="hljs-selector-tag"&gt;h1&lt;/span&gt;, &lt;span class="hljs-selector-tag"&gt;h2&lt;/span&gt; {
   &lt;span class="hljs-attribute"&gt;padding&lt;/span&gt;: &lt;span class="hljs-number"&gt;0&lt;/span&gt;;
   &lt;span class="hljs-attribute"&gt;margin-bottom&lt;/span&gt;: &lt;span class="hljs-number"&gt;0.5em&lt;/span&gt;;
}

&lt;span class="hljs-selector-tag"&gt;h1&lt;/span&gt; {
   &lt;span class="hljs-attribute"&gt;font-size&lt;/span&gt;: &lt;span class="hljs-number"&gt;32px&lt;/span&gt;;
   &lt;span class="hljs-attribute"&gt;font-weight&lt;/span&gt;: bold;
}

&lt;span class="hljs-selector-tag"&gt;h2&lt;/span&gt; {
   &lt;span class="hljs-attribute"&gt;font-size&lt;/span&gt;: &lt;span class="hljs-number"&gt;24px&lt;/span&gt;;
   &lt;span class="hljs-attribute"&gt;font-weight&lt;/span&gt;: bold;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first rule tells you that for all elements that match either the &lt;code&gt;h1&lt;/code&gt; or &lt;code&gt;h2&lt;/code&gt; selectors, the two declarations should apply.&lt;/p&gt;&lt;p&gt;You could visualize this CSS as a 5x2 binary matrix &lt;i&gt;A&lt;sup&gt;T&lt;/sup&gt;&lt;/i&gt; where the &lt;em&gt;n&lt;/em&gt; columns correspond to simple selectors (i.e., without commas in them) and the &lt;em&gt;m&lt;/em&gt; rows correspond to declarations:&lt;/p&gt;&lt;style&gt;
.css-table th { text-align: right; }
.css-table td { text-align: center; }
&lt;/style&gt;
&lt;table class="css-table"&gt;
        &lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;code&gt;h1&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code&gt;h2&lt;/code&gt;&lt;/th&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;th&gt;&lt;code&gt;padding: 0&lt;/code&gt;&lt;/th&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;th&gt;&lt;code&gt;margin-bottom: 0.5em&lt;/code&gt;&lt;/th&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;th&gt;&lt;code&gt;font-size: 32px&lt;/code&gt;&lt;/th&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;th&gt;&lt;code&gt;font-size: 24px&lt;/code&gt;&lt;/th&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;th&gt;&lt;code&gt;font-weight: bold&lt;/code&gt;&lt;/th&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You could also transpose the matrix, yielding &lt;em&gt;A&lt;/em&gt; with &lt;em&gt;m&lt;/em&gt; rows denoting selectors and &lt;em&gt;n&lt;/em&gt; columns denoting declarations. For my homepage’s CSS, &lt;em&gt;m&lt;/em&gt; = 60 and &lt;em&gt;n&lt;/em&gt; = 81; for bigger stylesheets, several thousand in either direction is not uncommon.&lt;/p&gt;&lt;p&gt;Now, linear algebra gives us algorithms to find a matrix &lt;em&gt;A′ ≈ A&lt;/em&gt; such that there exists a decomposition &lt;em&gt;A′ = B × C&lt;/em&gt;, where &lt;em&gt;B&lt;/em&gt; has dimensions &lt;em&gt;m × r&lt;/em&gt;, &lt;em&gt;C&lt;/em&gt; has dimensions &lt;em&gt;r × n&lt;/em&gt;, and &lt;em&gt;r&lt;/em&gt; is small – typically much smaller than &lt;em&gt;m&lt;/em&gt; or &lt;em&gt;n&lt;/em&gt;. So this is a way of dimensionality reduction.&lt;/p&gt;&lt;p&gt;In the usual algebra of real numbers, there’s no guarantee that &lt;em&gt;B&lt;/em&gt; or &lt;em&gt;C&lt;/em&gt; will themselves be binary matrices – in fact, most likely they won’t. But if we operate in Boolean algebra instead (i.e. one where 1 + 1 = 1), then both &lt;em&gt;B&lt;/em&gt; and &lt;em&gt;C&lt;/em&gt; will be binary. The flip side is that the Boolean BMF problem is NP-hard, so the algorithms found in the wild perform approximate decompositions, not guaranteed to be optimal.&lt;/p&gt;&lt;p&gt;But that’s okay, because lossiness is inherent in what we’re doing anyway, and it turns the binary matrices &lt;em&gt;B&lt;/em&gt; and &lt;em&gt;C&lt;/em&gt; are readily interpretable. Look again at the CSS matrix above: why is there a 1 in the top-left cell? Because at least one of the CSS rules stipulates the declaration &lt;code&gt;padding: 0&lt;/code&gt; for the selector &lt;code&gt;h1&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This is exactly the definition of matrix multiplication in the Boolean algebra. The matrix &lt;em&gt;A′&lt;/em&gt; will have a 1 at coordinates [&lt;em&gt;i, j&lt;/em&gt;] iff there is at least one &lt;em&gt;k&lt;/em&gt; ∈ {1, …, &lt;em&gt;r&lt;/em&gt;} such that &lt;em&gt;B&lt;/em&gt;[&lt;em&gt;i&lt;/em&gt;, &lt;em&gt;k&lt;/em&gt;] = 1 and &lt;em&gt;C&lt;/em&gt;[&lt;em&gt;k&lt;/em&gt;, &lt;em&gt;j&lt;/em&gt;] = 1. So the columns of &lt;em&gt;B&lt;/em&gt; and rows of &lt;em&gt;C&lt;/em&gt; actually correspond to CSS rules! Every time you write CSS, you’re actually writing out binary matrices – and the browser is multiplying them to get at the actual behaviour.&lt;/p&gt;&lt;p&gt;Well, not really, but it’s one way to think about it. It’s not perfect – it completely glosses over rules overlapping each other and having precedence, and treats them as equally important – but it somewhat works!&lt;/p&gt;&lt;p&gt;You could plug in any BMF algorithm to this approach. For cssfact, I’ve picked the code by &lt;a href="https://github.com/IBM/binary-matrix-factorization/"&gt;Barahona and Goncalves 2019&lt;/a&gt; – sadly, I wasn’t able to find the actual paper – not because it performs spectacularly well (it’s actually dog-slow on larger stylesheets), but because I was easily able to make it work and interface with it.&lt;/p&gt;&lt;h2 id="why"&gt;Why&lt;/h2&gt;&lt;p&gt;Why not?&lt;/p&gt;&lt;p&gt;The sheer joy of exploration is reason enough, but I believe there are potential practical applications. CSS codebases have the tendency to grow organically and eventually start collapsing under their own weight, and they have to be maintained very thoughtfully to prevent that. In many CSS monstrosities found in the wild, there are much cleaner, leaner, essence-capturing cores struggling to get out.&lt;/p&gt;&lt;p&gt;This tool probably won’t automatically extract them for you – so don’t put it in your CI pipeline – but by perusing the CSS that it produces and cross-checking it with the input, you could encounter hints on what redundancy there is in your styles. Things like “these components are actually very similar, so maybe should be united” may become more apparent.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2023-09-09:post:transducers</id>
    <title>My mental model of transducers</title>
    <link href="http://blog.danieljanus.pl/transducers/"/>
    <updated>2023-09-09T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;&lt;p&gt;I’ve been programming in Clojure for a long time, but I haven’t been using transducers much. I learned to mechanically transform &lt;code&gt;(into [] (map f coll))&lt;/code&gt; to &lt;code&gt;(into [] (map f) coll)&lt;/code&gt; for a slight performance gain, but not much beyond that. Recently, however, I’ve found myself refactoring transducers-based code at work, which prompted me to get back to speed.&lt;/p&gt;&lt;p&gt;I found Eero Helenius’ article &lt;a href="https://dev.solita.fi/2021/10/14/grokking-clojure-transducers.html"&gt;“Grokking Clojure transducers”&lt;/a&gt; a great help in that. To me, it’s much more approachable than the &lt;a href="https://clojure.org/reference/transducers"&gt;official documentation&lt;/a&gt; – in a large part because it shows you how to build transducers from the ground up, and this method of learning profoundly resonates with me. I highly recommend it. However, it’s also useful to have a visual intuition of how transducers work, a mental model that hints at the big picture without zooming into the details too much. In this post, I’d like to share mine and illustrate it with a REPL session. (Spoiler alert: there’s &lt;a href="https://github.com/clojure/core.async"&gt;core.async&lt;/a&gt; ahead, but in low quantities.)&lt;/p&gt;&lt;h2 id="pictures"&gt;Pictures&lt;/h2&gt;&lt;p&gt;Imagine data flowing through a conveyor belt. Say, infinitely repeating integers from 1 to 5:&lt;/p&gt;&lt;img src="/img/blog/conveyor-belt.svg" alt="Conveyor belt"&gt;
&lt;p&gt;I’m using the abstract term “conveyor belt”, rather than “sequence” or something like this, to avoid associations with any implementation details. Just pieces of data, one after another. These data may be anything; they may flow infinitely or stop at some point; may or may not all exist in memory at the same time. Doesn’t matter. That’s the beauty of transducers: they completely abstract away the implementation of sequentiality.&lt;/p&gt;&lt;p&gt;So, what is a transducer, intuitively? It’s a mechanism for &lt;em&gt;transforming conveyor belts into other conveyor belts&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;For example, &lt;code&gt;(map inc)&lt;/code&gt; is a transducer that says: “take this conveyor belt and produce one where every number is incremented”. Applying it to the above belt yields this one:&lt;/p&gt;&lt;img src="/img/blog/conveyor-belt-2.svg" alt="Conveyor belt, transformed"&gt;
&lt;p&gt;An important thing about transducers is that they’re &lt;em&gt;composable&lt;/em&gt;. To understand that, imagine further transforming the above belt by removing all the odd numbers. Intuitively, that’s what &lt;code&gt;(remove odd?)&lt;/code&gt; does:&lt;/p&gt;&lt;img src="/img/blog/conveyor-belt-3.svg" alt="Conveyor belt, transformed again"&gt;
&lt;p&gt;(I’ve left the spacing between boxes the same as before, because it helps me visualise &lt;code&gt;(remove odd?)&lt;/code&gt; better. I imagine an invisible gnome sitting above the belt, watching carefully all the boxes that pass below it, and snatching greedily every one that happens to contain an odd number.)&lt;/p&gt;&lt;p&gt;Composability means that Clojure lets you say &lt;code&gt;(comp (map inc) (remove odd?))&lt;/code&gt; to mean the transducer that transforms the first belt to the third one. By putting together two simple building blocks, we produced a more complex one – that it itself reusable and can be used as another building block in an ever more complex data pipeline.&lt;/p&gt;&lt;p&gt;Notice we &lt;em&gt;still&lt;/em&gt; haven’t said anything about the actual representation of the data, but are already able to model complex processes. We can then apply them to actual data, whether it’s a simple vector-to-vector transformation within the same JVM, or listening to a topic on a Kafka cluster, summarizing the incoming data and sending them to a data warehouse.&lt;/p&gt;&lt;h2 id="code"&gt;Code&lt;/h2&gt;&lt;p&gt;OK, enough handwaving, time for a demo. Let’s fire up a REPL and load core.async (I’m assuming you’ve added it to your dependencies already). I won’t reproduce here the resulting values of expressions we evaluate (they’re mostly &lt;code&gt;nil&lt;/code&gt;s anyway), but I will reproduce output from the REPL (as comments).&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;require&lt;/span&gt; &amp;#x27;[clojure.core.async &lt;span class="hljs-symbol"&gt;:refer&lt;/span&gt; [chan &amp;lt;!! &amp;gt;!! thread close!]])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Why core.async? Because I find it a great way to implement a conveyor belt that you can play with interactively. This can help you understand how the various Clojure-provided transducers work. For the noncognoscenti: core.async is a Clojure library that allows you to implement concurrent processes that communicate over &lt;em&gt;channels&lt;/em&gt;. By default, that communication is synchronous, meaning that if a process tries to read from a channel, it blocks until another process writes something to that channel.&lt;/p&gt;&lt;p&gt;As it happens, we can pass a transducer to the function that creates channels, &lt;code&gt;chan&lt;/code&gt;. It will put the invisible gnomes to work on values that pass through the channel. So you can view that channel as a conveyor belt!&lt;/p&gt;&lt;p&gt;For easy tinkering, we can do this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;transformed-belt&lt;/span&gt; [xf]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [ch (&lt;span class="hljs-name"&gt;chan&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt; xf)]
    (&lt;span class="hljs-name"&gt;thread&lt;/span&gt;
      (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;loop&lt;/span&gt;&lt;/span&gt; []
        (&lt;span class="hljs-name"&gt;when-some&lt;/span&gt; [value (&lt;span class="hljs-name"&gt;&amp;lt;!!&lt;/span&gt; ch)]
          (&lt;span class="hljs-name"&gt;println&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Value:&amp;quot;&lt;/span&gt; (&lt;span class="hljs-name"&gt;pr-str&lt;/span&gt; value)))
          (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;recur&lt;/span&gt;&lt;/span&gt;)))
    ch))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This fires up a process working at the receiving end of the conveyor belt. It will print out any transformed values as soon as they become available. Typing at the REPL, we will assume the role of producer, putting data on the belt.&lt;/p&gt;&lt;p&gt;Like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;b&lt;/span&gt; (&lt;span class="hljs-name"&gt;transformed-belt&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; inc)))
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;2&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;; Value: 3&lt;/span&gt;
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;42&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;; Value: 43&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It works! We’re putting in numbers, and out come the incremented ones.&lt;/p&gt;&lt;p&gt;When we’re done experimenting with the belt, we need to &lt;code&gt;close!&lt;/code&gt; it. This will cause the worker thread to shutdown.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;close!&lt;/span&gt; b)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now experiment with something more complex, like that combined transducer we’ve talked about before:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;b&lt;/span&gt; (&lt;span class="hljs-name"&gt;transformed-belt&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;comp&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; inc) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;remove&lt;/span&gt;&lt;/span&gt; odd?))))
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;1&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;; Value: 2&lt;/span&gt;
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;2&lt;/span&gt;)
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;3&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;; Value: 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We got the transformed 1 and 3, but the intermediate value for 2 was odd, so it was snatched by the gnome and we never saw it.&lt;/p&gt;&lt;p&gt;There’s even more fun to be had! Let’s try &lt;code&gt;(partition-all 3)&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;close!&lt;/span&gt; b)
(&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;b&lt;/span&gt; (&lt;span class="hljs-name"&gt;transformed-belt&lt;/span&gt; (&lt;span class="hljs-name"&gt;partition-all&lt;/span&gt; &lt;span class="hljs-number"&gt;3&lt;/span&gt;)))
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;1&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nothing…&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;2&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Still nothing…&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;3&lt;/span&gt;)
&lt;span class="hljs-comment"&gt;; Value: [1 2 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Blammo! Our gnome is now packaging together incoming items into bundles of three, caching them in the interim while the bundle is not complete yet. But if we close the input prematurely, it will acknowledge and produce the incomplete bundle:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;4&lt;/span&gt;)
(&lt;span class="hljs-name"&gt;&amp;gt;!!&lt;/span&gt; b &lt;span class="hljs-number"&gt;5&lt;/span&gt;)
(&lt;span class="hljs-name"&gt;close!&lt;/span&gt; b)
&lt;span class="hljs-comment"&gt;; Value: [4 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In fact, &lt;code&gt;partition-all&lt;/code&gt; is what prompted me to write this post. That code at work I mentioned actually included a transducer composition that had a &lt;code&gt;(net.cgrand.xforms/into [])&lt;/code&gt; in it. That transducer (from Christophe Grand’s &lt;a href="https://github.com/cgrand/xforms/"&gt;xforms&lt;/a&gt; library) accumulates data until there’s nothing more to accumulate, and then emits all of it as one large vector. By replacing it with &lt;code&gt;partition-all&lt;/code&gt;, I altered the downstream processing to handle multiple smaller batches rather than one huge batch, improving the system’s latency.&lt;/p&gt;&lt;p&gt;A small change for a huge win. Clojure continues to amaze me.&lt;/p&gt;&lt;p&gt;Plus, it’s fun to make JS-less animations in SVG. :)&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2021-09-25:post:testing-lithium</id>
    <title>Testing a compiler that can’t even print stuff out</title>
    <link href="http://blog.danieljanus.pl/testing-lithium/"/>
    <updated>2021-09-25T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;I’m enjoying a week-long vacation. In addition to other vacationy things (a trip to Prague, yay!), I wanted to do some off-work programming Just For Fun™ and revisit one of my dormant pet projects, to see if I can make some progress.&lt;/p&gt;&lt;p&gt;I opted for Lithium, my toy x86 assembler and Lisp compiler that hasn’t seen new development since 2014. But before that, I had &lt;a href="/2012/05/14/lithium/"&gt;blogged&lt;/a&gt; &lt;a href="/2013/05/26/lithium-revisited/"&gt;about it&lt;/a&gt; and even &lt;a href="https://danieljanus.pl/talks/reveal.js/2013-euroclojure.html#/"&gt;talked about it&lt;/a&gt; at EuroClojure one time.&lt;/p&gt;&lt;p&gt;Over the week, I’ve re-read the &lt;a href="http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf"&gt;paper&lt;/a&gt; that I’ve been loosely following while developing Lithium. In it, Abdulaziz Ghuloum advocates to have a testing infrastructure from day one, so that one can ensure that the compiler continues to work after each small modification. I’d cut corners on it before, but today, I’ve finally added one.&lt;/p&gt;&lt;p&gt;What’s the big deal? And why not earlier?&lt;/p&gt;&lt;p&gt;One of the original goals that I set myself for Lithium is that it have no runtime dependencies. Not even a C library; not even an OS. It produces raw x86 binaries targetting real mode – non-relocatable blobs of raw machine code. I’m running them in DOSBox, because it’s convenient, but the point is it’s not necessary.&lt;/p&gt;&lt;p&gt;(Some day, I’ll write a mission statement to explain why. But that’s a story for another day.)&lt;/p&gt;&lt;p&gt;And because the setup is so minimalistic, the setup suggested by Ghuloum becomes unfeasible. Ghuloum presupposes the existence of a host C compiler and linker; I have no such privilege. By itself, Lithium can barely output stuff to screen. There’s a &lt;code&gt;write-char&lt;/code&gt; primitive that emits one character, but nothing more than that. And there’s as yet no library to add things to, because there’s no &lt;code&gt;defn&lt;/code&gt; and not much of a global environment.&lt;/p&gt;&lt;p&gt;So what to do? I thought about the invariant in Ghuloum’s design, one that Lithium inherits as well:&lt;/p&gt;&lt;p&gt;&lt;em&gt;Every expression is compiled to machine code that puts its value in the &lt;code&gt;AX&lt;/code&gt; register.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;If I could somehow obtain the values that the CPU registers have at the end of executing a Lithium-compiled program, then I could compare them to the expected value in a test. But how to grab those registers?&lt;/p&gt;&lt;p&gt;That turned out to be easier than expected. Instead of extending Lithium to support printing decimal or hexadecimal numbers, I just grabbed &lt;a href="http://www.fysnet.net/yourhelp.htm"&gt;some pre-existing assembly code&lt;/a&gt; to affix to the program as an epilog. (It does depend on DOS’s interrupt &lt;code&gt;21h&lt;/code&gt;, but hey, it doesn’t hurt to have it for debugging/testing only.) Surprise: the snippet failed to compile, because Lithium’s assembler is woefully incomplete! But it was easy enough to extend it until it worked.&lt;/p&gt;&lt;p&gt;So this gave me a way to view the program’s results.&lt;/p&gt;&lt;img src="/img/blog/lithium-testing.png"&gt;
&lt;p&gt;But there’s another problem: these results are printed within DOSBox. In the emulated DOS machine. I needed a way to transfer them back to the host. Can you guess how?&lt;/p&gt;&lt;p&gt;Yes, you’re right: the simplest thing (DOS redirection to a file, as in &lt;code&gt;PROG.COM &gt;REG.TXT&lt;/code&gt;) works. And you’ll laugh at me that it hasn’t occurred to me until now, when I’m writing up the &lt;a href="https://github.com/nathell/lithium/commit/27563b3c5b92f32b24f750d98248d013f924a700"&gt;commit&lt;/a&gt; that’s already out in the wild. Another proof that it pays to write documentation.&lt;/p&gt;&lt;p&gt;My original idea was… SCREEN CAPTURE!&lt;/p&gt;&lt;p&gt;I’ve scavenged Google for a DOS screen grabber that can produce text files and is not a TSR, &lt;a href="http://www.pc-tools.net/dos/dosutils/"&gt;found one&lt;/a&gt;, bundled it with Lithium, and wrote &lt;a href="https://github.com/nathell/lithium/blob/27563b3c5b92f32b24f750d98248d013f924a700/src/lithium/driver.clj#L23-L36"&gt;some duct-tape code&lt;/a&gt; that invokes the compiled program and the screen grabber in turn and then parses the output. With that, I can finally have &lt;a href="https://github.com/nathell/lithium/blob/27563b3c5b92f32b24f750d98248d013f924a700/test/lithium/compiler_test.clj"&gt;tests&lt;/a&gt; that check whether &lt;code&gt;(+ 3 4)&lt;/code&gt; is really &lt;code&gt;7&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;And now let me go refactor it…&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2020-11-08:post:coronalotto</id>
    <title>I made a website to guess tomorrow’s number of COVID-19 cases, and here’s what happened</title>
    <link href="http://blog.danieljanus.pl/coronalotto/"/>
    <updated>2020-11-08T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="before"&gt;Before&lt;/h2&gt;&lt;p&gt;It seems so obvious in hindsight. Here in Poland, people have been guessing it ever since the pandemic breakout: in private conversations, in random threads on social media, in comments under governmental information outlets. It seemed a matter of time before someone came up with something like this. In fact, on one Sunday evening in October, I found myself flabbergasted that apparently no one yet has.&lt;/p&gt;&lt;p&gt;I doled out $4 for a domain, &lt;a href="http://koronalotek.pl"&gt;koronalotek.pl&lt;/a&gt; (can be translated as “coronalotto” or “coronalottery” – occurrences of the name on Twitter date back at least as far as April), and fired up a REPL. A few hours and 250 Clojure LOCs later, the site was up.&lt;/p&gt;&lt;p&gt;I wanted it to be as simple as possible. A form with two fields: “your name” and “how many cases tomorrow?” A top-ten list of today’s winners, sorted by the absolute difference between the guess and the actual number of cases, as &lt;a href="https://twitter.com/mz_gov_pl"&gt;reported daily on Twitter&lt;/a&gt; by the Polish Ministry of Health. The official number, prominently displayed. And that’s all.&lt;/p&gt;&lt;img src="/img/blog/koronalotek.png"&gt;
&lt;p&gt;On 17 October, I posted the link on my Facebook and Twitter feeds, and waited. The stream of guesses started to trickle in.&lt;/p&gt;&lt;h2 id="after"&gt;After&lt;/h2&gt;&lt;p&gt;It never grew to be more than a stream, but it hasn’t gone completely unnoticed either.&lt;/p&gt;&lt;img src="/img/blog/koronalotek-g1.png"&gt;
&lt;p&gt;The above plot shows daily number of accepted guesses (i.e., those that were used to generate the next day’s winners) over time – a metric of popularity. Each day’s number means guesses cast in the 24 hours up until 10:30 (Warsaw time) on that day, which is when the official numbers are published by the Ministry of Health.&lt;/p&gt;&lt;p&gt;I’ve been filtering out automated submissions, as well as excess manual submissions by the same IP that seemed to skew the results too much – I’ve arbitrarily set the “excess” threshold at 10. The missing datapoint for 19 October is not a zero, but a N/A: I’ve lost that datapoint due to a glitch. More on this below.&lt;/p&gt;&lt;p&gt;The interest peaked on October 23, with more than a thousand guesses for that day (I think it was reposted by someone with a significant outreach back then), and has been slowly declining since.&lt;/p&gt;&lt;p&gt;I have privately received some feedback. One person has pointed out that they found the site distasteful and that making fun of pandemic tragedies made them uncomfortable. (I empathise; for me it’s not so much making fun as it is a coping mechanism—a way to put distance between my thoughts and the difficult times we’re in and to keep fears at bay.) Some people, however, have thanked me for making them smile when they guessed more or less correctly.&lt;/p&gt;&lt;p&gt;Back to data. Being a data junkie, I looked at what I had been collecting. First things first: how accurate is the collective predictive power of the guessers?&lt;/p&gt;&lt;img src="/img/blog/koronalotek-g2.png"&gt;
&lt;p&gt;Quite accurate, in fact! Data for this plot has only been slightly preprocessed, by filtering out “unreasonable” guesses that don’t fall within the range &lt;code&gt;[100; 50000]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;People have over- and underguesstimated the number of new cases, but not by much. There were only a few occasions where the actual case count didn’t fall within one standard deviation of the mean of guesses (represented by the whiskers around blue bars on the plot). Granted, the daily standard deviation tends to be large (on the order of a few thousand), but still, I’m impressed. A paper on estimating the growth of pandemic based on coronalottery results coming soon to a journal near you! ;-)&lt;/p&gt;&lt;p&gt;Just for the heck of it, I’ve also been looking at individual votes. Specifically, names. Here’s a snapshot of unique guessers’ names sorted by decreasing length, on 23 October. (NSFW warning: expletives ahead!)&lt;/p&gt;&lt;img src="/img/blog/koronalotek-names.jpg"&gt;
&lt;p&gt;Let me translate a few of these for those of you who don’t speak Polish:&lt;/p&gt;&lt;p&gt;1 is “Sasin has fucked over 70 million zlotys for elections that didn’t take place and was never held responsible.” This alludes to the &lt;a href="https://notesfrompoland.com/2020/05/27/70-million-zloty-bill-for-polands-abandoned-presidential-election/"&gt;ghost election in Poland&lt;/a&gt; from May. This news had gone memetic, going so far as Minister Sasin’s name being ironically used as a dimensionless unit of 70 million (think Avogadro’s number). You’ll discover the same theme in #2, #3, #5, and others.&lt;/p&gt;&lt;p&gt;6 is “CT {Constitutional Tribunal}, you focking botch, stop repressing my abortion”. Just a day before, the Polish constitutional court (whose current legality is &lt;a href="https://en.wikipedia.org/wiki/Constitutional_Tribunal_(Poland)#2015%E2%80%93present:_Polish_Constitutional_Court_crisis"&gt;disputed at best&lt;/a&gt;) has &lt;a href="https://notesfrompoland.com/2020/10/22/constitutional-court-ruling-ends-almost-all-legal-abortion-in-poland/"&gt;decreed a ban on almost all legal abortion&lt;/a&gt; in Poland, giving rise to &lt;a href="https://edition.cnn.com/2020/10/31/europe/poland-abortion-protests-scli-intl/index.html"&gt;the biggest street protests in decades&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Not all is political: 4 is “Why study for the exam if we’re not gonna survive until November anyway?”. I hope whoever wrote this is alive and well.&lt;/p&gt;&lt;p&gt;Corollary? Give people a text field, and they’ll use it to express themselves: politically or otherwise.&lt;/p&gt;&lt;p&gt;In fact, I have taken the liberty of chiming in. Shortly after, I altered the thank-you page (which used to just say “thanks for guessing”) to proudly display one of the emblems of the Women’s Strike, along with a link to a &lt;a href="https://zrzutka.pl/kasa-na-aborcyjny-dream-team-55g5gx"&gt;crowdfounding campaign&lt;/a&gt; for an NGO that supports women needing abortion.&lt;/p&gt;&lt;img src="/img/blog/koronalotek-thanks.jpg"&gt;
&lt;h2 id="inside-out"&gt;Inside out&lt;/h2&gt;&lt;p&gt;I’m not much of a DevOps person, so I deployed it the quick and dirty way, not caring about scalability or performance. The maxim “make it as simple as possible” permeates the setup.&lt;/p&gt;&lt;p&gt;I just started a REPL within a &lt;code&gt;screen&lt;/code&gt; session on the tiny Scaleway C1 server that also hosts this blog and some of my other personal stuff. I launched a Jetty server within it, and set up a nginx proxy. And that’s pretty much it. I liberally tinker with the app’s state in “production,” evaluating all kinds of expressions when I feel like it.&lt;/p&gt;&lt;p&gt;Code changes are deployed by &lt;code&gt;git pull&lt;/code&gt;ing new developments and doing &lt;code&gt;(require 'koronalotek.core :reload)&lt;/code&gt; in the REPL.&lt;/p&gt;&lt;p&gt;Someone tried a SQL injection attack. This is doomed to fail because there’s no SQL involved. In fact, there’s no database at all. The entire state is kept in an in-memory atom and periodically synced out to an EDN file. In addition, state is reset and archived daily at the time of announcing winners. (I’ve added the archiving after forgetting it on one occasion – hence the lack of data for 19 October.)&lt;/p&gt;&lt;p&gt;I also don’t yet have a mechanism of automatically pulling in the Ministry of Health’s data. Every morning, I spend two minutes checking if there’s excess automatic votes, removing them if any, and then filling in the blanks:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;new-data!&lt;/span&gt; #inst &lt;span class="hljs-string"&gt;&amp;quot;2020-11-08T10:30+01:00&amp;quot;&lt;/span&gt; &lt;span class="hljs-number"&gt;24785&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For all the violations of good practices in this setup, it has worked out surprisingly well so far. I’ve resorted to removing automated votes a handful of times, and blacklisting IPs of voting bots in the nginx setup twice, but otherwise it’s been a low-maintenance toy. People seem to be willing to have fun, and I’m just not interfering.&lt;/p&gt;&lt;h2 id="takeaways"&gt;Takeaways&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;span&gt;You should call on your country’s authorities to exert pressure on the Polish government to respect women’s choices and stop actively repressing them.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Give people a text field, and they’ll use it to express themselves.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Release early, release often.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2020-05-08:post:making-of-clojure-dependency</id>
    <title>Making of “Clojure as a dependency”</title>
    <link href="http://blog.danieljanus.pl/making-of-clojure-dependency/"/>
    <updated>2020-05-08T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;In my previous post, &lt;a href="/2020/05/02/clojure-dependency/"&gt;“Clojure as a dependency”&lt;/a&gt;, I’ve presented the results of some toy research on Clojure version numbers seen in the wild. I’m a big believer in &lt;a href="https://en.wikipedia.org/wiki/Reproducibility#Reproducible_research"&gt;reproducible research&lt;/a&gt;, so I’m making available a &lt;a href="https://github.com/nathell/versions"&gt;Git repo&lt;/a&gt; that contains code you can run yourself to reproduce these results. This post is an experience report from writing that code.&lt;/p&gt;&lt;p&gt;There are two main components to this project: acquisition and analysis of data (implemented in the namespaces &lt;code&gt;versions.scrape&lt;/code&gt; and &lt;code&gt;versions.analyze&lt;/code&gt;, respectively). Let’s look at each of these in turn.&lt;/p&gt;&lt;h2 id="data-acquisition"&gt;Data acquisition&lt;/h2&gt;&lt;p&gt;This step uses the &lt;a href="https://developer.github.com/v3/"&gt;GitHub API v3&lt;/a&gt; to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;retrieve the 1000 most popular Clojure repositories (using the &lt;a href="https://developer.github.com/v3/search/#search-repositories"&gt;Search repositories&lt;/a&gt; endpoint and going through all &lt;a href="https://developer.github.com/v3/#pagination"&gt;pages&lt;/a&gt; of the paginated result);&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;for each of these repositories, look at its file list (in the master branch) and pick up any files named &lt;code&gt;project.clj&lt;/code&gt; or &lt;code&gt;deps.edn&lt;/code&gt; in the root directory, using the &lt;a href="https://developer.github.com/v3/repos/contents/"&gt;Contents&lt;/a&gt; endpoint);&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;parse each of these files and extract the list of dependencies.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As hinted by the namespace, I’ve opted to use &lt;a href="https://github.com/nathell/skyscraper"&gt;Skyscraper&lt;/a&gt; to orchestrate the process. It would arguably have been simpler to use GitHub’s &lt;a href="https://developer.github.com/v4/"&gt;GraphQL v4 API&lt;/a&gt;, but I wanted to showcase Skyscraper’s custom parsing facilities.&lt;/p&gt;&lt;p&gt;There’s no actual HTML scraping going on (all processors use either JSON or Clojure parsers), but Skyscraper is still able to “restructure” the result – traverse the graph endpoint in a manner similar to that of GraphQL – with very little effort. It would have been possible with any other RESTful API. Plus, we get goodies like caching or tree pruning for free.&lt;/p&gt;&lt;p&gt;Most of the code is straightforward, but parsing of &lt;code&gt;project.clj&lt;/code&gt; merits some explanation. Some of my initial assumptions proved incorrect, and it’s fun to see how. I initially tried to use &lt;a href="https://clojure.github.io/clojure/clojure.edn-api.html#clojure.edn/read"&gt;&lt;code&gt;clojure.edn&lt;/code&gt;&lt;/a&gt;, but Leiningen project definitions are not actually EDN – they are Clojure code, which is a superset of EDN. So I had to resort to &lt;code&gt;read-string&lt;/code&gt; from core – with &lt;code&gt;*read-eval*&lt;/code&gt; bound to nil (otherwise the code would have a Clojure injection vulnerability – think &lt;a href="https://xkcd.com/327/"&gt;Bobby Tables&lt;/a&gt;). Needless to say, some &lt;code&gt;project.clj&lt;/code&gt;s turned out to depend on read-eval.&lt;/p&gt;&lt;p&gt;Some projects (I’m looking at you, &lt;a href="https://github.com/dundalek/closh"&gt;Closh&lt;/a&gt;, &lt;a href="https://github.com/borkdude/babashka"&gt;Babashka&lt;/a&gt; and &lt;a href="https://github.com/borkdude/sci"&gt;sci&lt;/a&gt;) keep the version number outside of &lt;code&gt;project.clj&lt;/code&gt;, in a text file (typically in &lt;code&gt;resources/&lt;/code&gt;), and slurp it back into &lt;code&gt;project.clj&lt;/code&gt; with a read-eval’d expression:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;defproject&lt;/span&gt; closh-sci
  #=(&lt;span class="hljs-name"&gt;clojure.string/trim&lt;/span&gt;
     #=(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;slurp&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;resources/CLOSH_VERSION&amp;quot;&lt;/span&gt;))
  …)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A trick employed by one project, &lt;a href="https://github.com/metabase/metabase"&gt;Metabase&lt;/a&gt;, is to dynamically generate JVM options containing a port number at parse time, so that test suites running at the same time don’t clash with each other:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;#=(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;eval&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;format&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;-Dmb.jetty.port=%d&amp;quot;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;3001&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;rand-int&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;500&lt;/span&gt;))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, it turned out that &lt;code&gt;defproject&lt;/code&gt; is not always a first form in &lt;code&gt;project.clj&lt;/code&gt;. Some projects, like &lt;a href="https://github.com/robert-stuttaford/bridge"&gt;bridge&lt;/a&gt;, only contain a placeholder &lt;code&gt;project.clj&lt;/code&gt; with no forms; others, like &lt;a href="https://github.com/ztellman/aleph"&gt;aleph&lt;/a&gt;, first define some constants, and then refer to them in a &lt;code&gt;defproject&lt;/code&gt; form. If those constants contain parts of the dependencies list, then those dependencies won’t be processed correctly. Fortunately, not a lot of projects do this, so it doesn’t skew the results much.&lt;/p&gt;&lt;p&gt;Anyway, the end result of the acquisition phase is a sequence of maps describing project definitions. They look like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;{&lt;span class="hljs-symbol"&gt;:name&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;clojure-koans&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
 &lt;span class="hljs-symbol"&gt;:full-name&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;functional-koans/clojure-koans&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
 &lt;span class="hljs-symbol"&gt;:deps-type&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:leiningen&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
 &lt;span class="hljs-symbol"&gt;:page&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
 &lt;span class="hljs-symbol"&gt;:deps&lt;/span&gt; {org.clojure/clojure #:mvn{&lt;span class="hljs-symbol"&gt;:version&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;1.10.0&amp;quot;&lt;/span&gt;}&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
        koan-engine #:mvn{&lt;span class="hljs-symbol"&gt;:version&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;0.2.5&amp;quot;&lt;/span&gt;}}}&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
 &lt;span class="hljs-symbol"&gt;:profile-deps&lt;/span&gt; {&lt;span class="hljs-symbol"&gt;:dev&lt;/span&gt; {lein-koan #:mvn{&lt;span class="hljs-symbol"&gt;:version&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;0.1.5&amp;quot;&lt;/span&gt;}}}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Homogeneity is important: every dependency description has been converted to the cli-tools format, even if it comes from a &lt;code&gt;project.clj&lt;/code&gt;.&lt;/p&gt;&lt;h2 id="data-analysis"&gt;Data analysis&lt;/h2&gt;&lt;p&gt;I’ve long been searching for a way to do exploratory programming in Clojure without turning the code to a tangled mess, portable only along with my computer.&lt;/p&gt;&lt;p&gt;Exploratory (or research) programming is very different from “normal” programming. In the latter, most of the time you typically focus on a coherent project – a program or a library. In contrast, in the former, you spend a lot of time in the REPL, trying all sorts of different things and &lt;code&gt;def&lt;/code&gt;ing new values derived from already computed ones.&lt;/p&gt;&lt;p&gt;This is very convenient, but it’s extremely easy to get carried away in the REPL and get lost in a sea of &lt;code&gt;def&lt;/code&gt;s. If you want to redo your computations from scratch, just about your only option is to take your REPL transcript and re-evaluate the expressions one by one, in the correct order. Cleaning up the code (e.g. deglobalizing) as you go is very difficult.&lt;/p&gt;&lt;p&gt;I’ve found an answer: &lt;a href="https://plumatic.github.io/prismatics-graph-at-strange-loop"&gt;Plumatic Graph&lt;/a&gt;, part of the &lt;a href="https://github.com/plumatic/plumbing"&gt;plumbing&lt;/a&gt; library. There are a plethora of uses for it: for example, at &lt;a href="https://iamfy.co"&gt;Fy&lt;/a&gt;, my current workplace, we’re using it to define our test fixtures. But as it turns out, it makes exploratory programming enjoyable.&lt;/p&gt;&lt;p&gt;The bulk of code in &lt;a href="https://github.com/nathell/versions/blob/master/src/clj/versions/analyze.clj#L41"&gt;&lt;code&gt;versions.analyze&lt;/code&gt;&lt;/a&gt; consists of a big definition of a graph, with nodes representing computations – things that I’d normally have &lt;code&gt;def&lt;/code&gt;’d in a REPL. Consequently, most of these definitions are short and to the point. I also gave the nodes verbose, descriptive, explicit names. Name and conquer. &lt;code&gt;raw-repos&lt;/code&gt; is the output from data acquisition, &lt;code&gt;repos&lt;/code&gt; is an all-important node containing those &lt;code&gt;raw-repos&lt;/code&gt; that were successfully parsed, and most other things depend on it.&lt;/p&gt;&lt;p&gt;It also doesn’t obstruct much the normal REPL research flow. My normal workflow with REPL and Graph is something along the lines of:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span&gt;&lt;code&gt;(def result (main))&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;evaluate something using inputs from &lt;code&gt;result&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;nah, it leads nowhere&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;evaluate something else&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;hey, that’s interesting!&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;add a new node to the graph definition&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;GOTO 1&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Thanks to Graph’s lazy compiler, I can re-evaluate anything at need and have it evaluate only the things needed, and nothing else. Also, because the graph is explicit, it’s fairly easy to &lt;a href="https://github.com/RedBrainLabs/graph-fnk-viz"&gt;visualize it&lt;/a&gt;. (Click the image to open it in full-size in another tab.)&lt;/p&gt;&lt;p&gt;&lt;a href="/img/blog/computation-graph.png" target="_blank"&gt;&lt;img src="/img/blog/computation-graph.png"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Because it’s lazy, it doesn’t hurt to put extra things in there just in case, even when you’re not going to report them. For example, I was curious what things besides a version number people put in dependencies. &lt;code&gt;:exclusions&lt;/code&gt;, for sure, but what else? This is the &lt;code&gt;:what-other-things-besides-versions&lt;/code&gt; node.&lt;/p&gt;&lt;p&gt;Imagine my surprise when I found &lt;code&gt;:exlusions&lt;/code&gt; (&lt;em&gt;sic&lt;/em&gt;) in there, which turned out to be a typo in shadow-cljs’ &lt;code&gt;project.clj&lt;/code&gt;! I submitted &lt;a href="https://github.com/thheller/shadow-cljs/pull/699"&gt;a PR&lt;/a&gt;, and Thomas Heller merged it a few days after.&lt;/p&gt;&lt;p&gt;My only gripe with Graph is that it runs somewhat contrary to the current trends in the Clojure community: for example, it doesn’t support namespaced keywords (although there’s an &lt;a href="https://github.com/plumatic/plumbing/issues/126"&gt;open ticket&lt;/a&gt; for that). But on the whole, I’m sold. I’ll definitely be using it in the next piece of research in Clojure, and I’m on a lookout for something similar in pure R. If you know something, do tell me!&lt;/p&gt;&lt;h2 id="some-words-on-plotting"&gt;Some words on plotting&lt;/h2&gt;&lt;p&gt;The plot from previous post has been generated in pure R, using &lt;a href="https://ggplot2.tidyverse.org"&gt;ggplot2&lt;/a&gt; (an extremely versatile API). Clojure generates a CSV with munged data, and then R reads that CSV as a data frame and generates the plot in a few lines.&lt;/p&gt;&lt;p&gt;I’ve briefly played around with &lt;a href="https://github.com/scicloj/clojisr"&gt;clojisr&lt;/a&gt;, a bridge between Clojure and R. It was an enlightening experiment, and it would let me avoid the intermediate CSV, but I decided to ditch it for a few reasons:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;It pulls in quite a few dependencies (I wanted to keep them down to a minimum), and requires some previous setup on the R side.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;I’d much rather write my R as R, since I’m comfortable with it, rather than spend time wondering how it maps to Clojure. This is similar to the SQL story: these days I prefer &lt;a href="https://www.hugsql.org"&gt;HugSQL&lt;/a&gt; over &lt;a href="https://github.com/korma/Korma"&gt;Korma&lt;/a&gt;, unless I have good reasons to choose otherwise.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;clojisr opens up a child R process just by &lt;code&gt;require&lt;/code&gt;ing a namespace. I’m not a fan of that.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;But it’s definitely very promising! I applaud the effort and I’ll keep a close eye on it.&lt;/p&gt;&lt;h2 id="key-takeaways"&gt;Key takeaways&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Skyscraper makes data acquisition bearable, if not fun.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Plumatic Graph makes writing research code in Clojure fun.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;ggplot makes plotting data fun.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Clojure makes programming fun. (But you knew that already.)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2020-05-02:post:clojure-dependency</id>
    <title>Clojure as a dependency</title>
    <link href="http://blog.danieljanus.pl/clojure-dependency/"/>
    <updated>2020-05-02T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;I have a shameful confession to make: I have long neglected an open-source library that I maintain, &lt;a href="https://github.com/nathell/clj-tagsoup"&gt;clj-tagsoup&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This would have been less of an issue, but this is my second-most-starred project on GitHub. Granted, I don’t feel a need for it anymore, but apparently people do. I wish I had spent some time reviewing and merging the incoming PRs.&lt;/p&gt;&lt;p&gt;Anyway, I’ve recently been prompted to revive it, and I’m preparing a new release. While on it, I’ve been updating dependencies to their latest versions, and upon seeing a dependency on &lt;code&gt;[org.clojure/clojure "1.2.0"]&lt;/code&gt; in &lt;code&gt;project.clj&lt;/code&gt; (yes, it’s been neglected for that long), I started wondering: which Clojure to depend on? Actually, should Clojure itself be a dependency at all?&lt;/p&gt;&lt;p&gt;I’ve googled around for best practices, but with no conclusive answer. So I set out to do some research.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; with Leiningen, add it with &lt;code&gt;:scope "provided"&lt;/code&gt;; with cli-tools, you don’t have to, unless you want to be explicit.&lt;/p&gt;&lt;h2 id="is-it-possible-for-a-clojure-project-to-declare-no-dependency-on-clojure-at-all?"&gt;Is it possible for a Clojure project to declare no dependency on Clojure at all?&lt;/h2&gt;&lt;p&gt;Quite possible, as it turns out. But the details depend on the build tool.&lt;/p&gt;&lt;p&gt;Obviously, this only makes sense for libraries. Or, more broadly, for projects that are not meant to be used standalone, but rather included in other projects (which will have a Clojure dependency of their own).&lt;/p&gt;&lt;h3 id="leiningen"&gt;Leiningen&lt;/h3&gt;&lt;p&gt;If you try to create a Leiningen project that has no dependencies:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;defproject&lt;/span&gt; foo &lt;span class="hljs-string"&gt;&amp;quot;0.1.0&amp;quot;&lt;/span&gt;
  &lt;span class="hljs-symbol"&gt;:dependencies&lt;/span&gt; [])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;then Leiningen (as of version 2.9.3, but I’d guess older versions behave similarly) won’t allow you to launch a REPL:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ lein repl
Error: Could not find or load main class clojure.main
Caused by: java.lang.ClassNotFoundException: clojure.main
Subprocess failed (exit code: 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But all is not lost: &lt;code&gt;lein jar&lt;/code&gt; works just fine (as long as you don’t AOT-compile any namespaces), as does &lt;code&gt;lein install&lt;/code&gt;. The resulting library will happily function as a dependency of other projects.&lt;/p&gt;&lt;p&gt;The upside of depending on no particular Clojure version is that you don’t impose it on your consumers. If a library depends on Clojure 1.9.0, but a project that uses it depends on Clojure 1.10.1, then Leiningen will fetch 1.9.0’s &lt;code&gt;pom.xml&lt;/code&gt; (it’s smart enough to figure out that the jar itself won’t be needed, as the conflict will always be resolved in favour of the direct dependency), and &lt;code&gt;lein deps :tree&lt;/code&gt; will report “possibly confusing dependencies”.&lt;/p&gt;&lt;p&gt;It’s not very useful to have a library that you can’t launch a REPL against, though. So what some people do is declare a dependency on Clojure not in the main &lt;code&gt;:dependencies&lt;/code&gt;, but in a profile.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;defproject&lt;/span&gt; foo &lt;span class="hljs-string"&gt;&amp;quot;0.1.0&amp;quot;&lt;/span&gt;
  &lt;span class="hljs-symbol"&gt;:dependencies&lt;/span&gt; []
  &lt;span class="hljs-symbol"&gt;:profiles&lt;/span&gt; {&lt;span class="hljs-symbol"&gt;:dev&lt;/span&gt; {&lt;span class="hljs-symbol"&gt;:dependencies&lt;/span&gt; [[org.clojure/clojure &lt;span class="hljs-string"&gt;&amp;quot;1.10.1&amp;quot;&lt;/span&gt;]]}})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This avoids conflicts and brings back the possibility to launch a REPL. Sometimes, people create multiple profiles for different Clojure versions; &lt;a href="https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md"&gt;Leiningen’s documentation&lt;/a&gt; mentions this possibility.&lt;/p&gt;&lt;p&gt;Unfortunately, with this approach it’s still not possible to AOT-compile things or create uberjars with Leiningen. (Putting Clojure in the &lt;code&gt;:provided&lt;/code&gt; profile causes building the uberjar to succeed, but the resulting &lt;code&gt;-standalone&lt;/code&gt; jar doesn’t actually contain Clojure).&lt;/p&gt;&lt;p&gt;Another option is to add Clojure to the main &lt;code&gt;:dependencies&lt;/code&gt;, but with &lt;code&gt;:scope "provided"&lt;/code&gt;. Per the &lt;a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html"&gt;Maven documentation&lt;/a&gt;, this means:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;This is much like &lt;code&gt;compile&lt;/code&gt;, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope &lt;code&gt;provided&lt;/code&gt; because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The key are the last words: “not transitive.” If project A depends on a library B that declares a “provided” dependency C, then C won’t be automatically put in A’s dependencies, and A is expected to explicitly declare its own C.&lt;/p&gt;&lt;p&gt;This means that it’s adequate for both libraries and standalone projects when it comes to declaring a Clojure dependency. It doesn’t break anything, doesn’t cause any ephemeral conflicts, and can be combined with the profiles approach when multiple configurations are called for.&lt;/p&gt;&lt;h3 id="cli-tools"&gt;cli-tools&lt;/h3&gt;&lt;p&gt;cli-tools will accept a &lt;code&gt;deps.edn&lt;/code&gt; as simple as &lt;code&gt;{}&lt;/code&gt;. Even passing &lt;code&gt;-Srepro&lt;/code&gt; to &lt;code&gt;clojure&lt;/code&gt; or &lt;code&gt;clj&lt;/code&gt; (which excludes the Clojure dependency that you probably have in your &lt;code&gt;~/.clojure/deps.edn&lt;/code&gt;) doesn’t break anything: cli-tools will just use 1.10.1 (at least as of version 1.10.1.536).&lt;/p&gt;&lt;p&gt;With cli-tools, as a library author you probably don’t have to declare a Clojure dependency at all. But things are less uniform in this land than they are in Leiningen (for example, there are quite a few uberjarrers to choose from), so it’s reasonable to check with your tooling first.&lt;/p&gt;&lt;h3 id="boot"&gt;Boot&lt;/h3&gt;&lt;p&gt;I’m no longer a Boot user, so I can’t tell. But from what I know, it uses Aether just like Leiningen and Maven do, so I’d wager a guess the same caveats apply as for Leiningen. Haven’t checked, though.&lt;/p&gt;&lt;h2 id="so-what-do-the-existing-projects-do?"&gt;So what do the existing projects do?&lt;/h2&gt;&lt;p&gt;I figured it would be a fun piece of research to examine how the popular projects depend (or don’t depend) on Clojure. I queried GitHub’s API for the 1000 most starred Clojure projects, fetched and parsed their &lt;code&gt;project.clj&lt;/code&gt;s and/or &lt;code&gt;deps.edn&lt;/code&gt;s, and tallied things up.&lt;/p&gt;&lt;p&gt;I’ll write a separate “making of” post, because it turned out to be an even more fun weekend project than I had anticipated. But for now, let me share the conclusions.&lt;/p&gt;&lt;p&gt;I ended up with 968 project definition files that I was able to successfully parse: 140 &lt;code&gt;deps.edn&lt;/code&gt;s and 828 &lt;code&gt;project.clj&lt;/code&gt;s. Here’s a breakdown of Clojure version declared as a “main” dependency (i.e., not in a profile or alias):&lt;/p&gt;&lt;img src="/img/blog/clojure-versions.png"&gt;
&lt;p&gt;N/A means that there’s no dependency on Clojure declared, and “other” is an umbrella for the zoo of alphas, betas and snapshots.&lt;/p&gt;&lt;p&gt;As expected, not depending on Clojure is comparatively more popular in the cli-tools land: almost half (48.6%) of cli-tools projects don’t declare a Clojure dependency, versus 21.5% (174 projects) for Leiningen.&lt;/p&gt;&lt;p&gt;That Leiningen number still seemed quite high to me, so I dug a little deeper. Out of those 174 projects, 100 have Clojure somewhere in their &lt;code&gt;:profiles&lt;/code&gt;. The remaining 74 are somewhat of outliers:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;some, like Ring or Pedestal, are umbrella projects composed of sub-projects (with the &lt;code&gt;lein-sub&lt;/code&gt; plugin) that have actual dependencies themselves;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;some, like Klipse or Reagent, are essentially ClojureScript-only;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;some, like Overtone, use the &lt;code&gt;lein-tools-deps&lt;/code&gt; plugin to store their dependencies in &lt;code&gt;deps.edn&lt;/code&gt; while using Leiningen for other tasks.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Finally, the popularity of &lt;code&gt;:scope "provided"&lt;/code&gt; is much lower. Only 68 Leiningen projects specify it (8.9% of those that declare any dependencies), and only two &lt;code&gt;deps.edn&lt;/code&gt; files do so (re-frame and fulcro – note that re-frame actually has both a &lt;code&gt;project.clj&lt;/code&gt; and a &lt;code&gt;deps.edn&lt;/code&gt;).&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2020-02-10:post:cond-indentation</id>
    <title>Indenting cond forms</title>
    <link href="http://blog.danieljanus.pl/cond-indentation/"/>
    <updated>2020-02-10T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;Indentation matters when reading Clojure code. It is the primary visual cue that helps the reader discern the code structure. Most Clojure code seen in the wild conforms to either the &lt;a href="https://github.com/bbatsov/clojure-style-guide#source-code-layout-organization"&gt;community style guide&lt;/a&gt; or the proposed &lt;a href="https://tonsky.me/blog/clojurefmt/"&gt;simplified rules&lt;/a&gt;; the existing editors make it easy to reformat code to match them.&lt;/p&gt;&lt;p&gt;I find both these rulesets to be helpful when reading code. But there’s one corner-case that’s been irking me: &lt;code&gt;cond&lt;/code&gt; forms.&lt;/p&gt;&lt;p&gt;&lt;code&gt;cond&lt;/code&gt; takes an even number of arguments: alternating test-expression pairs. They are commonly put next to each other, two forms per line.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  test expr-1
  another-test expr-2
  &lt;span class="hljs-symbol"&gt;:else&lt;/span&gt; expr-3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sometimes, people align the expressions under one another, in a tabular fashion:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  test         expr-1
  another-test expr-2
  &lt;span class="hljs-symbol"&gt;:else&lt;/span&gt;        expr-3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But things get out of hand when either &lt;code&gt;tests&lt;/code&gt; or &lt;code&gt;exprs&lt;/code&gt; get longer and call for multiple lines themselves. There are several options here, all of them less than ideal.&lt;/p&gt;&lt;h3 id="tests-and-expressions-next-to-each-other"&gt;Tests and expressions next to each other&lt;/h3&gt;&lt;p&gt;In other words, keep the above rule. Because we’ll have multiple lines in a form, this tends to make the resulting code axe-shaped:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;some-function&lt;/span&gt; something) expected-value) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;do&lt;/span&gt;&lt;/span&gt;
                                                 (&lt;span class="hljs-name"&gt;do-this&lt;/span&gt;)
                                                 (&lt;span class="hljs-name"&gt;and-also-do-that&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;another-predicate&lt;/span&gt; something-else) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;try&lt;/span&gt;&lt;/span&gt;
                                       (&lt;span class="hljs-name"&gt;do-another-thing&lt;/span&gt;)
                                       (&lt;span class="hljs-name"&gt;catch&lt;/span&gt; Exception _
                                         (&lt;span class="hljs-name"&gt;println&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Whoops!&amp;quot;&lt;/span&gt;))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This yields code that is indented abnormally far to the right, forcing the reader’s eyeballs to move in two dimensions – even more so if the tabular feel is desired. If &lt;em&gt;both&lt;/em&gt; the test and the expression is multi-lined, it just looks plain weird.&lt;/p&gt;&lt;h3 id="stack-all-forms-vertically,-no-extra-spacing"&gt;Stack all forms vertically, no extra spacing&lt;/h3&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;some-function&lt;/span&gt; something) expected-value)
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;do&lt;/span&gt;&lt;/span&gt;
    (&lt;span class="hljs-name"&gt;do-this&lt;/span&gt;)
    (&lt;span class="hljs-name"&gt;and-also-do-that&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;another-predicate&lt;/span&gt; something-else)
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;try&lt;/span&gt;&lt;/span&gt;
    (&lt;span class="hljs-name"&gt;do-another-thing&lt;/span&gt;)
    (&lt;span class="hljs-name"&gt;catch&lt;/span&gt; Exception _
      (&lt;span class="hljs-name"&gt;println&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Whoops!&amp;quot;&lt;/span&gt;))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This gets rid of the long lines, but introduces another problem: it’s hard to tell at a glance&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;where a given test or expression starts or ends;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;which tests are paired with which expression;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;whether a given line corresponds to a test or an expression, and which one.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="stack-all-forms-vertically,-blank-lines-between-test/expr-pairs"&gt;Stack all forms vertically, blank lines between test/expr pairs&lt;/h3&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;some-function&lt;/span&gt; something) expected-value)
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;do&lt;/span&gt;&lt;/span&gt;
    (&lt;span class="hljs-name"&gt;do-this&lt;/span&gt;)
    (&lt;span class="hljs-name"&gt;and-also-do-that&lt;/span&gt;))

  (&lt;span class="hljs-name"&gt;another-predicate&lt;/span&gt; something-else)
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;try&lt;/span&gt;&lt;/span&gt;
    (&lt;span class="hljs-name"&gt;do-another-thing&lt;/span&gt;)
    (&lt;span class="hljs-name"&gt;catch&lt;/span&gt; Exception _
      (&lt;span class="hljs-name"&gt;println&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Whoops!&amp;quot;&lt;/span&gt;))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The Style Guide &lt;a href="https://github.com/bbatsov/clojure-style-guide#short-forms-in-cond"&gt;says&lt;/a&gt; that this is an “ok-ish” thing to do.&lt;/p&gt;&lt;p&gt;But with the added blank lines, logical structure of the code is much more apparent. However, it breaks another assumption that I make when reading the code: &lt;em&gt;functions contain no blank lines.&lt;/em&gt; The Style Guide even &lt;a href="https://github.com/bbatsov/clojure-style-guide#no-blank-lines-within-def-forms"&gt;mentions it&lt;/a&gt;, saying that &lt;code&gt;cond&lt;/code&gt; forms are an acceptable exception.&lt;/p&gt;&lt;p&gt;It is now harder to tell at a glance where the enclosing function starts or ends. And once this assumption is broken once, the brain expects it to be broken again, causing reading disruption across the entire file.&lt;/p&gt;&lt;h3 id="forms-one-under-another,-extra-indentation-for-expressions-only"&gt;Forms one under another, extra indentation for expressions only&lt;/h3&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;some-function&lt;/span&gt; something) expected-value)
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;do&lt;/span&gt;&lt;/span&gt;
      (&lt;span class="hljs-name"&gt;do-this&lt;/span&gt;)
      (&lt;span class="hljs-name"&gt;and-also-do-that&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;another-predicate&lt;/span&gt; something-else)
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;try&lt;/span&gt;&lt;/span&gt;
      (&lt;span class="hljs-name"&gt;do-another-thing&lt;/span&gt;)
      (&lt;span class="hljs-name"&gt;catch&lt;/span&gt; Exception _
        (&lt;span class="hljs-name"&gt;println&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Whoops!&amp;quot;&lt;/span&gt;))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I resorted to this several times. The lines are not too long; the visual cues are there; it’s obvious what is the condition, what is the test, and what goes with what.&lt;/p&gt;&lt;p&gt;Except… it’s against the rules. List items stacked vertically should be aligned one under the other. I have to actively fight my Emacs to enforce this formatting, and it will be lost next time I press &lt;code&gt;C-M-q&lt;/code&gt; on this form. No good.&lt;/p&gt;&lt;h3 id="forms-one-under-another,-expressions-prefixed-by-#-=&amp;gt;"&gt;Forms one under another, expressions prefixed by &lt;code&gt;#_=&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;cond&lt;/span&gt;&lt;/span&gt;
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;some-function&lt;/span&gt; something) expected-value)
  #_=&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;do&lt;/span&gt;&lt;/span&gt;
         (&lt;span class="hljs-name"&gt;do-this&lt;/span&gt;)
         (&lt;span class="hljs-name"&gt;and-also-do-that&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;another-predicate&lt;/span&gt; something-else)
  #_=&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;try&lt;/span&gt;&lt;/span&gt;
         (&lt;span class="hljs-name"&gt;do-another-thing&lt;/span&gt;)
         (&lt;span class="hljs-name"&gt;catch&lt;/span&gt; Exception _
           (&lt;span class="hljs-name"&gt;println&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Whoops!&amp;quot;&lt;/span&gt;))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This one is my own invention: I haven’t seen it anywhere else. But I think it manages to avoid most problems.&lt;/p&gt;&lt;p&gt;&lt;code&gt;#_&lt;/code&gt; is a reader macro that causes the next form to be elided and not seen by the compiler. &lt;code&gt;=&gt;&lt;/code&gt; is a valid form. Thus, &lt;code&gt;#_=&gt;&lt;/code&gt; is effectively whitespace as far as the compiler is concerned, and the indentation rules treat it as yet another symbol (although it technically isn’t one). No tooling is broken, no assumptions are broken, and the &lt;code&gt;#_=&gt;&lt;/code&gt; tends to be syntax-highlighted unintrusively so it doesn’t stand out. I tend to read it aloud as “then.”&lt;/p&gt;&lt;h3 id="meanwhile,-in-another-galaxy"&gt;Meanwhile, in another galaxy&lt;/h3&gt;&lt;p&gt;Other Lisps (Scheme and CL) wrap each test/expression pair in an extra pair of parens, thereby avoiding the blending of conditions and expressions when indented one under the other. But I’m still happy Clojure went with fewer parens. As I say, this is a corner case where additional pair of parens would somewhat help, but most of the time I find them less aesthetic and a visual clutter.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2020-01-21:post:middleware</id>
    <title>Careful with that middleware, Eugene</title>
    <link href="http://blog.danieljanus.pl/middleware/"/>
    <updated>2020-01-21T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="prologue"&gt;Prologue&lt;/h2&gt;&lt;p&gt;I’ll be releasing version 0.3 of &lt;a href="https://github.com/nathell/skyscraper"&gt;Skyscraper&lt;/a&gt;, my Clojure framework for scraping entire sites, in a few days.&lt;/p&gt;&lt;p&gt;More than three years have passed since its last release. During that time, I’ve made a number of attempts at redesigning it to be more robust, more usable, and faster; the last one, resulting in an almost complete rewrite, is now almost ready for public use as I’m ironing out the rough edges, documenting it, and adding tests.&lt;/p&gt;&lt;p&gt;It’s been a long journey and I’ll blog about it someday; but today, I’d like to tell another story: one of a nasty bug I had encountered.&lt;/p&gt;&lt;h2 id="part-one:-wrap,-wrap,-wrap,-wrap"&gt;Part One: Wrap, wrap, wrap, wrap&lt;/h2&gt;&lt;p&gt;While updating the code of one of my old scrapers to use the API of Skyscraper 0.3, I noticed an odd thing: some of the output records contained scrambled text. Apparently, the character encoding was not recognised properly.&lt;/p&gt;&lt;p&gt;“Weird,” I thought. Skyscraper should be extra careful about honoring the encoding of pages being scraped (declared either in the headers, or the &lt;code&gt;&lt;meta http-equiv&gt;&lt;/code&gt; tag). In fact, I remembered having seen it working. What was wrong?&lt;/p&gt;&lt;p&gt;For every page that it downloads, Skyscraper 0.3 caches the HTTP response body along with the headers so that it doesn’t have to be downloaded again; the headers are needed to ensure proper encoding when parsing a cached page. The headers are lower-cased, so that Skyscraper can then call &lt;code&gt;(get all-headers "content-type")&lt;/code&gt; to get the encoding declared in headers. If this step is missed, and the server returns the encoding in a header named &lt;code&gt;Content-Type&lt;/code&gt;, it won’t be matched. Kaboom!&lt;/p&gt;&lt;p&gt;I looked at the cache, and sure enough, the header names in the cache were not lower-cased, even though they should be. But why?&lt;/p&gt;&lt;p&gt;Maybe I was mistaken, and I had forgotten the lower-casing after all? A glance at the code: no. The lower-casing was there, right around the call to the download function.&lt;/p&gt;&lt;p&gt;Digression: Skyscraper uses &lt;a href="https://github.com/dakrone/clj-http"&gt;clj-http&lt;/a&gt; to download pages. clj-http, in turn, uses the &lt;a href="http://clojure-doc.org/articles/cookbooks/middleware.html"&gt;middleware pattern&lt;/a&gt;: there’s a “bare” request function, and then there are wrapper functions that implement things like redirects, OAuth, exception handling, and what have you. I say “wrapper” because they literally wrap the bare function: &lt;code&gt;(wrap-something request)&lt;/code&gt; returns another function that acts just like &lt;code&gt;request&lt;/code&gt;, but with added functionality. And that other function can in turn be wrapped with yet another one, and so on.&lt;/p&gt;&lt;p&gt;There’s a default set of middleware wrappers defined by clj-http, and it also provides a macro, &lt;code&gt;with-additional-middleware&lt;/code&gt;, which allows you to specify additional wrappers. One such wrapper is &lt;code&gt;wrap-lower-case-headers&lt;/code&gt;, which, as the name suggests, causes the response’s header keys to be returned in lower case.&lt;/p&gt;&lt;p&gt;Back to Skyscraper. We’re ready to look at the code now. Can you spot the problem?&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [request-fn (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;or&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-symbol"&gt;:request-fn&lt;/span&gt; options)
                     http/request)]
  (&lt;span class="hljs-name"&gt;http/with-additional-middleware&lt;/span&gt; [http/wrap-lower-case-headers]
    (&lt;span class="hljs-name"&gt;request-fn&lt;/span&gt; req
                success-fn
                error-fn)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I stared at it for several minutes, did some dirty experiments in the REPL, perused the code of clj-http, until it dawned on me.&lt;/p&gt;&lt;p&gt;See that &lt;code&gt;request-fn&lt;/code&gt;? Even though Skyscraper uses &lt;code&gt;http/request&lt;/code&gt; by default, you can override it in the options to supply your own way of doing HTTP. (Some of the tests use it to mock calls to a HTTP server.) In this particular case, it was not overridden, though: the usual &lt;code&gt;http/request&lt;/code&gt; was used. So things looked good: within the body of &lt;code&gt;http/with-additional-middleware&lt;/code&gt;, headers should be lower-cased because &lt;code&gt;request-fn&lt;/code&gt; is &lt;code&gt;http/request&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Or is it?&lt;/p&gt;&lt;p&gt;Let me show you how &lt;code&gt;with-additional-middleware&lt;/code&gt; is implemented. It expands to another macro, &lt;code&gt;with-middleware&lt;/code&gt;, which is defined as follows (docstring redacted):&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defmacro&lt;/span&gt; &lt;span class="hljs-title"&gt;with-middleware&lt;/span&gt;
  [middleware &amp;amp; body]
  `(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [m# ~middleware]
     (&lt;span class="hljs-name"&gt;binding&lt;/span&gt; [*current-middleware* m#
               clj-http.client/request (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;reduce&lt;/span&gt;&lt;/span&gt; #(%&lt;span class="hljs-number"&gt;2&lt;/span&gt; %&lt;span class="hljs-number"&gt;1&lt;/span&gt;)
                                               clj-http.core/request
                                               m#)]
       ~@body)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s right: &lt;code&gt;with-middleware&lt;/code&gt; works by dynamically rebinding &lt;code&gt;http/request&lt;/code&gt;. Which means the &lt;code&gt;request-fn&lt;/code&gt; I was calling is not actually the wrapped version, but the one captured by the outer &lt;code&gt;let&lt;/code&gt;, the one that wasn’t rebound, the one without the additional middleware!&lt;/p&gt;&lt;p&gt;After this light-bulb moment, I moved &lt;code&gt;with-additional-middleware&lt;/code&gt; outside of the &lt;code&gt;let&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;http/with-additional-middleware&lt;/span&gt; [http/wrap-lower-case-headers]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [request-fn (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;or&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-symbol"&gt;:request-fn&lt;/span&gt; options)
                       http/request)]
    (&lt;span class="hljs-name"&gt;request-fn&lt;/span&gt; req
                success-fn
                error-fn)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And, sure enough, it worked.&lt;/p&gt;&lt;h2 id="part-two:-the-tests-are-screaming-loud"&gt;Part Two: The tests are screaming loud&lt;/h2&gt;&lt;p&gt;Is it the end of the story? I’m guessing you’re thinking it is. I thought so too. But I wanted to add one last thing: a regression test, so I’d never run into the same problem in the future.&lt;/p&gt;&lt;p&gt;I whipped up a test in which one ISO-8859-2-encoded page was scraped, and a check for the correct string was made. I ran it against the fixed code. It was green. I ran it against the previous, broken version…&lt;/p&gt;&lt;p&gt;It was &lt;em&gt;green&lt;/em&gt;, too.&lt;/p&gt;&lt;p&gt;At this point, I knew I had to get to the bottom of this.&lt;/p&gt;&lt;p&gt;Back to experimenting. After a while, I found out that extracting encoding from a freshly-downloaded page actually worked fine! It only failed when parsing headers fetched from a cache. But the map was the same in both cases! In both cases, the code was effectively doing&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;get&lt;/span&gt;&lt;/span&gt; {&lt;span class="hljs-string"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;text/html; charset=ISO-8859-2&amp;quot;&lt;/span&gt;}
     &lt;span class="hljs-string"&gt;&amp;quot;content-type&amp;quot;&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This lookup &lt;em&gt;shouldn’t&lt;/em&gt; succeed: in map lookup, string comparison is case-sensitive. And yet, for freshly-downloaded headers, it &lt;em&gt;did&lt;/em&gt; succeed!&lt;/p&gt;&lt;p&gt;I checked the &lt;code&gt;type&lt;/code&gt; of both maps. One of them was a &lt;code&gt;clojure.lang.PersistentHashMap&lt;/code&gt;, as expected. The other one was not. It was actually a &lt;code&gt;clj_http.headers.HeaderMap&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;I’ll let the comment of that one speak for itself:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;a map implementation that stores both the original (or canonical) key and value for each key/value pair, but performs lookups and other operations using the normalized – this allows a value to be looked up by many similar keys, and not just the exact precise key it was originally stored with.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;And so it turned out that the library authors have actually foreseen the need for looking up headers irrespective of case, and provided a helpful means for that. The whole lowercasing business was not needed, after all!&lt;/p&gt;&lt;p&gt;I stripped out the &lt;code&gt;with-additional-middleware&lt;/code&gt; altogether, added some code elsewhere to ensure that the header map is a &lt;code&gt;HeaderMap&lt;/code&gt; regardless of whether it comes from the cache or not, and they lived happily ever after.&lt;/p&gt;&lt;h2 id="epilogue"&gt;Epilogue&lt;/h2&gt;&lt;p&gt;Moral of the story? It’s twofold.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Dynamic rebinding can be dangerous. Having a public API that is implemented in terms of dynamic rebinding, even more so. I’d prefer if clj-http just allowed the custom middleware to be explicitly specified as an argument, thusly:&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;http/request&lt;/span&gt; req
              &lt;span class="hljs-symbol"&gt;:additional-middleware&lt;/span&gt; [http/wrap-lower-case-headers])
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Know your dependencies. If you have a problem that might be generically addressed by the library you’re using, look deeper. It might be there already.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Thanks to &lt;a href="https://www.3jane.co.uk"&gt;3Jane&lt;/a&gt; for proofreading this article.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2020-01-03:post:word-champions</id>
    <title>Word Champions</title>
    <link href="http://blog.danieljanus.pl/word-champions/"/>
    <updated>2020-01-03T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;This story begins on August 9, 2017, when a friend messaged me on Facebook: “Hey, I’m going to be on a TV talent show this weekend. They’ll be giving me this kind of problems. Any ideas how to prepare?”&lt;/p&gt;&lt;p&gt;He attached a link to this video:&lt;/p&gt;&lt;iframe width="100%" height="500" src="https://www.youtube.com/embed/34AcKyYdNBo" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Now, we’re both avid Scrabble players, so we explored some ideas about extracting helpful data out of the &lt;a href="http://www.pfs.org.pl/english.php"&gt;Official Polish Scrabble Player’s Dictionary&lt;/a&gt;. I launched a Clojure REPL and wrote some throwaway code to generate sample training problems for Krzysztof. The code used a brute-force algorithm, so it was dog slow, but it was a start. It was Wednesday.&lt;/p&gt;&lt;p&gt;I woke up next morning with the problem still in my head. Clearly, I had found myself in a &lt;a href="https://xkcd.com/356/"&gt;nerd sniping&lt;/a&gt; situation.&lt;/p&gt;&lt;img src="https://imgs.xkcd.com/comics/nerd_sniping.png"&gt;
&lt;p&gt;There was only one obvious way out—to write a full-blown training app so that Krzysztof could practice as if he were in the studio. The clock was ticking: we had two days left.&lt;/p&gt;&lt;p&gt;After work, I started a fresh &lt;a href="https://github.com/day8/re-frame/"&gt;re-frame&lt;/a&gt; project. (I was a recent re-frame convert those days, so I wanted to see how well it could cope with the task at hand.) Late that night, or rather early next morning, the prototype was ready.&lt;/p&gt;&lt;p&gt;It had very messy code. It only worked on Chrome. It failed miserably on mobile. It took ages to load. It had native JS dependencies, notably &lt;a href="https://material-ui.com/"&gt;Material-UI&lt;/a&gt; and &lt;a href="https://react-dnd.github.io/react-dnd/about"&gt;react-dnd&lt;/a&gt;, and for some reason it would not compile with ClojureScript’s advanced optimization turned on; so it weighed in at more than 6 MB, slurping in more than 300 JS files on load.&lt;/p&gt;&lt;p&gt;But it worked.&lt;/p&gt;&lt;p&gt;Krzysztof didn’t win his episode against the other contestants, ending up third, but he completed his challenge successfully. It took him 3 minutes and 42 seconds, out of 5 minutes allotted. The episode aired on 24 October.&lt;/p&gt;&lt;iframe width="100%" height="500" src="https://www.youtube.com/embed/7ec6j31nlAk" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Krzysztof said that the problem he ended up solving on the show was way easier than the ones generated by the app: had they been more difficult, the wow factor might have been higher.&lt;/p&gt;&lt;p&gt;Several months later, we met at a Scrabble tournament, and I received a present. I wish I had photographed that bottle of wine, so I could show it here, but I hadn’t.&lt;/p&gt;&lt;p&gt;Meanwhile, the code remained messy and low-priority. But I kept returning to it when I felt like it, fixing up things one at a time. I’ve added difficulty levels, so you can have only one diagram, or three. I’ve made it work on Firefox. I’ve done a major rewrite, restructuring the code in a sane way and removing the JS dependencies other than React. I’ve made advanced compilation work, getting the JS down to 400K. I’ve made it work on mobile devices. I’ve written a puzzle generator in C, which ended up several orders of magnitude faster than the prototype Clojure version (it’s still brute-force, but uses some dirty C tricks to speed things up; I hope to rewrite it in Rust someday).&lt;/p&gt;&lt;p&gt;And now, 2½ years later, I’ve added an English version, with an accompanying set of puzzles (generated from a wordlist taken from &lt;a href="https://github.com/first20hours/google-10000-english"&gt;this repo&lt;/a&gt;), for the English-speaking world to enjoy.&lt;/p&gt;&lt;p&gt;&lt;a href="http://danieljanus.pl/wladcyslow/"&gt;Play Word Champions now!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The code is &lt;a href="https://github.com/nathell/wordchampions"&gt;on GitHub&lt;/a&gt; if you’d like to check it out or try hacking on it. It’s small, less than 1KLOC in total, so I think it can be a learning tool for re-frame or ClojureScript.&lt;/p&gt;&lt;p&gt;(This game as featured on the TV shows is called Gridlock. The name “Word Champions” was inspired by the title of Krzysztof’s video on YouTube, literally meaning “Lord of the Words”. There is no pun in the Polish title.)&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2019-02-05:post:clj-tvision</id>
    <title>Re-framing text-mode apps</title>
    <link href="http://blog.danieljanus.pl/clj-tvision/"/>
    <updated>2019-02-05T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;“But, you know, many explorers liked to go to places that are unusual. And, it’s only for the fun of it.” – Richard P. Feynman&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;A couple of nights ago, I hacked together a small Clojure program.&lt;/p&gt;&lt;p&gt;All it does is displays a terminal window with a red rectangle in it. You can use your cursor keys to move it around the window, and space bar to change its colour. It’s fun, but it doesn’t sound very useful, does it?&lt;/p&gt;&lt;p&gt;In this post, I’ll try to convince you that there’s more to this little toy than might at first sight appear. You may want to check out &lt;a href="https://github.com/nathell/clj-tvision"&gt;the repo&lt;/a&gt; as you go along.&lt;/p&gt;&lt;h2 id="in-which-an-unexpected-appearance-is-made"&gt;In which an unexpected appearance is made&lt;/h2&gt;&lt;p&gt;(I’ve always envied &lt;a href="https://technomancy.us"&gt;Phil Hagelberg&lt;/a&gt; this kind of headlines.)&lt;/p&gt;&lt;p&gt;As you might have guessed from this article’s title, clj-tvision (a working name for the program) is a &lt;a href="https://github.com/Day8/re-frame"&gt;re-frame&lt;/a&gt; app.&lt;/p&gt;&lt;p&gt;For those of you who haven’t heard of re-frame, a word of explanation: it’s a ClojureScripty way of writing React apps, with Redux-like management of application state. If you do know re-frame (shameless plug: we at &lt;a href="https://works-hub.com"&gt;WorksHub&lt;/a&gt; do, and use it a lot: it powers the site you’re looking at right now!), you’ll instantly find yourself at home. However, a few moments later, a thought might dawn upon you, and you might start to feel a little uneasy…&lt;/p&gt;&lt;p&gt;Because I’ve mentioned React and ClojureScript, and yet I’d said earlier that we’re talking a text-mode application here. And I’ve mentioned that it’s written in Clojure. It is, in fact, not using React at all, and it has nothing to do whatsoever with ClojureScript, JavaScript, or the browser.&lt;/p&gt;&lt;p&gt;How is that even possible?&lt;/p&gt;&lt;p&gt;Here’s the catch: re-frame is implemented in &lt;code&gt;.cljc&lt;/code&gt; files. So while it’s mostly used in the ClojureScript frontend, it &lt;em&gt;can&lt;/em&gt; be used from Clojure. You may know this if you’re testing your events or subscriptions on the JVM.&lt;/p&gt;&lt;p&gt;While it’s mostly – if not hitherto exclusively – used for just that, I wanted to explore whether it could be used to manage state in an actual, non-web app. Text-mode is a great playground for this kind of exploration. Rather than picking a GUI toolkit and concern myself with its intricacies, I chose to just put things on a rectangular sheet of text characters.&lt;/p&gt;&lt;p&gt;(But if you are interested in pursuing a React-ish approach for GUIs, check out what Bodil Stokke’s been doing in &lt;a href="https://github.com/bodil/vgtk"&gt;vgtk&lt;/a&gt;.)&lt;/p&gt;&lt;h2 id="living-without-the-dom"&gt;Living without the DOM&lt;/h2&gt;&lt;p&gt;The building blocks of a re-frame app are subscriptions, events, and views. While the first two work in Clojureland pretty much the same way they do in the browser (although there are differences, of which more anon), views are a different beast.&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/Day8/re-frame/blob/master/docs/SubscriptionFlow.md"&gt;re-frame’s documentation&lt;/a&gt; says that views are “data in, Hiccup out. Hiccup is ClojureScript data structures which represent DOM.” But outside of the browser realm, there’s no DOM. So let’s rephrase that more generally: re-frame views should produce &lt;em&gt;data structures which declaratively describe the component’s appearance to the user&lt;/em&gt;. In web apps, those structures correspond to the DOM. What they will look like outside is up to us. We’ll be growing our own DOM-like model, piecemeal, as needs arise.&lt;/p&gt;&lt;p&gt;For clj-tvision, I’ve opted for a very simple thing. Let’s start with a concrete example. Here’s a view:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;view&lt;/span&gt; []
  [{&lt;span class="hljs-symbol"&gt;:type&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:rectangle&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:x1&lt;/span&gt; &lt;span class="hljs-number"&gt;10&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:y1&lt;/span&gt; &lt;span class="hljs-number"&gt;5&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:x2&lt;/span&gt; &lt;span class="hljs-number"&gt;20&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:y2&lt;/span&gt; &lt;span class="hljs-number"&gt;10&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:color&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:red&lt;/span&gt;}])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unlike in the DOM, in this model the UI state isn’t a tree. It’s a flat sequence of maps that each represent individual “primitive elements”. We could come up with a fancy buzzword-compliant name and call it Component List Model, or CLiM for short, in homage to &lt;a href="https://en.wikipedia.org/wiki/Common_Lisp_Interface_Manager"&gt;the venerable GUI toolkit&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Like normal re-frame views, CLiM views can include subviews. An example follows:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;square&lt;/span&gt; [left top size color]
  [{&lt;span class="hljs-symbol"&gt;:type&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:rectangle&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
    &lt;span class="hljs-symbol"&gt;:x1&lt;/span&gt; left&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
    &lt;span class="hljs-symbol"&gt;:y1&lt;/span&gt; top&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
    &lt;span class="hljs-symbol"&gt;:x2&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; left size &lt;span class="hljs-number"&gt;-1&lt;/span&gt;)&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
    &lt;span class="hljs-symbol"&gt;:y2&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; top size &lt;span class="hljs-number"&gt;-1&lt;/span&gt;)&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt;
    &lt;span class="hljs-symbol"&gt;:color&lt;/span&gt; color}])

(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;view&lt;/span&gt; []
  [[square &lt;span class="hljs-number"&gt;1&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt; &lt;span class="hljs-number"&gt;5&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:red&lt;/span&gt;]
   [square &lt;span class="hljs-number"&gt;9&lt;/span&gt; &lt;span class="hljs-number"&gt;9&lt;/span&gt; &lt;span class="hljs-number"&gt;5&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:blue&lt;/span&gt;]])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;How to render a view? Simple. First, flatten the list, performing funcalls on subviews so that you get a sequence containing only primitives. Then, draw each of them in order. (If there is an overlap, the trailers will obscure the leaders. Almost biblical.)&lt;/p&gt;&lt;p&gt;I’ve defined a multimethod, &lt;code&gt;render-primitive&lt;/code&gt;, dispatching on &lt;code&gt;:type&lt;/code&gt;. Its methods draw the corresponding primitive to a Lanterna screen.&lt;/p&gt;&lt;p&gt;Oh, didn’t I mention &lt;a href="https://github.com/mabe02/lanterna"&gt;Lanterna&lt;/a&gt;? It’s a Java library for terminals. Either real ones or emulated in Swing (easier to work with when you’re in a CIDER REPL). Plus, it sports virtual screens which can be blitted to a real terminal. This gives us a rough poor man’s equivalent of React’s VDOM. And it has a &lt;a href="https://github.com/AvramRobert/clojure-lanterna"&gt;Clojure wrapper&lt;/a&gt;!&lt;/p&gt;&lt;h2 id="events-at-eventide"&gt;Events at eventide&lt;/h2&gt;&lt;p&gt;So now we know how to draw our UI. But an app isn’t made up of just drawing. It has a main loop: it listens to events, which cause the app state to change and the corresponding components to redraw.&lt;/p&gt;&lt;p&gt;re-frame does provide an event mechanism, but it doesn’t &lt;em&gt;define&lt;/em&gt; any events per se. So we need to ask ourselves: who calls &lt;em&gt;dispatch&lt;/em&gt;? How do events originate? How to write the main loop?&lt;/p&gt;&lt;p&gt;clj-tvision is a proof-of-concept, so it doesn’t concern itself with mouse support. There’s only one way a user can interact with the app: via the keyboard. So keystrokes will be the only “source events”, as it were, for the app; and so writing the event loop should be simple. Sketching pseudocode:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;loop&lt;/span&gt;&lt;/span&gt; []
  (&lt;span class="hljs-name"&gt;render-app&lt;/span&gt;)
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [keystroke (&lt;span class="hljs-name"&gt;wait-for-key&lt;/span&gt;)] &lt;span class="hljs-comment"&gt;;; blocking!&lt;/span&gt;
    (&lt;span class="hljs-name"&gt;dispatch&lt;/span&gt; [&lt;span class="hljs-symbol"&gt;:key-pressed&lt;/span&gt; keystroke])
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;recur&lt;/span&gt;&lt;/span&gt;)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Simple as that, should work, right?&lt;/p&gt;&lt;p&gt;Wrong.&lt;/p&gt;&lt;p&gt;If you actually try that, it’ll &lt;em&gt;somewhat&lt;/em&gt; work. Hit right arrow to move the rectangle, nothing happens! Hit right arrow again, it moves. Hit left, it moves right. Hit right, it moves left. Not what you want.&lt;/p&gt;&lt;p&gt;You see, there’s a complication stemming from the fact that re-frame’s events are asynchronous by default. (Hence the &lt;code&gt;dispatch&lt;/code&gt; vs. &lt;code&gt;dispatch-sync&lt;/code&gt; dichotomy.) They don’t get dispatched immediately; rather, re-frame places them on a queue and processes them asynchronously, so that they don’t hog the browser. The Clojure version of re-frame handles that using a single-threaded executor with a dedicated thread.&lt;/p&gt;&lt;p&gt;We &lt;em&gt;almost&lt;/em&gt; could use &lt;code&gt;dispatch-sync&lt;/code&gt; everywhere, but for re-frame that’s a no-no: once within a &lt;code&gt;dispatch-sync&lt;/code&gt; handler, you cannot dispatch other events. If you try anyway, re-frame will detect it and politely point its dragon-scaly head at you, explaining it doesn’t like it. (It is a benevolent dragon, you know.)&lt;/p&gt;&lt;p&gt;So we need to hook into that “next-tick” machinery of re-frame’s somehow. There are probably better ways of doing this, but I opted to blatantly redefine &lt;code&gt;re-frame.interop/next-tick&lt;/code&gt; to tell the main loop: “hey, events have been handled and we have a new state, dispatch an event so we can redraw.” This is one of the rare cases where monkey-patching third-party code with &lt;code&gt;alter-var-root&lt;/code&gt; saves you the hassle of forking that entire codebase.&lt;/p&gt;&lt;p&gt;So now we have &lt;em&gt;two&lt;/em&gt; sources of events: keystrokes, and &lt;code&gt;next-tick&lt;/code&gt;. To multiplex them, I’ve whipped up a channel with core.async. Feels hacky, but allows to add mouse support in the future. Or time-based events that will be fired periodically every so often.&lt;/p&gt;&lt;p&gt;For completeness, I should also add that Clojure-side re-frame doesn’t have the luxury of having reactive atoms provided by Reagent. Its ratoms are ordinary Clojure atoms. Unlike in ClojureScript, any time the app state changes, &lt;em&gt;every&lt;/em&gt; subscription in the signal graph will be recomputed. It may well be possible to port Reagent’s ratoms to Clojure, but it is a far more advanced exercise. For simple apps, what re-frame provides on its own might just be enough.&lt;/p&gt;&lt;p&gt;And with that final bit, we can swipe all that hackitude under the carpet… or, should I say, tuck it into an internal ns that hopefully no-one will ever look into. And we’re left with shiny, declarative, re-framey, beautiful UI code on the surface. &lt;a href="https://github.com/nathell/clj-tvision/blob/master/src/tvision/core.clj"&gt;Just look&lt;/a&gt;.&lt;/p&gt;&lt;h2 id="closing-thoughts"&gt;Closing thoughts&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;“Within C++, there is a much smaller and cleaner language struggling to get out.” – Bjarne Stroustrup&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;If you’ve ever encountered legacy C++ code, this will ring true. Come to think of it, Stroustrup’s words are true of every system that has grown organically over its lifetime, with features being added to it but hardly ever removed.&lt;/p&gt;&lt;p&gt;And modern webapps may well be the epitome of that kind of system. We now have desktop apps that are fully self-contained on a single machine, yet use an overwhelmingly complex and vast machinery grown out of a simple system originally devised to &lt;a href="http://info.cern.ch/hypertext/WWW/TheProject.html"&gt;view static documents over the Internet&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;For all that complexity, we continue to use it. Partly owing to its ubiquity, partly for convenience. In my experience, the abstractions provided by re-frame allow you to wrap your head around large apps and reason about them much more easily than, say, object-oriented approaches. It just feels right. Conversely, writing an app in, say, GTK+ would now feel like a setback by some twenty years.&lt;/p&gt;&lt;p&gt;So this toy, this movable rectangle on a black screen, is not so much an app as it is a philosophical exercise. It is what my typing fingers produced while I pondered, weak and weary: “can we throw away most of that cruft, while still enjoying the abstractions that make life so much easier?”&lt;/p&gt;&lt;p&gt;Can we?&lt;/p&gt;&lt;p&gt;This post was originally published on &lt;a href="https://functional.works-hub.com/learn/re-framing-text-mode-apps-fd5cf"&gt;Functional Works&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2014-05-20:post:you-already-use-lisp-syntax</id>
    <title>You already use Lisp syntax</title>
    <link href="http://blog.danieljanus.pl/you-already-use-lisp-syntax/"/>
    <updated>2014-05-20T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;&lt;strong&gt;Unix Developer:&lt;/strong&gt; I’m not going to touch Lisp. It’s horrible!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Why so?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; The syntax! This illegible prefix-RPN syntax that nobody else uses. And just look at all these parens!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Well, many people find it perfectly legible, although most agree that it takes some time to get accustomed to. But I think you’re mistaken. Lots of people are using Lisp syntax on a daily basis…&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; I happen to know no one doing this.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; …without actually realizing this. In fact, I think &lt;em&gt;you&lt;/em&gt; yourself are using it.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; Wait, &lt;em&gt;what&lt;/em&gt;?!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; And the particular variant of Lisp syntax you’re using is called Bourne shell.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; Now I don’t understand. What on earth does the shell have to do with Lisp?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Just look: in the shell, you put the name of the program first, followed by the arguments, separated by spaces. In Lisp it’s exactly the same, except that you put an opening paren at the beginning and a closing paren at the end.&lt;/p&gt;&lt;p&gt;Shell: &lt;code&gt;run-something arg1 arg2 arg3&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Lisp: &lt;code&gt;(run-something arg1 arg2 arg3)&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; I still don’t get the analogy.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Then you need a mechanism for expression composition — putting the output of one expression as an input to another. In Lisp, you just nest the lists. And in the shell?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; Backticks.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; That’s right. Or &lt;code&gt;$()&lt;/code&gt;, which has the advantage of being more easily nestable. Let’s try arithmetic. How do you do arithmetic in the shell?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; &lt;code&gt;expr&lt;/code&gt;. Or the Bash builtin &lt;code&gt;let&lt;/code&gt;. For example,&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs bash"&gt;$ &lt;span class="hljs-built_in"&gt;let&lt;/span&gt; x=&lt;span class="hljs-string"&gt;&amp;#x27;2*((10+4)/7)&amp;#x27;&lt;/span&gt;; &lt;span class="hljs-built_in"&gt;echo&lt;/span&gt; &lt;span class="hljs-variable"&gt;$x&lt;/span&gt;
4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Now wouldn’t it be in line with the spirit of Unix — to have programs do just one thing — if we had one program to do addition, and another to do subtraction, and yet another to do multiplication and division?&lt;/p&gt;&lt;p&gt;It’s trivial to write it in C:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs c"&gt;&lt;span class="hljs-meta"&gt;#&lt;span class="hljs-keyword"&gt;include&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="hljs-meta"&gt;#&lt;span class="hljs-keyword"&gt;include&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="hljs-meta"&gt;#&lt;span class="hljs-keyword"&gt;include&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class="hljs-type"&gt;int&lt;/span&gt; &lt;span class="hljs-title function_"&gt;main&lt;/span&gt;&lt;span class="hljs-params"&gt;(&lt;span class="hljs-type"&gt;int&lt;/span&gt; argc, &lt;span class="hljs-type"&gt;char&lt;/span&gt; **argv)&lt;/span&gt; {
  &lt;span class="hljs-type"&gt;int&lt;/span&gt; mode = &lt;span class="hljs-number"&gt;-1&lt;/span&gt;, cnt = argc - &lt;span class="hljs-number"&gt;1&lt;/span&gt;, val, i;
  &lt;span class="hljs-type"&gt;char&lt;/span&gt; **args = argv + &lt;span class="hljs-number"&gt;1&lt;/span&gt;;
  &lt;span class="hljs-keyword"&gt;switch&lt;/span&gt; (argv[&lt;span class="hljs-number"&gt;0&lt;/span&gt;][&lt;span class="hljs-built_in"&gt;strlen&lt;/span&gt;(argv[&lt;span class="hljs-number"&gt;0&lt;/span&gt;]) - &lt;span class="hljs-number"&gt;1&lt;/span&gt;]) {
    &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#x27;+&amp;#x27;&lt;/span&gt;: mode = &lt;span class="hljs-number"&gt;0&lt;/span&gt;; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
    &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#x27;-&amp;#x27;&lt;/span&gt;: mode = &lt;span class="hljs-number"&gt;1&lt;/span&gt;; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
    &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#x27;x&amp;#x27;&lt;/span&gt;: mode = &lt;span class="hljs-number"&gt;2&lt;/span&gt;; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
    &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#x27;d&amp;#x27;&lt;/span&gt;: mode = &lt;span class="hljs-number"&gt;3&lt;/span&gt;; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
  }
  &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (mode == &lt;span class="hljs-number"&gt;-1&lt;/span&gt;) {
    &lt;span class="hljs-built_in"&gt;fprintf&lt;/span&gt;(&lt;span class="hljs-built_in"&gt;stderr&lt;/span&gt;, &lt;span class="hljs-string"&gt;&amp;quot;invalid math operation\n&amp;quot;&lt;/span&gt;);
    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;;
  }
  &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; ((mode == &lt;span class="hljs-number"&gt;1&lt;/span&gt; || mode == &lt;span class="hljs-number"&gt;3&lt;/span&gt;) &amp;amp;&amp;amp; !cnt) {
    &lt;span class="hljs-built_in"&gt;fprintf&lt;/span&gt;(&lt;span class="hljs-built_in"&gt;stderr&lt;/span&gt;, &lt;span class="hljs-string"&gt;&amp;quot;%s requires at least one arg\n&amp;quot;&lt;/span&gt;, argv[&lt;span class="hljs-number"&gt;0&lt;/span&gt;]);
    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;;
  }
  &lt;span class="hljs-keyword"&gt;switch&lt;/span&gt; (mode) {
    &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;: val = &lt;span class="hljs-number"&gt;0&lt;/span&gt;; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
    &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-number"&gt;2&lt;/span&gt;: val = &lt;span class="hljs-number"&gt;1&lt;/span&gt;; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
    &lt;span class="hljs-keyword"&gt;default&lt;/span&gt;: val = atoi(*args++); cnt--; &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
  }
  &lt;span class="hljs-keyword"&gt;while&lt;/span&gt; (cnt--) {
    &lt;span class="hljs-keyword"&gt;switch&lt;/span&gt; (mode) {
      &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;: val += atoi(*args++); &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
      &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;: val -= atoi(*args++); &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
      &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-number"&gt;2&lt;/span&gt;: val *= atoi(*args++); &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
      &lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-number"&gt;3&lt;/span&gt;: val /= atoi(*args++); &lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
    }
  }
  &lt;span class="hljs-built_in"&gt;printf&lt;/span&gt;(&lt;span class="hljs-string"&gt;&amp;quot;%d\n&amp;quot;&lt;/span&gt;, val);
  &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This dispatches on the last character of its name, so it can be symlinked to &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt; (I picked unusual names for multiplication and division to make them legal and avoid escaping).&lt;/p&gt;&lt;p&gt;Now behold:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs bash"&gt;$ x 2 $(d $(+ 10 4) 7)
4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; Wow, this sure looks a lot like Lisp!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; And yet it’s the shell. Our two basic rules — program-name-first and &lt;code&gt;$()&lt;/code&gt;-for-composition — allowed us to explicitly specify the order of evaluation, so there was no need to do any fancy parsing beyond what the shell already provides.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UD:&lt;/strong&gt; So is the shell a Lisp?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Not really. The shell is &lt;a href="http://blog.codinghorror.com/new-programming-jargon/"&gt;stringly typed&lt;/a&gt;: a program takes textual parameters and produces textual output. To qualify as a Lisp, it would have to have a composite type: a list or a cons cell to build lists on top of. Then, you’d be able to represent code as this data structure, and write programs to transform code to other code.&lt;/p&gt;&lt;p&gt;But the Tao of Lisp lingers in the shell syntax.&lt;/p&gt;&lt;hr&gt;
&lt;p&gt;I know I’ve glossed over many details here, like the shell syntax for redirection, globbing, subprocesses, the fact that programs have standard input in addition to command-line arguments, pipes, etc. — all these make the analogy rather weak. But I think it’s an interesting way to teach Lisp syntax to people.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2013-05-26:post:lithium-revisited</id>
    <title>Lithium revisited: A 16-bit kernel (well, sort of) written in Clojure (well, sort of)</title>
    <link href="http://blog.danieljanus.pl/lithium-revisited/"/>
    <updated>2013-05-26T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;Remember &lt;a href="http://blog.danieljanus.pl/blog/2012/05/14/lithium/"&gt;Lithium&lt;/a&gt;? The x86 assembler written in Clojure, and a simple stripes effect written in it? Well, here’s another take on that effect:&lt;/p&gt;&lt;img src="/img/blog/stripes2.png"&gt;
&lt;p&gt;And here is the source code:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;do&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;init-graph&lt;/span&gt;)
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;loop&lt;/span&gt;&lt;/span&gt; [x &lt;span class="hljs-number"&gt;0&lt;/span&gt; y &lt;span class="hljs-number"&gt;0&lt;/span&gt;]
      (&lt;span class="hljs-name"&gt;put-pixel&lt;/span&gt; x y (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [z (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;mod&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;319&lt;/span&gt; x) y) &lt;span class="hljs-number"&gt;32&lt;/span&gt;)]
                       (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; z &lt;span class="hljs-number"&gt;16&lt;/span&gt;) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;16&lt;/span&gt; z) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;16&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;31&lt;/span&gt; z)))))
      (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; y &lt;span class="hljs-number"&gt;200&lt;/span&gt;)
        &lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
        (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; x &lt;span class="hljs-number"&gt;319&lt;/span&gt;)
          (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;recur&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;inc&lt;/span&gt;&lt;/span&gt; y))
          (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;recur&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;inc&lt;/span&gt;&lt;/span&gt; x) y)))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I’ve implemented this several months ago, pushed it to Github and development has pretty much stalled since then. And after seeing &lt;a href="https://news.ycombinator.com/item?id=5771276"&gt;this recent post&lt;/a&gt; on HN today, I’ve decided to give Lithium a little more publicity, in the hope that it will provide a boost of motivation to me. Because what we have here is pretty similar to Rustboot: it’s a 16-bit kernel written in Clojure.&lt;/p&gt;&lt;p&gt;Well, sort of.&lt;/p&gt;&lt;p&gt;After writing a basic assembler capable of building bare binaries of simple x86 real-mode programs, I’ve decided to make it a building block of a larger entity. So I’ve embarked on a project to implement a compiler for a toy Lisp-like language following the paper &lt;a href="http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf"&gt;“An Incremental Approach to Compiler Construction”&lt;/a&gt;, doing it in Clojure and making the implemented language similar to Clojure rather than to Scheme.&lt;/p&gt;&lt;p&gt;(Whether it actually can be called Clojure is debatable. It’s unclear what the definition of Clojure the language is. Is running on JVM a part of what makes Clojure Clojure? Or running on any host platform? Is ClojureScript Clojure? What about ClojureCLR, or clojure-py?)&lt;/p&gt;&lt;p&gt;So far I’ve only gotten to step 7 of 24 or so, but that’s already enough to have a working &lt;code&gt;loop/recur&lt;/code&gt; implementation, and it was trivial to throw in some graphical mode 13h primitives to be able to implement this effect.&lt;/p&gt;&lt;p&gt;By default I’m running Lithium programs as DOS .COM binaries under DOSBox, but technically, the code doesn’t depend on DOS in any way (it doesn’t ever invoke interrupt 21h) and so it can be combined with a simple bootloader into a kernel runnable on the bare metal.&lt;/p&gt;&lt;p&gt;The obligatory HOWTO on reproducing the effect: install DOSBox and Leiningen, checkout [the code][3], launch a REPL with &lt;code&gt;lein repl&lt;/code&gt;, execute the following forms, and enjoy the slowness with which individual pixels are painted:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;require&lt;/span&gt; &amp;#x27;lithium.compiler)
(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;in-ns&lt;/span&gt;&lt;/span&gt; &amp;#x27;lithium.compiler)
(&lt;span class="hljs-name"&gt;run!&lt;/span&gt; (&lt;span class="hljs-name"&gt;compile-program&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;/path/to/lithium/examples/stripes-grey.clj&amp;quot;&lt;/span&gt;))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2012-05-14:post:lithium</id>
    <title>Lithium: an x86 assembler for Clojure</title>
    <link href="http://blog.danieljanus.pl/lithium/"/>
    <updated>2012-05-14T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;Ah, the golden days of childhood’s hackage. Don’t you have fond memories of them?&lt;/p&gt;&lt;p&gt;I got my first PC when I was 10. It was a 486DX2/66 with 4 megs of RAM and a 170 meg HDD; it ran DOS and had lots of things installed on it, notably Turbo Pascal 6. I hacked a lot in it. These were pre-internet days when knowledge was hard to come by, especially for someone living in a &lt;a href="http://en.wikipedia.org/wiki/W%C4%85chock"&gt;small town in Poland&lt;/a&gt;; my main sources were the software I had (TP’s online help was of excellent quality), a couple of books, and a &lt;a href="http://www.cpcwiki.eu/index.php/Bajtek"&gt;popular computing magazine&lt;/a&gt; that published articles on programming. From the latter, I learned how to program the VGA: how to enter mode 13h, draw pixels on screen, wait for vertical retrace, manipulate the palette and how to combine these things into neat effects. One of the very first thing I discovered was when you plot every pixel using sum of its coordinates modulo 40 as color, you get a nice-looking diagonal stripes effect. Because of the initially incomprehensible inline assembly snippets appearing all over the place, I eventually learned x86 assembly, too.&lt;/p&gt;&lt;img src="/img/blog/stripes.png"&gt;
&lt;p&gt;Back to 2012: I’ve long been wanting to hack on something just for pure fun, a side pet project. Writing code for the bare metal is fun because it’s just about as close as you can get to wielding the ultimate power. And yet, since Clojure is so much fun too, I wanted the project to have something to do with Clojure.&lt;/p&gt;&lt;p&gt;So here’s &lt;a href="http://github.com/nathell/lithium"&gt;Lithium&lt;/a&gt;, an x86 16-bit assembler written in pure Clojure and capable of assembling a binary version of the stripes effect.&lt;/p&gt;&lt;p&gt;To try it, clone the git repo to your Linux or OS X machine, install DOSBox, launch a REPL with Leiningen, change to the &lt;code&gt;lithium&lt;/code&gt; namespace and say:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;run!&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;/home/you/lithium/src/stripes.li.clj&amp;quot;&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="faq"&gt;FAQ&lt;/h3&gt;&lt;p&gt;(Well, this is not really a FAQ since nobody actually asked me any questions about Lithium yet. This is more in anticipation of questions that may arise.)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What’s the importance of this?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.physics.ohio-state.edu/~kilcup/262/feynman.html"&gt;None whatsoever&lt;/a&gt;. It’s just for fun.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;How complete is it?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Very incomplete. To even call it pre-pre-alpha would be an exaggeration. It’s currently little more than pure minimum required to assemble &lt;code&gt;stripes.li.clj&lt;/code&gt;. Output format wise, it only produces bare binaries (similar to DOS .COMs), and that’s unlikely to change anytime soon.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Do you intend to continue developing it?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Absolutely. I will try to make it more complete, add 32- and possibly 64-bit modes, see how to add a macro system (since the input is s-expressions, it should be easy to produce Clojure macros to write assembly), write something nontrivial in it, and see how it can be used as a backend for some higher-level language compiler (I’m not sure yet which language that will turn out to be).&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2012-04-25:post:how-to-call-a-private-function-in-clojure</id>
    <title>How to call a private function in Clojure</title>
    <link href="http://blog.danieljanus.pl/how-to-call-a-private-function-in-clojure/"/>
    <updated>2012-04-25T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; Don’t do it. If you really have to, use &lt;code&gt;(#'other-library/private-function args)&lt;/code&gt;.&lt;/p&gt;&lt;hr&gt;
&lt;p&gt;A private function in Clojure is one that has been defined using the &lt;code&gt;defn-&lt;/code&gt; macro, or equivalently by setting the metadata key &lt;code&gt;:private&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; on the var that holds the function. It is normally not allowed in Clojure to call such functions from outside of the namespace where they have been defined. Trying to do so results in an &lt;code&gt;IllegalStateException&lt;/code&gt; stating that the var is not public.&lt;/p&gt;&lt;p&gt;It is possible to circumvent this and call the private function, but it is not recommended. That the author of the library decided to make a function private probably means that he considers it to be an implementation detail, subject to change at any time, and that you should not rely on it being there. If you think it would be useful to have this functionality available as part of the public API, your best bet is to contact the library author and consult the change, so that it may be included officially in a future version.&lt;/p&gt;&lt;p&gt;Contacting the author, however, is not always feasible: she may not be available or you might be in haste. In this case, several workarounds are available. The simplest is to use &lt;code&gt;(#'other-library/private-function args)&lt;/code&gt;, which works in Clojure 1.2.1 and 1.3.0 (it probably works in other versions of Clojure as well, but I haven’t checked that).&lt;/p&gt;&lt;p&gt;Why does this work? When the Clojure compiler encounters a form &lt;code&gt;(sym args)&lt;/code&gt;, it invokes &lt;code&gt;analyzeSeq&lt;/code&gt; on that form. If its first element is a symbol, it proceeds to analyze that symbol. One of the first operation in that analysis is checking if it names an inline function, by calling &lt;code&gt;isInline&lt;/code&gt;. That function looks into the metadata of the Var named by the symbol in question. If it’s not public, it &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.3.0/src/jvm/clojure/lang/Compiler.java#L6281"&gt;throws an exception&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;On the other hand, &lt;code&gt;#'&lt;/code&gt; is the reader macro for var. So our workaround is equivalent to &lt;code&gt;((var other-library/private-function) args)&lt;/code&gt;. In this case, the first element of the form is not a symbol, but a form that evaluates to a var. The compiler is not able to check for this so it does not insert a check for privateness. So the code compiles to calling a Var object.&lt;/p&gt;&lt;p&gt;Here’s the catch: Vars are callable, just like functions. They &lt;a href="https://github.com/clojure/clojure/blob/clojure-1.3.0/src/jvm/clojure/lang/Var.java#L18"&gt;implement &lt;code&gt;IFn&lt;/code&gt;&lt;/a&gt;. When a var is called, it delegates the call to the &lt;code&gt;IFn&lt;/code&gt; object it is holding. This has been recently &lt;a href="https://groups.google.com/d/msg/clojure/1Su9o_8JZ8g/uZL-n4uRSiUJ"&gt;discussed on the Clojure group&lt;/a&gt;. Since that delegation does not check for the var’s privateness either, the net effect is that we are able to call a private function this way.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2012-04-12:post:lifehacking-gumtree</id>
    <title>Lifehacking: How to get cheap home equipment using Clojure</title>
    <link href="http://blog.danieljanus.pl/lifehacking-gumtree/"/>
    <updated>2012-04-12T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;I’ve moved to London last September. Like many new Londoners, I have changed accommodation fairly quickly, being already after one removal and with another looming in a couple of months; my current flat was largely unfurnished when I moved in, so I had to buy some basic homeware. I didn’t want to invest much in it, since it’d be only for a few months. Luckily, it is not hard to do that cheaply: many people are moving out and getting rid of their stuff, so quite often you can search for the desired item on &lt;a href="http://www.gumtree.com/london"&gt;Gumtree&lt;/a&gt; and find there’s a cheap one a short bike ride away.&lt;/p&gt;&lt;p&gt;Except when there isn’t. In this case, it’s worthwhile to check again within a few days as new items are constantly being posted. Being lazy, I’ve decided to automate this. A few hours and a hundred lines of Clojure later, &lt;a href="https://github.com/nathell/gumtree-scraper"&gt;gumtree-scraper&lt;/a&gt; was born.&lt;/p&gt;&lt;p&gt;I’ve packaged it using &lt;code&gt;lein uberjar&lt;/code&gt; into a standalone jar, which, when run, produces a &lt;code&gt;gumtree.rss&lt;/code&gt; that is included in my Google Reader subscriptions. This way, whenever something I’m interested in appears, I get notified within an hour or so.&lt;/p&gt;&lt;p&gt;It’s driven by a Google spreadsheet. I’ve created a sheet that has three columns: item name, minimum price, maximum price; then I’ve made it available to anyone who knows the URL. This way I can edit it pretty much from everywhere without touching the script. Each time the script is run (by cron), it downloads that spreadsheet as a CSV that looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;hand blender,,5
bike rack,,15
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For each row the script queries Gumtree’s category “For Sale” within London given the price range, gets each result and transforms it to a RSS entry.&lt;/p&gt;&lt;p&gt;Gumtree has no API, so I’m using screenscraping to retrieve all the data. Because the structure of the pages is much simpler, I’m actually scraping the &lt;a href="http://m.gumtree.com/"&gt;mobile version&lt;/a&gt;; a technical twist here is that the mobile version is only served to actual browsers so I’m supplying a custom User-Agent, pretending to be Safari. For actual scraping, the code uses &lt;a href="https://github.com/cgrand/enlive"&gt;Enlive&lt;/a&gt;; it works out nicely.&lt;/p&gt;&lt;p&gt;About half of the code is RSS generation — mostly XML emitting. I’d use &lt;code&gt;clojure.xml/emit&lt;/code&gt; but it’s known to &lt;a href="http://clojure-log.n01se.net/date/2012-01-03.html#17:28a"&gt;produce malformed XML&lt;/a&gt; at times, so I include a variant that should work.&lt;/p&gt;&lt;p&gt;In case anyone wants to tries it out, be aware that the location and category are hardcoded in the search URL template; if you want, change the template line in &lt;code&gt;get-page&lt;/code&gt;. The controller spreadsheet URL is not, however, hardcoded; it’s built up using the &lt;code&gt;spreadsheet.key&lt;/code&gt; system property. Here’s the wrapper script I use that is actually run by cron:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs bash"&gt;&lt;span class="hljs-meta"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="hljs-keyword"&gt;if&lt;/span&gt; [ &lt;span class="hljs-string"&gt;&amp;quot;`ps ax | grep java | grep gumtree`&amp;quot;&lt;/span&gt; ]; &lt;span class="hljs-keyword"&gt;then&lt;/span&gt;
  &lt;span class="hljs-built_in"&gt;echo&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;already running, exiting&amp;quot;&lt;/span&gt;
  &lt;span class="hljs-built_in"&gt;exit&lt;/span&gt; 0
&lt;span class="hljs-keyword"&gt;fi&lt;/span&gt;
&lt;span class="hljs-built_in"&gt;cd&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;`dirname &lt;span class="hljs-variable"&gt;$0&lt;/span&gt;`&amp;quot;&lt;/span&gt;
java -Dspreadsheet.key=MY_SECRET_KEY -jar &lt;span class="hljs-variable"&gt;$HOME&lt;/span&gt;/gumtree/gumtree.jar
&lt;span class="hljs-built_in"&gt;cp&lt;/span&gt; &lt;span class="hljs-variable"&gt;$HOME&lt;/span&gt;/gumtree/gumtree.rss &lt;span class="hljs-variable"&gt;$HOME&lt;/span&gt;/public_html
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let me remove that entry for a blender — I’ve bought one yesterday for £4…&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2011-12-09:post:combining-virtual-sequences</id>
    <title>Combining virtual sequences&lt;br&gt;or, Sequential Fun with Macros&lt;br&gt;or, How to Implement Clojure-Like Pseudo-Sequences with Poor Man’s Laziness in a Predominantly Imperative Language</title>
    <link href="http://blog.danieljanus.pl/combining-virtual-sequences/"/>
    <updated>2011-12-09T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;h2 id="sequences-and-iteration"&gt;Sequences and iteration&lt;/h2&gt;&lt;p&gt;There are a number of motivations for this post. One stems from my extensive exposure to Clojure over the past few years: this was, and still is, my primary programming language for everyday work. Soon, I realized that much of the power of Clojure comes from a &lt;em&gt;sequence&lt;/em&gt; abstraction being one of its central concepts, and a standard library that contains many sequence-manipulating functions. It turns out that by combining them it is possible to solve a wide range of problems in a concise, high-level way. In contrast, it pays to think in terms of whole sequences, rather than individual elements.&lt;/p&gt;&lt;p&gt;Another motivation comes from a classical piece of functional programming humour, [The Evolution of a Haskell Programmer][1]. If you don’t know it, go check it out: it consists of several Haskell implementations of factorial, starting out from a straightforward recursive definition, passing through absolutely hilarious versions involving category-theoretical concepts, and finally arriving at this simple version that is considered most idiomatic:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs haskell"&gt;&lt;span class="hljs-title"&gt;fac&lt;/span&gt; n = product [&lt;span class="hljs-number"&gt;1&lt;/span&gt;..n]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is very Clojure-like in that it involves a sequence (a list comprehension). In Clojure, this could be implemented as&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;fac&lt;/span&gt; [n]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;reduce&lt;/span&gt;&lt;/span&gt; * &lt;span class="hljs-number"&gt;1&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;range&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;inc&lt;/span&gt;&lt;/span&gt; n)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, I thought to myself, how would I write factorial in an imperative language? Say, Pascal?&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs pascal"&gt;&lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;function&lt;/span&gt; &lt;span class="hljs-title"&gt;fac&lt;/span&gt;&lt;span class="hljs-params"&gt;(n : integer)&lt;/span&gt; :&lt;/span&gt; integer;
&lt;span class="hljs-keyword"&gt;var&lt;/span&gt;
  i, res : integer;
&lt;span class="hljs-keyword"&gt;begin&lt;/span&gt;
  res := &lt;span class="hljs-number"&gt;1&lt;/span&gt;;
  &lt;span class="hljs-keyword"&gt;for&lt;/span&gt; i := &lt;span class="hljs-number"&gt;1&lt;/span&gt; &lt;span class="hljs-keyword"&gt;to&lt;/span&gt; n &lt;span class="hljs-keyword"&gt;do&lt;/span&gt;
    res := res * i;
  fac := res;
&lt;span class="hljs-keyword"&gt;end&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is very different from the functional version that works with sequences. It is much more elaborate, introducing an explicit loop. On the other hand, it’s memory efficient: it’s clear that its memory requirements are O(1), whereas a naïve implementation of a sequence would need O(n) to construct it all in memory and then reduce it down to a single value.&lt;/p&gt;&lt;p&gt;Or is it really that different? Think of the changing values of &lt;code&gt;i&lt;/code&gt; in that loop. On first iteration it is 1, on second iteration it’s 2, and so on up to n. Therefore, one can really think of a &lt;code&gt;for&lt;/code&gt; loop as a sequence! I call it a “virtual” sequence, since it is not an actual data structure; it’s just a snippet of code.&lt;/p&gt;&lt;p&gt;To rephrase it as a definition: a virtual sequence is a snippet of code that (presumably repeatedly) &lt;em&gt;yields&lt;/em&gt; the member values.&lt;/p&gt;&lt;h2 id="let’s-write-some-code!"&gt;Let’s write some code!&lt;/h2&gt;&lt;p&gt;To illustrate it, throughout the remainder of this article I will be using Common Lisp, for the following reasons:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;It allows for imperative style, including GOTO-like statements. This will enable us to generate very low-level code.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Thanks to macros, we will be able to obtain interesting transformations.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Okay, so let’s have a look at how to generate a one-element sequence. Simple enough:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; vsingle (&lt;span class="hljs-name"&gt;x&lt;/span&gt;)
 `(yield ,x))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The name &lt;code&gt;VSINGLE&lt;/code&gt; stands for “Virtual sequence that just yields a SINGLE element”. (In general, I will try to define virtual sequences named and performing similarly to their Clojure counterparts here; whenever there is a name clash with an already existing CL function, the name will be prefixed with &lt;code&gt;V&lt;/code&gt;.) We will not concern ourselves with the actual definition of &lt;code&gt;YIELD&lt;/code&gt; at the moment; for debugging, we can define it just as printing the value to the standard output.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defun&lt;/span&gt; yield (&lt;span class="hljs-name"&gt;x&lt;/span&gt;)
  (&lt;span class="hljs-name"&gt;format&lt;/span&gt; &lt;span class="hljs-literal"&gt;t&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;~A~%&amp;quot;&lt;/span&gt; x))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can also convert a Lisp list to a virtual sequence which just yields each element of the list in turn:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; vseq (&lt;span class="hljs-name"&gt;list&lt;/span&gt;)
  `(loop for x in ,list do (yield x)))

(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; vlist (&lt;span class="hljs-name"&gt;&amp;amp;rest&lt;/span&gt; elems)
  `(vseq (list ,@elems)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s try to define &lt;code&gt;RANGE&lt;/code&gt;. We could use &lt;code&gt;loop&lt;/code&gt;, but for the sake of example, let’s pretend that it doesn’t exist and write a macro that expands to low-level GOTO-ridden code. For those of you who are not familiar with Common Lisp, &lt;code&gt;GO&lt;/code&gt; is like GOTO, except it takes a label that should be established within a &lt;code&gt;TAGBODY&lt;/code&gt; container.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; range (&lt;span class="hljs-name"&gt;start&lt;/span&gt; &lt;span class="hljs-symbol"&gt;&amp;amp;optional&lt;/span&gt; end (&lt;span class="hljs-name"&gt;step&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;unless&lt;/span&gt; end
    (&lt;span class="hljs-name"&gt;setf&lt;/span&gt; end start start &lt;span class="hljs-number"&gt;0&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;let&lt;/span&gt; ((&lt;span class="hljs-name"&gt;fv&lt;/span&gt; (&lt;span class="hljs-name"&gt;gensym&lt;/span&gt;)))
    `(let ((,fv ,start))
       (tagbody
        loop
          (when (&amp;gt;= ,fv ,end)
            (go out))
          (yield ,fv)
          (incf ,fv ,step)
          (go loop)
       out))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Infinite&lt;/em&gt; virtual sequences are also possible. After all, there’s nothing preventing us from considering a snippet of code that loops infinitely, executing &lt;code&gt;YIELD&lt;/code&gt;, as a virtual sequence! We will define the equivalent of Clojure’s iterate: given a function &lt;code&gt;fun&lt;/code&gt; and initial value &lt;code&gt;val&lt;/code&gt;, it will repeatedly generate &lt;code&gt;val&lt;/code&gt;, &lt;code&gt;(fun val)&lt;/code&gt;, &lt;code&gt;(fun (fun val))&lt;/code&gt;, etc.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; iterate (&lt;span class="hljs-name"&gt;fun&lt;/span&gt; val)
  (&lt;span class="hljs-name"&gt;let&lt;/span&gt; ((&lt;span class="hljs-name"&gt;fv&lt;/span&gt; (&lt;span class="hljs-name"&gt;gensym&lt;/span&gt;)))
    `(let ((,fv ,val))
       (tagbody loop
          (yield ,fv)
          (setf ,fv (funcall ,fun ,fv))
          (go loop)))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So far, we have defined a number of ways to create virtual sequences. Now let’s ask ourselves: is there a way, given code for a virtual sequence, to yield only the elements from the original that satisfy a certain predicate? In other words, can we define a &lt;code&gt;filter&lt;/code&gt; for virtual sequences? Sure enough. Just replace every occurrence of &lt;code&gt;yield&lt;/code&gt; with code that checks whether the yielded value satisfies the predicate, and only if it does invokes &lt;code&gt;yield&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;First we write a simple code walker that applies some transformation to every &lt;code&gt;yield&lt;/code&gt; occurrence in a given snippet:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defun&lt;/span&gt; replace-yield (&lt;span class="hljs-name"&gt;tree&lt;/span&gt; replace)
  (&lt;span class="hljs-name"&gt;if&lt;/span&gt; (&lt;span class="hljs-name"&gt;consp&lt;/span&gt; tree)
      (&lt;span class="hljs-name"&gt;if&lt;/span&gt; (&lt;span class="hljs-name"&gt;eql&lt;/span&gt; (&lt;span class="hljs-name"&gt;car&lt;/span&gt; tree) &amp;#x27;yield)
          (&lt;span class="hljs-name"&gt;funcall&lt;/span&gt; replace (&lt;span class="hljs-name"&gt;cadr&lt;/span&gt; tree))
          (&lt;span class="hljs-name"&gt;loop&lt;/span&gt; for x in tree collect (&lt;span class="hljs-name"&gt;replace-yield&lt;/span&gt; x replace)))
      tree))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now write &lt;code&gt;filter&lt;/code&gt; like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; filter (&lt;span class="hljs-name"&gt;pred&lt;/span&gt; vseq &lt;span class="hljs-symbol"&gt;&amp;amp;environment&lt;/span&gt; env)
  (&lt;span class="hljs-name"&gt;replace-yield&lt;/span&gt; (&lt;span class="hljs-name"&gt;macroexpand&lt;/span&gt; vseq env)
                 (&lt;span class="hljs-name"&gt;lambda&lt;/span&gt; (&lt;span class="hljs-name"&gt;x&lt;/span&gt;) `(when (funcall ,pred ,x) (yield ,x)))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is important to point out that since &lt;code&gt;filter&lt;/code&gt; is a macro, the arguments are passed to it unevaluated, so if &lt;code&gt;vseq&lt;/code&gt; is a virtual sequence definition like &lt;code&gt;(range 10)&lt;/code&gt;, we need to macroexpand it before replacing &lt;code&gt;yield&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;We can now verify that &lt;code&gt;(filter #'evenp (range 10))&lt;/code&gt; works. It macroexpands to something similar to&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;LET&lt;/span&gt; ((&lt;span class="hljs-name"&gt;#&lt;/span&gt;&lt;span class="hljs-symbol"&gt;:G70192&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;))
  (&lt;span class="hljs-name"&gt;TAGBODY&lt;/span&gt;
    LOOP (&lt;span class="hljs-name"&gt;IF&lt;/span&gt; (&lt;span class="hljs-name"&gt;&amp;gt;=&lt;/span&gt; #&lt;span class="hljs-symbol"&gt;:G70192&lt;/span&gt; &lt;span class="hljs-number"&gt;10&lt;/span&gt;)
           (&lt;span class="hljs-name"&gt;PROGN&lt;/span&gt; (&lt;span class="hljs-name"&gt;GO&lt;/span&gt; OUT)))
         (&lt;span class="hljs-name"&gt;IF&lt;/span&gt; (&lt;span class="hljs-name"&gt;FUNCALL&lt;/span&gt; #&amp;#x27;EVENP #&lt;span class="hljs-symbol"&gt;:G70192&lt;/span&gt;)
           (&lt;span class="hljs-name"&gt;PROGN&lt;/span&gt; (&lt;span class="hljs-name"&gt;YIELD&lt;/span&gt; #&lt;span class="hljs-symbol"&gt;:G70192&lt;/span&gt;)))
         (&lt;span class="hljs-name"&gt;SETQ&lt;/span&gt; #&lt;span class="hljs-symbol"&gt;:G70192&lt;/span&gt; (&lt;span class="hljs-name"&gt;+&lt;/span&gt; #&lt;span class="hljs-symbol"&gt;:G70192&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;))
         (&lt;span class="hljs-name"&gt;GO&lt;/span&gt; LOOP)
    OUT))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;concat&lt;/code&gt; is extremely simple. To produce all elements of &lt;code&gt;vseq1&lt;/code&gt; followed by all elements of &lt;code&gt;vseq2&lt;/code&gt;, just execute code corresponding to &lt;code&gt;vseq1&lt;/code&gt; and then code corresponding to &lt;code&gt;vseq2&lt;/code&gt;. Or, for multiple sequences:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; concat (&lt;span class="hljs-name"&gt;&amp;amp;rest&lt;/span&gt; vseqs)
  `(progn ,@vseqs))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To define &lt;code&gt;take&lt;/code&gt;, we’ll need to wrap the original code in a block that can be escaped from by means of &lt;code&gt;return-from&lt;/code&gt; (which is just another form of &lt;code&gt;goto&lt;/code&gt;). We’ll add a counter that will start from &lt;code&gt;n&lt;/code&gt; and keep decreasing on each &lt;code&gt;yield&lt;/code&gt;; once it reaches zero, we escape the block:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; take (&lt;span class="hljs-name"&gt;n&lt;/span&gt; vseq &lt;span class="hljs-symbol"&gt;&amp;amp;environment&lt;/span&gt; env)
  (&lt;span class="hljs-name"&gt;let&lt;/span&gt; ((&lt;span class="hljs-name"&gt;x&lt;/span&gt; (&lt;span class="hljs-name"&gt;gensym&lt;/span&gt;))
        (&lt;span class="hljs-name"&gt;b&lt;/span&gt; (&lt;span class="hljs-name"&gt;gensym&lt;/span&gt;)))
    `(let ((,x ,n))
       (block ,b
         ,(replace-yield (macroexpand vseq env)
                         (lambda (y) `(progn (yield ,y)
                                             (decf ,x)
                                             (when (zerop ,x)
                                               (return-from ,b)))))))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;rest&lt;/code&gt; (or, rather, &lt;code&gt;vrest&lt;/code&gt;, as that name is taken) can be defined similarly:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; vrest (&lt;span class="hljs-name"&gt;vseq&lt;/span&gt; &lt;span class="hljs-symbol"&gt;&amp;amp;environment&lt;/span&gt; env)
  (&lt;span class="hljs-name"&gt;let&lt;/span&gt; ((&lt;span class="hljs-name"&gt;skipped&lt;/span&gt; (&lt;span class="hljs-name"&gt;gensym&lt;/span&gt;)))
    (&lt;span class="hljs-name"&gt;replace-yield&lt;/span&gt;
     `(let ((,skipped &lt;span class="hljs-literal"&gt;nil&lt;/span&gt;)) ,(macroexpand vseq env))
     (&lt;span class="hljs-name"&gt;lambda&lt;/span&gt; (&lt;span class="hljs-name"&gt;x&lt;/span&gt;) `(if ,skipped (yield ,x) (setf ,skipped &lt;span class="hljs-literal"&gt;t&lt;/span&gt;))))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;vfirst&lt;/code&gt; is another matter. It should return a value instead of producing a virtual sequence, so we need to actually execute the code — but with &lt;code&gt;yield&lt;/code&gt; bound to something else. We want to establish a block as with &lt;code&gt;take&lt;/code&gt;, but our &lt;code&gt;yield&lt;/code&gt; will immediately return from the block once the first value is yielded:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; vfirst (&lt;span class="hljs-name"&gt;vseq&lt;/span&gt;)
  (&lt;span class="hljs-name"&gt;let&lt;/span&gt; ((&lt;span class="hljs-name"&gt;block-name&lt;/span&gt; (&lt;span class="hljs-name"&gt;gensym&lt;/span&gt;)))
   `(block ,block-name
      (flet ((yield (x) (return-from ,block-name x)))
        ,vseq))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that so far we’ve seen three classes of macros:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;macros that create virtual sequences;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;macros that transform virtual sequences to another virtual sequences;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;and finally, vfirst is our first example of a macro that produces a result out of a virtual sequence.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Our next logical step is &lt;code&gt;vreduce&lt;/code&gt;. Again, we’ll produce code that rebinds &lt;code&gt;yield&lt;/code&gt;: this time to a function that replaces the value of a variable (the accumulator) by result of calling a function on the accumulator’s old value and the value being yielded.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; vreduce (&lt;span class="hljs-name"&gt;f&lt;/span&gt; val vseq)
  `(let ((accu ,val))
     (flet ((yield (x) (setf accu (funcall ,f accu x))))
       ,vseq
       accu)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now build a constructs that executes a virtual sequence and wraps the results up as a Lisp list, in terms of &lt;code&gt;vreduce&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defun&lt;/span&gt; conj (&lt;span class="hljs-name"&gt;x&lt;/span&gt; y)
  (&lt;span class="hljs-name"&gt;cons&lt;/span&gt; y x))

(&lt;span class="hljs-name"&gt;defmacro&lt;/span&gt; realize (&lt;span class="hljs-name"&gt;vseq&lt;/span&gt;)
 `(nreverse (vreduce #&amp;#x27;conj &lt;span class="hljs-literal"&gt;nil&lt;/span&gt; ,vseq)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s verify that it works:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;realize&lt;/span&gt; (&lt;span class="hljs-name"&gt;range&lt;/span&gt; &lt;span class="hljs-number"&gt;10&lt;/span&gt;))
(&lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt; &lt;span class="hljs-number"&gt;2&lt;/span&gt; &lt;span class="hljs-number"&gt;3&lt;/span&gt; &lt;span class="hljs-number"&gt;4&lt;/span&gt; &lt;span class="hljs-number"&gt;5&lt;/span&gt; &lt;span class="hljs-number"&gt;6&lt;/span&gt; &lt;span class="hljs-number"&gt;7&lt;/span&gt; &lt;span class="hljs-number"&gt;8&lt;/span&gt; &lt;span class="hljs-number"&gt;9&lt;/span&gt;)

CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;realize&lt;/span&gt; (&lt;span class="hljs-name"&gt;take&lt;/span&gt; &lt;span class="hljs-number"&gt;5&lt;/span&gt; (&lt;span class="hljs-name"&gt;filter&lt;/span&gt; #&amp;#x27;oddp (&lt;span class="hljs-name"&gt;iterate&lt;/span&gt; #&amp;#x27;&lt;span class="hljs-number"&gt;1&lt;/span&gt;+ &lt;span class="hljs-number"&gt;0&lt;/span&gt;))))
(&lt;span class="hljs-number"&gt;1&lt;/span&gt; &lt;span class="hljs-number"&gt;3&lt;/span&gt; &lt;span class="hljs-number"&gt;5&lt;/span&gt; &lt;span class="hljs-number"&gt;7&lt;/span&gt; &lt;span class="hljs-number"&gt;9&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hey! Did we just manipulate an &lt;em&gt;infinite&lt;/em&gt; sequence and got the result in a &lt;em&gt;finite&lt;/em&gt; amount of time? And that without explicit support for laziness in our language? How cool is that?!&lt;/p&gt;&lt;p&gt;Anyway, let’s finally define our factorial:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defun&lt;/span&gt; fac (&lt;span class="hljs-name"&gt;n&lt;/span&gt;)
  (&lt;span class="hljs-name"&gt;vreduce&lt;/span&gt; #&amp;#x27;* &lt;span class="hljs-number"&gt;1&lt;/span&gt; (&lt;span class="hljs-name"&gt;range&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt; (&lt;span class="hljs-number"&gt;1&lt;/span&gt;+ n))))
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="benchmarking"&gt;Benchmarking&lt;/h2&gt;&lt;p&gt;Factorials grow too fast, so for the purpose of benchmarking let’s write a function that adds numbers from 0 below n, in sequence-y style. First using Common Lisp builtins:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defun&lt;/span&gt; sum-below (&lt;span class="hljs-name"&gt;n&lt;/span&gt;)
  (&lt;span class="hljs-name"&gt;reduce&lt;/span&gt; #&amp;#x27;+ (&lt;span class="hljs-name"&gt;loop&lt;/span&gt; for i from &lt;span class="hljs-number"&gt;0&lt;/span&gt; below n collect i) &lt;span class="hljs-symbol"&gt;:initial-value&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And now with our virtual sequences:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;(&lt;span class="hljs-name"&gt;defun&lt;/span&gt; sum-below-2 (&lt;span class="hljs-name"&gt;n&lt;/span&gt;)
  (&lt;span class="hljs-name"&gt;vreduce&lt;/span&gt; #&amp;#x27;+ &lt;span class="hljs-number"&gt;0&lt;/span&gt; (&lt;span class="hljs-name"&gt;range&lt;/span&gt; n)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s try to time the two versions. On my Mac running Clozure CL 1.7, this gives:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;time&lt;/span&gt; (&lt;span class="hljs-name"&gt;sum-below&lt;/span&gt; &lt;span class="hljs-number"&gt;10000000&lt;/span&gt;))
(&lt;span class="hljs-name"&gt;SUM-BELOW&lt;/span&gt; &lt;span class="hljs-number"&gt;10000000&lt;/span&gt;) took &lt;span class="hljs-number"&gt;8&lt;/span&gt;,&lt;span class="hljs-number"&gt;545&lt;/span&gt;,&lt;span class="hljs-number"&gt;512&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;8.545512&lt;/span&gt; seconds) to run
                    with &lt;span class="hljs-number"&gt;2&lt;/span&gt; available CPU cores.
During that period, &lt;span class="hljs-number"&gt;2&lt;/span&gt;,&lt;span class="hljs-number"&gt;367&lt;/span&gt;,&lt;span class="hljs-number"&gt;207&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;2.367207&lt;/span&gt; seconds) were spent in user mode
                    &lt;span class="hljs-number"&gt;270&lt;/span&gt;,&lt;span class="hljs-number"&gt;481&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;0.270481&lt;/span&gt; seconds) were spent in system mode
&lt;span class="hljs-number"&gt;5&lt;/span&gt;,&lt;span class="hljs-number"&gt;906&lt;/span&gt;,&lt;span class="hljs-number"&gt;274&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;5.906274&lt;/span&gt; seconds) was spent in GC.
 &lt;span class="hljs-number"&gt;160&lt;/span&gt;,&lt;span class="hljs-number"&gt;000&lt;/span&gt;,&lt;span class="hljs-number"&gt;016&lt;/span&gt; bytes of memory allocated.
 &lt;span class="hljs-number"&gt;39&lt;/span&gt;,&lt;span class="hljs-number"&gt;479&lt;/span&gt; minor page faults, &lt;span class="hljs-number"&gt;1&lt;/span&gt;,&lt;span class="hljs-number"&gt;359&lt;/span&gt; major page faults, &lt;span class="hljs-number"&gt;0&lt;/span&gt; swaps.
&lt;span class="hljs-number"&gt;49999995000000&lt;/span&gt;

CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;time&lt;/span&gt; (&lt;span class="hljs-name"&gt;sum-below-2&lt;/span&gt; &lt;span class="hljs-number"&gt;10000000&lt;/span&gt;))
(&lt;span class="hljs-name"&gt;SUM-BELOW-2&lt;/span&gt; &lt;span class="hljs-number"&gt;10000000&lt;/span&gt;) took &lt;span class="hljs-number"&gt;123&lt;/span&gt;,&lt;span class="hljs-number"&gt;081&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;0.123081&lt;/span&gt; seconds) to run
                    with &lt;span class="hljs-number"&gt;2&lt;/span&gt; available CPU cores.
During that period, &lt;span class="hljs-number"&gt;127&lt;/span&gt;,&lt;span class="hljs-number"&gt;632&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;0.127632&lt;/span&gt; seconds) were spent in user mode
                    &lt;span class="hljs-number"&gt;666&lt;/span&gt; microseconds (&lt;span class="hljs-number"&gt;0.000666&lt;/span&gt; seconds) were spent in system mode
 &lt;span class="hljs-number"&gt;4&lt;/span&gt; minor page faults, &lt;span class="hljs-number"&gt;0&lt;/span&gt; major page faults, &lt;span class="hljs-number"&gt;0&lt;/span&gt; swaps.
&lt;span class="hljs-number"&gt;49999995000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As expected, &lt;code&gt;SUM-BELOW-2&lt;/code&gt; is much faster, causes less page faults and presumably conses less. (Critics will be quick to point out that we could idiomatically write it using &lt;code&gt;LOOP&lt;/code&gt;’s &lt;code&gt;SUM/SUMMING&lt;/code&gt; clause, which would probably be yet faster, and I agree; yet if we were reducing by something other than &lt;code&gt;+&lt;/code&gt; — something that &lt;code&gt;LOOP&lt;/code&gt; has not built in as a clause — this would not be an option.)&lt;/p&gt;&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;p&gt;We have seen how snippets of code can be viewed as sequences and how to combine them to produce other virtual sequences. As we are nearing the end of this article, it is perhaps fitting to ask: what are the limitations and drawbacks of this approach?&lt;/p&gt;&lt;p&gt;Clearly, this kind of sequences is less powerful than “ordinary” sequences such as Clojure’s. The fact that we’ve built them on macros means that once we escape the world of code transformation by invoking some macro of the third class, we can’t manipulate them anymore. In Clojure world, &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;rest&lt;/code&gt; are very similar; in virtual sequences, they are altogether different: they belong to different worlds. The same goes for &lt;code&gt;map&lt;/code&gt; (had we defined one) and &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;But imagine that instead of having just one programming language, we have a high-level language A in which we are writing macros that expand to code in a low-level language B. It is important to point out that the generated code is very low-level. It could almost be assembly: in fact, most of the macros we’ve written don’t even require language B to have composite data-types beyond the type of elements of collections (which could be simple integers)!&lt;/p&gt;&lt;p&gt;Is there a practical side to this? I don’t know: to me it just seems to be something with hack value. Time will tell if I can put it to good use.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2011-07-11:post:color-your-own-europe</id>
    <title>Color your own Europe with Clojure!</title>
    <link href="http://blog.danieljanus.pl/color-your-own-europe/"/>
    <updated>2011-07-11T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;This is a slightly edited translation of &lt;a href="http://plblog.danieljanus.pl/zippery-w-clojure"&gt;an article&lt;/a&gt; I first published on my Polish blog on January 19, 2011. It is meant to target newcomers to Clojure and show how to use Clojure to solve a simple real-life problems.&lt;/p&gt;&lt;h2 id="the-problem"&gt;The problem&lt;/h2&gt;&lt;p&gt;Some time ago I was asked to prepare a couple of differently-colored maps of Europe. I got some datasets which mapped countries of Europe to numerical values: the greater the value, the darker the corresponding color should be. A sample colored map looked like this:&lt;/p&gt;&lt;img src="/img/blog/europa.png"&gt;
&lt;p&gt;I began by downloading an easily editable &lt;a href="http://commons.wikimedia.org/wiki/File:Blank_map_of_Europe.svg"&gt;map&lt;/a&gt; from Wikipedia Commons, calculated the required color intensities for the first dataset, launched &lt;a href="http://www.inkscape.org"&gt;Inkscape&lt;/a&gt; and started coloring. After half an hour of tedious clicking, I realized that I would be better off writing a simple program in Clojure that would generate the map for me. It turned out to be an easy task: the remainder of this article will be an attempt to reconstruct my steps.&lt;/p&gt;&lt;h2 id="svg"&gt;SVG&lt;/h2&gt;&lt;p&gt;The format of the source image is SVG. I knew it was an XML-based vector graphics format, I’d often encountered images in this format on Wikipedia — but editing it by hand was new to me. Luckily, it turned out that the image has a simple structure. Each country’s envelope curve is described with a &lt;code&gt;path&lt;/code&gt; element that looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs xml"&gt;&lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;path&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;id&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;class&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;eu europe&amp;quot;&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;d&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;a long list of curve node coordinates&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An important thing to note here is the &lt;code&gt;id&lt;/code&gt; attribute — this is the two-letter ISO-3166-1-ALPHA2 country code. In fact, there is an informative comment right at the beginning of the image that explains the naming conventions used. Having such a splendid input was of great help.&lt;/p&gt;&lt;p&gt;Just like HTML, SVG &lt;a href="http://www.w3.org/TR/SVG/styling.html"&gt;uses CSS stylesheets&lt;/a&gt; to define the look of an element. All that is needed to color Poland red is to style the element with a &lt;code&gt;fill&lt;/code&gt; attribute:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs xml"&gt;&lt;span class="hljs-tag"&gt;&amp;lt;&lt;span class="hljs-name"&gt;path&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;id&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;style&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;fill: #ff0000;&amp;quot;&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;class&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;eu europe&amp;quot;&lt;/span&gt;
   &lt;span class="hljs-attr"&gt;d&lt;/span&gt;=&lt;span class="hljs-string"&gt;&amp;quot;a long list of curve node coordinates&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we know all this, let’s start coding!&lt;/p&gt;&lt;h2 id="xml-in-clojure"&gt;XML in Clojure&lt;/h2&gt;&lt;p&gt;The basic way to handle XML in Clojure is to use the &lt;code&gt;clojure.xml&lt;/code&gt; namespace, which contains functions that parse XML (on a DOM basis, i.e., into an in-memory tree structure) and serialize such structures back into XML. Let us launch a REPL and start by reading our map and parsing it:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;use&lt;/span&gt;&lt;/span&gt; &amp;#x27;clojure.xml)
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
&amp;gt; (&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;m&lt;/span&gt; (&lt;span class="hljs-name"&gt;parse&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;/home/nathell/eur/Blank_map_of_Europe.svg&amp;quot;&lt;/span&gt;))
[...a long while...]
Unexpected end of file from server
  [Thrown class java.net.SocketException]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hold on in there! What’s that &lt;code&gt;SocketException&lt;/code&gt; doing here? Firefox displays this map properly, so does Chrome, WTF?! Shouldn’t everything work fine in such a great language as Clojure?&lt;/p&gt;&lt;p&gt;Well, the language is as good as its libraries — and when it comes to Clojure, one can stretch that thought further: Clojure libraries are as good as the Java libraries they use under the hood. In this case, we’ve encountered a feature of the standard Java XML parser (from &lt;code&gt;javax.xml&lt;/code&gt; package). It is restrictive and tries to reject invalid documents (even if they are well-formed). If the file being parsed contains a &lt;code&gt;DOCTYPE&lt;/code&gt; declaration, the Java parser, and hence &lt;code&gt;clojure.xml/parse&lt;/code&gt;, tries to download the DTD schema from the given address and validate the document against that schema. This is unfortunate in many aspects, especially from the point of view of the &lt;a href="http://www.w3.org"&gt;World Wide Web Consortium&lt;/a&gt;, since their servers hold the Web standards. One can easily imagine the volume of network traffic this generates: W3C has a &lt;a href="http://www.w3.org/blog/systeam?cat=68"&gt;blog post&lt;/a&gt; about it. Many Java programmers have encountered this problem at some time. There are a few solutions; we will go the simplest way and just manually remove the offending &lt;code&gt;DOCTYPE&lt;/code&gt; declaration.&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;m&lt;/span&gt; (&lt;span class="hljs-name"&gt;parse&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;/home/nathell/eur/bm.svg&amp;quot;&lt;/span&gt;))
#&amp;#x27;user/m
&amp;gt; m
[...many screenfuls of numbers...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This time we managed to parse the image. Viewing the structure is not easy because of its sheer size (as expected: the file weighs in at over 0,5 MB!), but from the very first characters of the REPL’s output we can make out that’s it a Clojure map (no pun intended). Let’s examine its keys:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;keys&lt;/span&gt;&lt;/span&gt; m)
(&lt;span class="hljs-symbol"&gt;:tag&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:content&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So the map contains three entries with descriptive names. &lt;code&gt;:tag&lt;/code&gt; contains the name of the XML element, &lt;code&gt;:attrs&lt;/code&gt; is a map of attributes for this element, and &lt;code&gt;:content&lt;/code&gt; is a vector of its subelements, each in turn being represented by similarly structured map (or a string if it’s a text node):&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-symbol"&gt;:tag&lt;/span&gt; m)
&lt;span class="hljs-symbol"&gt;:svg&lt;/span&gt;
&amp;gt; (&lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; m)
{&lt;span class="hljs-symbol"&gt;:xmlns&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;http://www.w3.org/2000/svg&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:width&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;680&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:height&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;520&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:viewBox&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;1754 161 9938 7945&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:version&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:id&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;svg2&amp;quot;&lt;/span&gt;}
&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;count&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-symbol"&gt;:content&lt;/span&gt; m))
&lt;span class="hljs-number"&gt;68&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Just for the sake of practice, let’s try to write the serialized representation of the parsed back as XML. The function &lt;code&gt;emit&lt;/code&gt; should be able to do it, but it prints XML to standard output. We can use the &lt;code&gt;with-out-writer&lt;/code&gt; macro from the namespace &lt;code&gt;clojure.contrib.io&lt;/code&gt; to dump the XML to a file:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;use&lt;/span&gt;&lt;/span&gt; &amp;#x27;clojure.contrib.io)
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
&amp;gt; (&lt;span class="hljs-name"&gt;with-out-writer&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;/tmp/a.svg&amp;quot;&lt;/span&gt; (&lt;span class="hljs-name"&gt;emit&lt;/span&gt; m))
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We try to view &lt;code&gt;a.svg&lt;/code&gt; in Firefox and…&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Error parsing XML: not well-formed
Area: file:///tmp/a.xml
Row 15, column 44: Updated to reflect dissolution of Serbia &amp; Montenegro: http://commons.wikimedia.org/wiki/User:Zirland
                 -------------------------------------------^
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It turns out that using &lt;code&gt;clojure.xml/emit&lt;/code&gt; is not recommended, because it does not handle XML entities in comments correctly; we should use &lt;code&gt;clojure.contrib.lazy-xml&lt;/code&gt; instead. For the sake of example, though, let’s stay with &lt;code&gt;emit&lt;/code&gt; and manually remove the offending line once again (we can safely do it, since that’s just a comment).&lt;/p&gt;&lt;h2 id="coloring-poland"&gt;Coloring Poland&lt;/h2&gt;&lt;p&gt;We saw earlier that our main XML node contains 68 subnodes. Let’s see what they are — tag names will suffice:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:tag&lt;/span&gt; (&lt;span class="hljs-symbol"&gt;:content&lt;/span&gt; m))
(&lt;span class="hljs-symbol"&gt;:title&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:desc&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:defs&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:rect&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:g&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:g&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So far, so good. Seems that all country descriptions are contained directly in the main node. Let us try to find Poland:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&gt; (count (filter #(and (= (:tag %) :path)
                       (= ((:attrs %) :id) "pl"))
                 (:content m)))
1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(This snippet of code filters the list of subnodes of &lt;code&gt;m&lt;/code&gt; to pick only those elements whose tag name is &lt;code&gt;path&lt;/code&gt; and value of attribute &lt;code&gt;id&lt;/code&gt; is &lt;code&gt;pl&lt;/code&gt;, and returns the length of such list.) Let’s try to add a &lt;code&gt;style&lt;/code&gt; attribute to that element, according to what we said earlier. Because Clojure data structures are immutable, we have to define a new top-level element which will be the same as &lt;code&gt;m&lt;/code&gt;, except that we will set the style of the appropriate subnode:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title"&gt;m2&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; m
                &lt;span class="hljs-symbol"&gt;:content&lt;/span&gt;
                (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; #(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;and&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-symbol"&gt;:tag&lt;/span&gt; %) &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt;)
                               (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;=&lt;/span&gt;&lt;/span&gt; ((&lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; %) &lt;span class="hljs-symbol"&gt;:id&lt;/span&gt;) &lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt;))
                        (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; % &lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; %) &lt;span class="hljs-symbol"&gt;:style&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;fill: #ff0000;&amp;quot;&lt;/span&gt;))
                        %)
                     (&lt;span class="hljs-symbol"&gt;:content&lt;/span&gt; m))))
#&amp;#x27;user/m&lt;span class="hljs-number"&gt;2&lt;/span&gt;
&amp;gt; (&lt;span class="hljs-name"&gt;with-out-writer&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;/tmp/a.svg&amp;quot;&lt;/span&gt; (&lt;span class="hljs-name"&gt;emit&lt;/span&gt; m2))
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We open the created file and see a map with Poland colored red. Yay!&lt;/p&gt;&lt;h2 id="generalization"&gt;Generalization&lt;/h2&gt;&lt;p&gt;We will generalize our code a bit. Let us write a function that colors a single state, taking a &lt;code&gt;path&lt;/code&gt; element (subnode of &lt;code&gt;svg&lt;/code&gt;) as an argument:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;color-state&lt;/span&gt;
  [{&lt;span class="hljs-symbol"&gt;:keys&lt;/span&gt; [tag attrs] &lt;span class="hljs-symbol"&gt;:as&lt;/span&gt; element} colorize-fn]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [state (&lt;span class="hljs-symbol"&gt;:id&lt;/span&gt; attrs)]
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if-let&lt;/span&gt;&lt;/span&gt; [color (&lt;span class="hljs-name"&gt;colorize-fn&lt;/span&gt; state)]
      (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; element &lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; attrs &lt;span class="hljs-symbol"&gt;:style&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;str&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;fill:&amp;quot;&lt;/span&gt; color)))
      element)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This function is similar to the anonymous one we used above in the &lt;code&gt;map&lt;/code&gt; call, but differs in some respects. It takes two arguments. As mentioned, the first one is the XML element (destructured into &lt;code&gt;tag&lt;/code&gt; and &lt;code&gt;attrs&lt;/code&gt;: you can read more about destructuring in &lt;a href="http://clojure.org/special_forms"&gt;the appropriate part of Clojure docs&lt;/a&gt;), and the second argument is… a function that should take a two-letter country code and return a HTML color description (or &lt;code&gt;nil&lt;/code&gt;, if that country’s color is not specified — &lt;code&gt;color-state&lt;/code&gt; will cope with this and return the element unchanged).&lt;/p&gt;&lt;p&gt;Now that we have &lt;code&gt;color-state&lt;/code&gt;, we can easily write a higher-level function that processes and writes XML in one step:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;save-color-map&lt;/span&gt;
  [svg colorize-fn outfile]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [colored-map (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; svg &lt;span class="hljs-symbol"&gt;:content&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; #(&lt;span class="hljs-name"&gt;color-state&lt;/span&gt; % colorize-fn) (&lt;span class="hljs-symbol"&gt;:content&lt;/span&gt; svg)))]
    (&lt;span class="hljs-name"&gt;with-out-writer&lt;/span&gt; out
      (&lt;span class="hljs-name"&gt;emit&lt;/span&gt; colored-map))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s test it:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;save-color-map&lt;/span&gt; m {&lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;#00ff00&amp;quot;&lt;/span&gt;} &lt;span class="hljs-string"&gt;&amp;quot;/tmp/a.svg&amp;quot;&lt;/span&gt;)
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This time Poland is green (we used a country→color map as an argument to &lt;code&gt;color-state&lt;/code&gt;, since Clojure maps are callable like functions). Let’s try to add blue Germany:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;save-color-map&lt;/span&gt; m {&lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;#00ff00&amp;quot;&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;de&amp;quot;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;#0000ff&amp;quot;&lt;/span&gt;} &lt;span class="hljs-string"&gt;&amp;quot;/tmp/a.svg&amp;quot;&lt;/span&gt;)
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It works!&lt;/p&gt;&lt;h2 id="problem-with-the-uk"&gt;Problem with the UK&lt;/h2&gt;&lt;p&gt;Inspired by our success, we try to color different countries. It mostly works, but the United Kingdom remains gray, regardless of whether we specify its code as “uk” or “gb”. We resort to the source of our image, and the beginning comment once again proves helpful:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Certain countries are further subdivided the United Kingdom has gb-gbn for Great Britain and gb-nir for Northern Ireland. Russia is divided into ru-kgd for the Kaliningrad Oblast and ru-main for the Main body of Russia. There is the additional grouping #xb for the “British Islands” (the UK with its Crown Dependencies – Jersey, Guernsey and the Isle of Man)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Perhaps we have to specify “gb-gbn” and “gb-nir”, instead of just “gb”? We try that, but still no luck. After a while of thought: oh yes! Our initial assumption that &lt;em&gt;all&lt;/em&gt; the country definitions are &lt;code&gt;path&lt;/code&gt; subnodes of the toplevel &lt;code&gt;svg&lt;/code&gt; node is false. We have to fix that.&lt;/p&gt;&lt;p&gt;So far we have been doing a “flat” transform of the SVG tree: we only changed the subnodes of the toplevel node, but no deeper. We should change all the &lt;code&gt;path&lt;/code&gt; elements (and &lt;code&gt;g&lt;/code&gt;, if we want to color groups of paths like the UK), regardless of how deep they occur in the tree.&lt;/p&gt;&lt;p&gt;We can use a &lt;a href="http://clojure.org/other_libraries"&gt;zipper&lt;/a&gt; to do a depth-first walk of the SVG tree. Let us define a function that takes a zipper, a predicate that tells whether to edit the node in question, and the transformation function to apply to the node if the predicate returns &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;map-zipper&lt;/span&gt; [f pred z]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;zip/end?&lt;/span&gt; z)
    (&lt;span class="hljs-name"&gt;zip/root&lt;/span&gt; z)
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;recur&lt;/span&gt;&lt;/span&gt; f pred (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt; z (&lt;span class="hljs-name"&gt;zip/edit&lt;/span&gt; #(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;pred&lt;/span&gt; %) (&lt;span class="hljs-name"&gt;f&lt;/span&gt; %) %)) zip/next)))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we rewrite &lt;code&gt;save-color-map&lt;/code&gt; as:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;save-color-map&lt;/span&gt;
  [svg colorize-fn outfile]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [colored-map (&lt;span class="hljs-name"&gt;map-zipper&lt;/span&gt; #(&lt;span class="hljs-name"&gt;color-state&lt;/span&gt; % colorize-fn) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;fn&lt;/span&gt;&lt;/span&gt; [x] (#{&lt;span class="hljs-symbol"&gt;:g&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:path&lt;/span&gt;} (&lt;span class="hljs-symbol"&gt;:tag&lt;/span&gt; x))) (&lt;span class="hljs-name"&gt;zip/xml-zip&lt;/span&gt; svg))]
    (&lt;span class="hljs-name"&gt;with-out-writer&lt;/span&gt; out
      (&lt;span class="hljs-name"&gt;emit&lt;/span&gt; colored-map))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This time the UK can be colored.&lt;/p&gt;&lt;h2 id="colorizers"&gt;Colorizers&lt;/h2&gt;&lt;p&gt;We have automated the process of styling countries to make them appear in color, but translating particular numbers to RGB is tedious. In the last part of this article we will see how to ease this: we are going to write a &lt;em&gt;colorizer&lt;/em&gt;, i.e., a function suitable for passing to &lt;code&gt;color-state&lt;/code&gt; and &lt;code&gt;save-color-map&lt;/code&gt; (so far we’ve been using maps for this).&lt;/p&gt;&lt;p&gt;Let’s start by writing a function that translates a triplet of numbers into a HTML RGB notation, because it will be easier for us to work with integers than with strings:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;htmlize-color&lt;/span&gt;
  [[r g b]]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;format&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;#%02x%02x%02x&amp;quot;&lt;/span&gt; r g b))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we insert a call to &lt;code&gt;htmlize-color&lt;/code&gt; into the appropriate pace in &lt;code&gt;color-state&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;color-state&lt;/span&gt;
  [{&lt;span class="hljs-symbol"&gt;:keys&lt;/span&gt; [tag attrs] &lt;span class="hljs-symbol"&gt;:as&lt;/span&gt; element} colorize-fn]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [state (&lt;span class="hljs-symbol"&gt;:id&lt;/span&gt; attrs)]
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;if-let&lt;/span&gt;&lt;/span&gt; [color (&lt;span class="hljs-name"&gt;colorize-fn&lt;/span&gt; state)]
      (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; element &lt;span class="hljs-symbol"&gt;:attrs&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;assoc&lt;/span&gt;&lt;/span&gt; attrs &lt;span class="hljs-symbol"&gt;:style&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;str&lt;/span&gt;&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;fill:&amp;quot;&lt;/span&gt; (&lt;span class="hljs-name"&gt;htmlize-color&lt;/span&gt; color))))
      element)))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now imagine we have a table with numeric values for states, like this:&lt;/p&gt;&lt;table class="entry"&gt;
&lt;tr class="header"&gt;&lt;th&gt;State&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Poland&lt;/td&gt;&lt;td class="center"&gt;20&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Germany&lt;/td&gt;&lt;td class="center"&gt;15&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Netherlands&lt;/td&gt;&lt;td class="center"&gt;30&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;We want to have a function that assigns colors to states, such that the intensity of a color should be proportional to the value assigned to a given state. To be more general, assume we have two colors, c1 and c2, and for a given state, for each of the R, G, B components we assign a value proportional to the difference between the state’s value and the smallest value in the dataset, normalized to lie between c1 and c2.&lt;/p&gt;&lt;p&gt;This sounds complex, but I hope an example will clear things up. This is the Clojure implementation of the described algorithm:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defn&lt;/span&gt; &lt;span class="hljs-title"&gt;make-colorizer&lt;/span&gt;
  [dataset ranges]
  (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [minv (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;apply&lt;/span&gt;&lt;/span&gt; min (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;vals&lt;/span&gt;&lt;/span&gt; dataset))
        maxv (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;apply&lt;/span&gt;&lt;/span&gt; max (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;vals&lt;/span&gt;&lt;/span&gt; dataset))
        progress (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;fn&lt;/span&gt;&lt;/span&gt; [[min-col max-col]] (/ (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&lt;/span&gt;&lt;/span&gt; max-col min-col) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&lt;/span&gt;&lt;/span&gt; maxv minv))) ranges)]
    (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;into&lt;/span&gt;&lt;/span&gt; {}
          (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;fn&lt;/span&gt;&lt;/span&gt; [[k v]] [(&lt;span class="hljs-name"&gt;.toLowerCase&lt;/span&gt; k) (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;fn&lt;/span&gt;&lt;/span&gt; [progress [min-color _]] (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;int&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;+&lt;/span&gt;&lt;/span&gt; min-color (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;*&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&lt;/span&gt;&lt;/span&gt; v minv) progress)))) progress ranges)])
               dataset))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let us see how it works on our sample data:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;&amp;gt; (&lt;span class="hljs-name"&gt;make-colorizer&lt;/span&gt; {&lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt; &lt;span class="hljs-number"&gt;20&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;de&amp;quot;&lt;/span&gt; &lt;span class="hljs-number"&gt;15&lt;/span&gt;&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;nl&amp;quot;&lt;/span&gt; &lt;span class="hljs-number"&gt;30&lt;/span&gt;} [[&lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;255&lt;/span&gt;] [&lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;] [&lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;]])
{&lt;span class="hljs-string"&gt;&amp;quot;pl&amp;quot;&lt;/span&gt; (&lt;span class="hljs-number"&gt;85&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;)&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;de&amp;quot;&lt;/span&gt; (&lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;)&lt;span class="hljs-punctuation"&gt;,&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;nl&amp;quot;&lt;/span&gt; (&lt;span class="hljs-number"&gt;255&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-number"&gt;0&lt;/span&gt;)}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The second argument means that the red component is to range between 0 and 255, and the green and blue components are to be fixed at 0.&lt;/p&gt;&lt;p&gt;Like we wanted, Germany ends up darkest (because it has the least value), the Netherlands is lightest (because it has the greatest value), and Poland’s intensity is one third that of the Netherlands (because 20 is in one third of the way between 15 and 30).&lt;/p&gt;&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;&lt;p&gt;The application we created can be further developed in many ways. One can, for instance, add a Web interface for it, or write many different colorizers (e.g., discrete colorizer: fixed colours for ranges of input values, or a temperature colorizer transitioning smoothly from blue through white to red — to do this we would have to pass through the HSV color space).&lt;/p&gt;&lt;p&gt;What is your idea to improve on it? For those of you who are tired of pasting snippets of code into the REPL, I’m putting the complete source code with a Leiningen project on &lt;a href="https://github.com/nathell/color-europe"&gt;GitHub&lt;/a&gt;. Forks are welcome.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2010-05-04:post:defnk</id>
    <title>Keyword arguments</title>
    <link href="http://blog.danieljanus.pl/defnk/"/>
    <updated>2010-05-04T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;There’s been an &lt;a href="http://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure"&gt;ongoing&lt;/a&gt; &lt;a href="http://www.fatvat.co.uk/2009/01/passing-parameters-in-clojure.html"&gt;debate&lt;/a&gt; about how to pass optional named arguments to Clojure functions. One way to do this is the &lt;a href="http://richhickey.github.com/clojure-contrib/def-api.html#clojure.contrib.def/defnk"&gt;defnk&lt;/a&gt; macro from &lt;code&gt;clojure.contrib.def&lt;/code&gt;; I hesitate to call it &lt;em&gt;canonical&lt;/em&gt;, since apparently not everyone uses it, but I’ve found it useful a number of times. Here’s a sample:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;user&amp;gt; (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;use&lt;/span&gt;&lt;/span&gt; &amp;#x27;clojure.contrib.def)
&lt;span class="hljs-literal"&gt;nil&lt;/span&gt;
user&amp;gt; (&lt;span class="hljs-name"&gt;defnk&lt;/span&gt; f [&lt;span class="hljs-symbol"&gt;:b&lt;/span&gt; &lt;span class="hljs-number"&gt;43&lt;/span&gt;] (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;inc&lt;/span&gt;&lt;/span&gt; b))
#&amp;#x27;user/f
user&amp;gt; (&lt;span class="hljs-name"&gt;f&lt;/span&gt;)
&lt;span class="hljs-number"&gt;44&lt;/span&gt;
user&amp;gt; (&lt;span class="hljs-name"&gt;f&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:b&lt;/span&gt; &lt;span class="hljs-number"&gt;100&lt;/span&gt;)
&lt;span class="hljs-number"&gt;101&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is an example of &lt;em&gt;keyword arguments&lt;/em&gt; in action. Keyword arguments are a core feature of some languages, notably &lt;a href="http://www.gigamonkeys.com/book/functions.html#keyword-parameters"&gt;Common Lisp&lt;/a&gt; and &lt;a href="http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#htoc38"&gt;Objective Caml&lt;/a&gt;. Clojure doesn’t have them, but it’s pretty easy to emulate their basic usage with macros, as &lt;code&gt;defnk&lt;/code&gt; does.&lt;/p&gt;&lt;p&gt;But there’s more to Common Lisp’s keyword arguments than &lt;code&gt;defnk&lt;/code&gt; provides. In CL, the default value of a keyword argument can be an expression referring to other arguments of the same function. For example:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs lisp"&gt;CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;defun&lt;/span&gt; f (&lt;span class="hljs-name"&gt;&amp;amp;key&lt;/span&gt; (&lt;span class="hljs-name"&gt;a&lt;/span&gt; &lt;span class="hljs-number"&gt;1&lt;/span&gt;) (&lt;span class="hljs-name"&gt;b&lt;/span&gt; a))
           (&lt;span class="hljs-name"&gt;+&lt;/span&gt; a b))
F
CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;f&lt;/span&gt;)
&lt;span class="hljs-number"&gt;2&lt;/span&gt;
CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;f&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:a&lt;/span&gt; &lt;span class="hljs-number"&gt;45&lt;/span&gt;)
&lt;span class="hljs-number"&gt;90&lt;/span&gt;
CL-USER&amp;gt; (&lt;span class="hljs-name"&gt;f&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:b&lt;/span&gt; &lt;span class="hljs-number"&gt;101&lt;/span&gt;)
&lt;span class="hljs-number"&gt;102&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I wish &lt;code&gt;defnk&lt;/code&gt; had this feature. Or is there some better way that I don’t know of?&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2010-04-18:post:sunflower</id>
    <title>Sunflower</title>
    <link href="http://blog.danieljanus.pl/sunflower/"/>
    <updated>2010-04-18T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;The program I’ve been [writing about recently][1] has come to a point where I think it can be shown to the wide public. It’s called [Sunflower][2] and has its home on GitHub. It’s nowhere near being completed, and of alpha quality right now, but even at this stage it might be useful.&lt;/p&gt;&lt;p&gt;Just as sunflower seed kernels come wrapped in hulls, most HTML documents seen in the wild come wrapped in noise that is not really part of the document itself. Take any news site: a document from such a site contains things such as advertisements, header, footer, and many links. Now suppose you have many documents grabbed from the same site. Is it possible to somehow automate the extraction of the document “essences”?&lt;/p&gt;&lt;p&gt;Sunflower to the rescue. It relies on the assumption that documents coming from the same source have the same structure. It presents a list of strings to the user, and asks to pick those that are contained in the text essence. Then it finds the coordinates of the smallest HTML subtree that contains all those strings, and uses those coordinates to extract information from all documents. And it comes with a nice, easily understandable GUI for that.&lt;/p&gt;&lt;p&gt;This technique works remarkably well for many collections, although not all. An earlier, proof-of-concept implementation (in Common Lisp) has been used to extract many press texts for the [National Corpus of Polish][3].&lt;/p&gt;&lt;p&gt;I’ve given up on the symbol-capturing approach to wizards I’ve presented in my previous posts. Inspired by the DOM tree in Web apps, with a bag of elements with identifiers, I now have a central bag of Swing widgets (implemented as an atom) identified by keywords. This bag contains tidbits of the mutable state of Sunflower. This means that I can write callback functions like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;#(&lt;span class="hljs-name"&gt;with-components&lt;/span&gt; [strings-model selected-dir]
   (&lt;span class="hljs-name"&gt;.removeAllElements&lt;/span&gt; strings-model)
   (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [p (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt; selected-dir htmls first parse)]
     (&lt;span class="hljs-name"&gt;add-component&lt;/span&gt; &lt;span class="hljs-symbol"&gt;:parsed&lt;/span&gt; p)
     (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;doseq&lt;/span&gt;&lt;/span&gt; [x (&lt;span class="hljs-name"&gt;strings&lt;/span&gt; p)]
       (&lt;span class="hljs-name"&gt;.addElement&lt;/span&gt; strings-model x))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Name and conquer: having parts of state explicitly named mean that I can reliably access them from just about anywhere. This reduces confusion and allows for less tangled, more self-contained and understandable code.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2010-04-05:post:symbol-capture</id>
    <title>A case for symbol capture</title>
    <link href="http://blog.danieljanus.pl/symbol-capture/"/>
    <updated>2010-04-05T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;Clojure by default protects macro authors from incidentally capturing a local symbol. Stuart Halloway &lt;a href="http://blog.thinkrelevance.com/2008/12/17/on-lisp-clojure-chapter-9"&gt;describes this&lt;/a&gt; in more detail, explaining why this is a Good Thing. However, sometimes this kind of symbol capture is called for. I’ve encountered one such case today while hacking a Swing application.&lt;/p&gt;&lt;p&gt;As I develop the app, I find new ways to express Swing concepts and interact with Swing objects in a more Clojuresque way, so a library of GUI macros and functions gets written. One of them is a &lt;code&gt;wizard&lt;/code&gt; macro for easy creation of installer-like wizards, where there is a sequence of screens that can be navigated with &lt;em&gt;Back&lt;/em&gt; and &lt;em&gt;Next&lt;/em&gt; buttons at the bottom of the window.&lt;/p&gt;&lt;p&gt;The API (certainly not finished yet) currently looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;wizard&lt;/span&gt; &amp;amp; components)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where each Swing &lt;code&gt;component&lt;/code&gt; corresponding to one wizard screen can be augmented by a supplementary map, which can contain, &lt;em&gt;inter alia&lt;/em&gt;, a function to execute upon showing the screen in question.&lt;/p&gt;&lt;p&gt;Now, I want those functions to be able to access the &lt;em&gt;Back&lt;/em&gt; and &lt;em&gt;Next&lt;/em&gt; buttons in case they want to disable or enable them at need. I thus want the API user to be able to use two symbols, &lt;code&gt;back-button&lt;/code&gt; and &lt;code&gt;next-button&lt;/code&gt;, in the macro body, and have them bound to the corresponding buttons.&lt;/p&gt;&lt;p&gt;It is crucial that these bindings be lexical and not dynamic. If they were dynamic, they would be only effective during the definition of the wizard, but not when my closures are invoked later on. Thus, my implementation looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-keyword"&gt;defmacro&lt;/span&gt; &lt;span class="hljs-title"&gt;wizard&lt;/span&gt; [&amp;amp; panels]
  `(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;let&lt;/span&gt;&lt;/span&gt; [~&amp;#x27;back-button (&lt;span class="hljs-name"&gt;button&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;&amp;lt; Back&amp;quot;&lt;/span&gt;)
         ~&amp;#x27;next-button (&lt;span class="hljs-name"&gt;button&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;Next &amp;gt;&amp;quot;&lt;/span&gt;)]
   (&lt;span class="hljs-name"&gt;do-wizard&lt;/span&gt; ~&amp;#x27;back-button ~&amp;#x27;next-button ~(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;vec&lt;/span&gt;&lt;/span&gt; panels))))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;do-wizard&lt;/code&gt; is a private function implementing the actual wizard creation, and the &lt;code&gt;~'foo&lt;/code&gt; syntax forces symbol capture.&lt;/p&gt;&lt;p&gt;By the way, if all goes well, this blog post should be the first one syndicated to Planet Clojure. Hello, Planet Clojure readers!&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2010-03-31:post:lein-swank</id>
    <title>The pitfalls of &lt;code&gt;lein swank&lt;/code&gt;</title>
    <link href="http://blog.danieljanus.pl/lein-swank/"/>
    <updated>2010-03-31T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;A couple of weeks ago I finally got around to acquainting myself with [Leiningen][1], one of the most popular build tools for Clojure. The thing that stopped me the most was that Leiningen uses [Maven][2] under the hood, which seemed a scary beast at first sight — but once I’ve overcome the initial fear, it turned out to be a quite simple and useful tool.&lt;/p&gt;&lt;p&gt;One feature in particular is very useful for Emacs users like me: &lt;code&gt;lein swank&lt;/code&gt;. You define all dependencies in &lt;code&gt;project.clj&lt;/code&gt; as usual, add a magical line to &lt;code&gt;:dev-dependencies&lt;/code&gt;, then say&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ lein swank
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and lo and behold, you can &lt;code&gt;M-x slime-connect&lt;/code&gt; from your Emacs and have all the code at your disposal.&lt;/p&gt;&lt;p&gt;There is, however, an issue that you must be aware of when using &lt;code&gt;lein swank&lt;/code&gt;: Leiningen uses a custom class loader — [AntClassLoader][3] to be more precise — to load the Java classes referenced by the code. Despite being a seemingly irrelevant thing — an implementation detail — this can bite you in a number of most surprising and obscure ways. Try evaluating the following code in a Leiningen REPL:&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs clojure"&gt;(&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;str&lt;/span&gt;&lt;/span&gt; (&lt;span class="hljs-name"&gt;.decode&lt;/span&gt;
       (&lt;span class="hljs-name"&gt;java.nio.charset.Charset/forName&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;ISO-8859-2&amp;quot;&lt;/span&gt;)
       (&lt;span class="hljs-name"&gt;java.nio.ByteBuffer/wrap&lt;/span&gt;
         (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;into-array&lt;/span&gt;&lt;/span&gt; Byte/TYPE (&lt;span class="hljs-name"&gt;&lt;span class="hljs-built_in"&gt;map&lt;/span&gt;&lt;/span&gt; byte [&lt;span class="hljs-number"&gt;-79&lt;/span&gt; &lt;span class="hljs-number"&gt;-26&lt;/span&gt; &lt;span class="hljs-number"&gt;-22&lt;/span&gt;])))))
&lt;span class="hljs-comment"&gt;;=&amp;gt; &amp;quot;???&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The same code evaluated in a plain Clojure REPL will give you &lt;code&gt;"ąćę"&lt;/code&gt;, which is a string represented in ISO-8859-2 by the three bytes from the above snippet.&lt;/p&gt;&lt;p&gt;Whence the difference? Internally, each charset is represented as a unique instance of its specific class. These are loaded lazily as needed by the &lt;code&gt;Charset/forName&lt;/code&gt; method. Presumably, the system class loader is used for that, and somewhere along the way a &lt;code&gt;SecurityException&lt;/code&gt; gets thrown and caught.&lt;/p&gt;&lt;p&gt;Note also that there are parts of Java API which use the charset lookup under the hood and are thus vulnerable to the same problem, for example &lt;code&gt;Reader&lt;/code&gt; constructors taking charset names. If you use &lt;code&gt;clojure.contrib.duck-streams&lt;/code&gt;, then rebinding &lt;code&gt;*default-encoding*&lt;/code&gt; will not work from a Leiningen REPL. Jars and überjars produced by Leiningen should be fine, though.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:blog.danieljanus.pl,2010-02-10:post:clojure-set</id>
    <title>Clojure SET</title>
    <link href="http://blog.danieljanus.pl/clojure-set/"/>
    <updated>2010-02-10T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;I’ve just taken a short breath off work to put &lt;a href="http://github.com/nathell/setgame"&gt;some code&lt;/a&gt; on GitHub that I had written over one night some two months ago. It is an implementation of the &lt;a href="http://en.wikipedia.org/wiki/Set_(game)"&gt;Set&lt;/a&gt; game in Clojure, using Swing for GUI.&lt;/p&gt;&lt;p&gt;I do not have time to clean up or comment the code, so I’m leaving it as is for now; however, I hope that even in its current state it can be of interest, especially for Clojure learners.&lt;/p&gt;&lt;p&gt;Some random notes on the code:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Clojure is concise! The whole thing is just under 250 lines of code, complete with game logic and the GUI. Of these, the logic is about 50 LOC. Despite this it reads clearly and has been a pleasure to write, thanks to Clojure’s supports for sets as a data structure (in vein of the game’s title and theme).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;There are no graphics included. All the drawing is done in the GUI part of code (I’ve replaced the canonical squiggle shape by a triangle and stripes by gradients, for the sake of easier drawing).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;I’ve toyed around with different Swing layout managers for this game. Back in the days when I wrote in plain Java, I used to use &lt;a href="https://tablelayout.dev.java.net/"&gt;TableLayout&lt;/a&gt;, but it has a non-free license; &lt;a href="http://www.jgoodies.com/freeware/forms/"&gt;JGoodies Forms&lt;/a&gt; is also nice, but has a slightly more complicated API (and it’s an additional dependency, after all). In the end I’ve settled with the standard GridBagLayout, which is similar in spirit to those two, but requires more boilerplate to set up. As it turned out, simple macrology makes it quite pleasurable to use; see &lt;code&gt;add-gridbag&lt;/code&gt; in the code for details.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Other things of interest might be my function to randomly shuffle seqs, which strikes a nice balance between simplicity/conciseness of implementation and randomness; and a useful debugging macro.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Comments?&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
</feed>
