RSSAmplifier

Blog

code · words · emotions: Daniel Janus’s blog

blog.danieljanus.plRSS feed ↗72 posts

Latest posts

Things I wish Datomic had: Map values

Whence this post JEP 401 – a proposal to add value classes to Java – has been crystallizing for almost six years now, but I only learned about it this morning. I skimmed it, nodding along to myself as I thought “gee, I can’t imagine going back to Java” and “wonder how this might make Clojure more performant?”. But then I thought about some Datomic (actually, Datahike) data remodelling that I’d…

Now what?

Here’s an impressive Show HN project : a comprehensive, reverse-engineered, LLM-written technical documentation of how a calculator’s operating system works. What a resource! Insert a standard paragraph about how we live in interesting times. I keep seeing projects like this increasingly more often: complex, working beasts – that would previously have been nigh impossible to implement by one…

How can I keep from singing?

This is a story of a most unexpected journey — one that is just starting. If somebody had told me four years ago that I’d be writing this today, I would have stared at them in astonishment or laughed dismissedly. Yet here I am, writing about a late-found hobby that has somehow become a very important part of my life. It almost feels like making a confession. Deep breath. Okay, here we go: In 2022,…

Translating non-trivial codebases with Claude

I was wrong (or was I?) In my last post , I stated: I don’t think it’s [me writing about LLMs] likely to happen anytime soon: I prefer to write about things that I’m excited about. I was wrong. And right at the same time. Here comes another post where LLMs play a prominent role. I've asked Claude Code (Opus 4.6) to “rewrite this non-trivial codebase from C++ to Java”. And it worked quite…

On LLMs in programming

’Tis the year’s midnight, and it is the day’s . Well, it’s two weeks past Lucy’s as I write this, but it is still that time of the year: the time of slowing down, taking a step back from the hustle and bustle of everyday, reflecting on what has happened and what is yet to come. Perhaps no better time to put together my thoughts on LLMs, and more specifically on their use in programming. This post…

No, really, you can’t branch Datomic from the past (and what you can do instead)

I have a love-hate relationship with Datomic . 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. 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.…

Cleaner codebase, happier mind

This is my home-office desk on a typical day. Yuck – look at those mugs, cables and rubbish! As a person with ADHD, I have a hard time maintaining cleanliness – and a high tolerance to mess around me. However, being in a cluttered environment does take its toll. Often I find myself frustrated by it, but also overwhelmed by tasks at hand, to the point of cleaning up feeling almost an insurmountable…

Double, double toil and trouble or, Corner-Cases of Comparing Clojure Numbers

Let’s talk about Clojure. In Clojure, comparing two numbers can throw an exception. Check this out: ( < 1/4 0.5M ) ;=> true ; as expected ( < 1/3 0.5M ) ; Execution error (ArithmeticException) at java.math.BigDecimal/divide (BigDecimal.java:1783). ; Non-terminating decimal expansion; no exact representable decimal result. But why? Why would comparing two perfectly cromulent numbers throw an…

Lossy CSS compression for fun and loss (or profit)

What 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…

My mental model of transducers

Intro I’ve been programming in Clojure for a long time, but I haven’t been using transducers much. I learned to mechanically transform (into [] (map f coll)) to (into [] (map f) coll) 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. I found Eero Helenius’ article…

A visual tree iterator in Rust

My adventure with learning Rust continues. As a quick recap from the previous post, I’m writing a tree viewer . I have now completed another major milestone, which is to rewrite the tree-printing function to use an iterator. (Rationale: it makes the code more reusable – I can, for instance, easily implement a tree-drawing view for Cursive with it.) And, as usual, I’ve fallen into many traps before…

Learning to learn Rust

I’m enjoying a two-month sabbatical this summer. It’s been great so far! I’ve used almost half of the time to cycle through the entire Great Britain and let my body work physically and my mind rest (usually, the opposite is true). And now that I’m back, I’ve switched focus to a few personal projects that I have really wanted to work on for a while but never found time. One of these projects is to…

Dutch Clojure Days 2022

It’s a tradition of this blog that I write down impressions on my way back from Amsterdam conferences ( addendum a week later : unfortunately I took a flight this time, too short to complete this entry, and it had to wait until I caught up). This time, it was Dutch Clojure Days 2022 , my first post-COVID full-size conference and the first DCD I’ve ever been to. And, hopefully, not last. I know I…

How to pay for books

This post was originally published in Polish . This translation has been slightly edited to explain some details that are likely to be obscure for people outside Poland. Fortuna imperatrix mundi I wouldn’t make a good emperor of the universe. Sometimes I wonder what I would change if I had the power to shape the world any way I could, and always I come to the same conclusion: I don’t know . I see…

I love my GPD Micro PC

I bought two computers this year: a beefy Macbook Pro with M1 Pro and a GPD Micro PC. The MBP is meant to be my mobile workstation, to satisfy all my needs whenever I need to work outside of my home office (at home, I’m still mostly using a two-year-old Intel-based Mac Mini). The GPD was a caprice. Perhaps I’m at the stage in life when well-off men buy themselves Ferraris to fend off a mid-life…

Testing a compiler that can’t even print stuff out

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. I opted for Lithium, my toy x86 assembler and Lisp compiler that hasn’t seen new development since 2014. But before that, I had blogged about it and even talked about…

Things I wish Git had: Commit groups

Intro Everyone 1 and their dog 2 loves Git. I know I do. It works, it’s efficient, it has a brilliant data model, and it sports every feature under the sun . In 13 years of using it, I’ve never found myself needing a feature it didn’t have. Until recently. But before I tell you about it, let’s talk about GitHub. There are three groups of GitHub users, distinguished by how they prefer to merge pull…

I made a website to guess tomorrow’s number of COVID-19 cases, and here’s what happened

Before 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…

Making of “Clojure as a dependency”

In my previous post, “Clojure as a dependency” , I’ve presented the results of some toy research on Clojure version numbers seen in the wild. I’m a big believer in reproducible research , so I’m making available a Git repo that contains code you can run yourself to reproduce these results. This post is an experience report from writing that code. There are two main components to this project:…

Clojure as a dependency

I have a shameful confession to make: I have long neglected an open-source library that I maintain, clj-tagsoup . 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. Anyway, I’ve recently been prompted to revive it, and…

Indenting cond forms

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 community style guide or the proposed simplified rules ; the existing editors make it easy to reformat code to match them. I find both these rulesets to be helpful when reading code. But there’s one corner-case…

Careful with that middleware, Eugene

Prologue I’ll be releasing version 0.3 of Skyscraper , my Clojure framework for scraping entire sites, in a few days. 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…

Word Champions

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?” He attached a link to this video: Now, we’re both avid Scrabble players, so we explored some ideas about extracting helpful data out of the Official Polish Scrabble Player’s Dictionary . I launched…

Web of Documents

In 1960, Ted Nelson envisioned a web of documents. It was called Xanadu . It was a grand, holistic vision: of documents that, once published, are available basically forever; of bidirectional links that could glue together not just documents, but parts thereof; of managing copyright and royalties. It was complex. And it never really came to fruition. But thirty-one years later, another web of…

Re-framing text-mode apps

Intro “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 A couple of nights ago, I hacked together a small Clojure program. 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…

Happy Programmers’ Day!

Happy Programmers’ Day , everyone! A feast isn’t a feast, though, until it has a proper way of celebrating it. The Pi Day , for instance, has one: you eat a pie (preferably exactly at 1:59:26.535am), but I haven’t heard of any way of celebrating the Programmers’ Day, so I had to invent one. An obvious way would be to write a program, preferably a non-trivial one, but that requires time and…

You already use Lisp syntax

Unix Developer: I’m not going to touch Lisp. It’s horrible! Me: Why so? UD: The syntax! This illegible prefix-RPN syntax that nobody else uses. And just look at all these parens! Me: 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… UD: I happen to know…

DOS debugging quirk

While hacking on Lithium, I’ve noticed an interesting thing. Here’s a sample DOS program in assembly (TASM syntax): .model tiny .code org 100h N equ 2 start: mov bp , sp mov ax , 100 mov [ bp -N], ax mov cx ,[ bp -N] cmp cx , ax jne wrong mov dx ,offset msg jmp disp wrong: mov dx ,offset msg2 disp: mov ah , 9 int 21h mov ax , 4c00h int 21h msg db "ok$" msg2 db "wrong$" end start If you assemble,…

2048: A close look at the source

Dust has now mostly settled down on 2048 . Yet, in all the deluge of variants and clones that has swept through Hacker News , little has been written about the experience of modifying the game. As I too have jumped on the 2048-modding bandwagon, it’s time to fill that gap, because, as we shall see, the code more than deserves a close look. I’ll start with briefly describing my variant. It’s called…

Lithium revisited: A 16-bit kernel (well, sort of) written in Clojure (well, sort of)

Remember Lithium ? The x86 assembler written in Clojure, and a simple stripes effect written in it? Well, here’s another take on that effect: And here is the source code: ( do ( init-graph ) ( loop [x 0 y 0 ] ( put-pixel x y ( let [z ( mod ( + ( - 319 x) y) 32 )] ( if ( < z 16 ) ( + 16 z) ( + 16 ( - 31 z))))) ( if ( = y 200 ) nil ( if ( = x 319 ) ( recur 0 ( inc y)) ( recur ( inc x) y))))) I’ve…

My top three iOS apps for mapping

Living in London means that I now have a whole lot of new area to explore by cycling or walking. I try to take every opportunity to spend a free day or weekend out. One of the most important things when on the move is knowing where you are, where to go, and how to get there — and for that, you need a map. As I soon learned, the maps to use in the UK are the Ordnance Survey ones (either the…

Lithium: an x86 assembler for Clojure

Ah, the golden days of childhood’s hackage. Don’t you have fond memories of them? 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 small town in Poland ; my main…

How to call a private function in Clojure

tl;dr: Don’t do it. If you really have to, use (#'other-library/private-function args) . A private function in Clojure is one that has been defined using the defn- macro, or equivalently by setting the metadata key :private to true 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…

Lifehacking: How to get cheap home equipment using Clojure

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:…

Ever wanted to programmatically file a lawsuit? In Poland, you can.

This has somehow escaped me: just over a year ago, the Sixth Civil Division of the Lublin-West Regional Court in Lublin, Poland, has opened its online branch . It serves the entire territory of Poland and is competent to recognize lawsuits concerning payment claims. There is basic information available in English. It has proven immensely popular, having processed about two million cases in its…

Combining virtual sequences<br>or, Sequential Fun with Macros<br>or, How to Implement Clojure-Like Pseudo-Sequences with Poor Man’s Laziness in a Predominantly Imperative Language

Sequences and iteration 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 sequence abstraction being one of its central concepts, and a standard library that contains many…

Color your own Europe with Clojure!

This is a slightly edited translation of an article 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. The problem 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…

Meet my little friend createTree

I’ve recently been developing an iPhone application in my spare time. I’m not going to tell you what it is just yet (I will post a separate entry once I manage to get it into the App Store); for now, let me just say that I’m writing it in JavaScript and HTML5, using [PhoneGap][1] and [jQTouch][2] to give it a native touch. After having written some of code, I began testing it on a real device and…

A quirk with JavaScript closures

I keep running into this obstacle every now and then. Consider this example: > q = [] [] > for ( var i = 0 ; i < 3 ; i++) q. push ( function ( ) { console . log (i); }); > q[ 0 ]() 3 I wanted an array of three closures, each printing a different number to the console when called. Instead, each prints 3 (or, rather, whatever the value of the variable i happens to be). I am not exactly sure about…

The Dijkstran wheel of fortune: SPSS, Excel, VBA

It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration. — Edsger W. Dijkstra, EWD 498 I like to think of myself somewhat egotistically as a counterexample to the above Dijkstra’s statement. Granted, some of my code is definitely of poor quality, and I dare not call…

Hello world, again

I’ve been quiet on the front of blogging in English recently. But that doesn’t mean I’ve given up. After more than a year, I had become tired of maintaining a Blosxom installation. I greatly admire Blosxom, its minimalism and extensibility, but the default installation is just too minimal for my needs. And the plugins tend to have rough edges. Like the Disqus comments that I’ve enabled at one time…

Last post here

I’ve decided to move my English blog to Posterous. The new address is http://danieljanus-en.posterous.com . This URL ( http://blog.danieljanus.pl ) will point to the new blog in about a week’s time. I’m only posting this to let people update their RSS feeds to the new address, which is http://feeds.feedburner.com/MusingsOfALispnik

Keyword arguments

There’s been an ongoing debate about how to pass optional named arguments to Clojure functions. One way to do this is the defnk macro from clojure.contrib.def ; I hesitate to call it canonical , since apparently not everyone uses it, but I’ve found it useful a number of times. Here’s a sample: user> ( use &#x27;clojure.contrib.def) nil user> ( defnk f [ :b 43 ] ( inc b)) #&#x27;user/f user> ( f )…

Sunflower

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. Just as sunflower seed kernels come wrapped in hulls, most HTML documents seen in the wild come wrapped in noise…

A case for symbol capture

Clojure by default protects macro authors from incidentally capturing a local symbol. Stuart Halloway describes this 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. As I develop the app, I find new ways to express Swing concepts and interact with Swing objects…

Hiking in the Apennines

I’ve recently done a week-long hike in the Umbria-Marche region of the Italian Apennines (the vicinity of Monte Catria , near Cantiano , to be more precise), and here are some tips I’d like to share. The Umbria-Marche Apennine doesn’t seem to be frequented by a lot of tourists, especially in mid-March. The information offices, although helpful, are often closed (this is not only the case with the…

The pitfalls of <code>lein swank</code>

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. One feature in particular is very useful…

Downcasing strings

I just needed to convert a big (around 200 MB) text file, encoded in UTF-8 and containing Polish characters, all into lowercase. tr to the rescue, right? Well, not quite. $ echo ŻŹŚÓŃŁĘĆĄ | tr A-ZĄĆĘŁŃÓŚŹŻ a-ząćęłńóśźż żźśóńłęćą Looks reasonable (apart from the fact that I need to specify an explicit character mapping — it would be handy to just have a lcase utility or suchlike); but here’s what…

Clojure SET

I’ve just taken a short breath off work to put some code on GitHub that I had written over one night some two months ago. It is an implementation of the Set game in Clojure, using Swing for GUI. 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. Some random notes…

Reactivation (and some ramblings on my blogging infrastructure)

This blog has not seen content updates in more than a year. Plenty of things can happen in such a long period, and in fact many aspect of my life have seen major changes over this time. I’m not, however, going to write a lengthy post about all that right now. Instead, I just would like to announce the reactivation of the blog. You might have noticed that many things have changed. First, the blog…