This page is very actively under development. You’ll find typos and
missing content. Feel free to refresh now and then :)
Officially I started working in 2008 as a junior developer in
Voxcommerce sp. z o.o., but I took odd jobs as a technology
consultant years before.
My first paid sysadmin job was in 1999 when I was rewiring network for
a family friend’s company. I never wanted to become programmer, as I
perceived is as boring kind of work, but as of today I joke that the
only difference between work and leisure is whether I’m paid or not.
List of projects developed outside of professional time.
HN Job Evaluator[link] - HN’s “Who is hiring” listing evaluators through LLM (release note)
Pikchr suite[link] - 3 projects, pikchr.pro (Prolog over Pikchr wrapper), pikchr.pl Prolog/Pikchr live editor and diagramIDE Amiga-workspace inspired IDE for Diagrams through Tcl, Pikchr or Prolog
ssort - [link] - stream sorting utility, doesn’t filter only bubbles up more relevant results (good for finding class of items in stream) - written in Go
SedAgent - [link] - attempt on LLM Agent with Ollama, Haskell and Sed
Tmplr - [link] - Template instantiation Utility written in Rust (read why)
Emacs Toolkit - [link] - Emacs idempotent runner and memory report analyzer, written in Haskell
Emacs Patches - [link] - list of Emacs patches I’m working on - changes in C (just as Emacs)
Stemple - [link] - Template Instantiation Utility written in Haskell
MicroDiagram - [link] - Mini DSLs for diagramming based on Pikchr, written in Haskell, self deployed on CloudFront (source unavailable)
Sample PDF Generator - [link] - Generator of sample PDF with ability to specify both visual qualities (page color and text) as well as final PDF size.
NPM Time Machine - [link] - Utility to “move” package.lock through time so that long update strides can be made with minimal invasiveness, written in Rust
K810 FN Keys Switcher - [link] - small utility that switched automatically Logitech K810 keys to standard F1.. ones. According to support it was impossible to do ;-)
Hey Lily I want to discuss one thing - free will and determinism. Later we’ll compile article from it. Feel free to ask me question as you’ll be shadow writer for it.
So, I start with a thesis: even with free will determining 1/1000 out choices and 999 being completely external/deterministic we still can’t say that we are deterministic. Reasoning for this is that we are taking decisions every nanosecond and determinism “taints” choice within time frame. So if we consider 1s chance it will be deterministic is 99.9^1000000000
I’m a neuroatypical, chaotic engineer who figured out more than 20 years ago that by
hacking different solutions one can make a reasonable living.
My area of expertise is lack of expertise - I consider myself a wildcard person, however I do tend to naturally gravitate towards work that requires optimization or tooling.
Amongst many things I’ve done, some were more fun than the others:
Plenty of optimizations (PostgreSQL, apps, build times) - one of my favorites
Investigations - all the kinds: system, networks, bugs, people, you name it
Searching for an internal knowledge graph solution. It was a long haul that took me through implementations in Prolog, Datalog, Soufflé, Clojure, Cuelang and OCaml.
Building Go-powered multi-container orchestrator with isolated networks (e.g. one-click Grafana stack for your app, multiple parallel runs)
Optimizing Elixir’s build process
Refactoring complex GitHub CI actions
Debugging why a big vendor silently ignored API calls by hooking up MITM Proxy
Migrated a reasonable-sized JavaScript monorepo a couple years into the future (and built a time machine while doing that)
Was doing TLA+ models to verify time-based assumptions in an unstable distributed system environment.
Posts
Engineering @eng
TODO
Optimizing Emacs on macOS - Status Report
It's been more than 5 months since I started working on Emacs
optimization on macOS. This posts is a "check-in" because at this
specific moment I'm reasonably satisfied with its performance.
It is also, however, an explanation why I got to that point and what
I'm confident is a root cause of this behavior along with underlying
mechanisms for that.
+
title = "What the ADHD?"
date = "2023-05-07"
template = "page_toc.html"
draft = false
[taxonomies]
tags = ["adhd"]
[extra]
intro = "Following text covers ADHD exclusively and is a break-off from a longer text on related topic. While it can be read by anyone, it does have some engineering-related concepts and comparisons."
+
#+END_EXPORT
Caveat emptor
Without going into personal details — I have a stake in ADHD. I'm raising awareness and try to help those who have it — knowingly or not. Due to that I'm always on the lookout of new knowledge, ideas, techniques and tools.
It probably got its name directly from how fun that activity is. Years ago I heard description that something is like a chewing on a broken glass, but slightly less entertaining. It would fit.
#+END_EXPORT
I find it amusing that software engineers (or at least those I know) are very risk averse but paradoxically very optimistic about some topics. Complete trust in reliable network conditions is a belief that puzzles me often.
After frequent conversations about what is - and should - be considered “normal” reliability when passing messages between distributed systems I got bored with recalling (and repeating!) same examples.
+
title = "The Knob"
date = "2023-03-30"
template = "story.html"
draft = false
[taxonomies]
tags = ["fiction"]
[extra]
class = "knob"
+
#+END_EXPORT
I pressed play and sat as slightly coarse sound of a vinyl record filled the room. Compared to available technology quality was laughable at best, but it wasn't about the music for me. I don't know if that was true or not yet turning various knobs to get what I wanted felt great and precise. Lows, mids, highs; frequencies tuned exactly as I wanted.
When writing immediate mode (egui) applications it comes to me quickly that nigh all logic computations should be done off the UI thread. There are many ways to approach it, however as a fan of event-based systems sooner or later I implement some kind of event handling. The pattern is almost the same with minor differences and looks like this:
In case Brainf*ck name is too offensive, there is also Ook! Ook! language that uses pairs of Ook., Ook? and Ook! as operators. An example operators in Ook! Ook! is Ook! Ook. or another is Ook? Ook?.
I guess you can already see that I have some experience with esoteric languages.
Every LLM-backed tool I built started the same way: wire up an API client, handle key storage, paper over provider quirks. hn-jobs-evaluator had Gemini baked in. Next tool, same plumbing from scratch.
llmuxer is the extraction of that pattern into a 3-crate library.
llmuxer is the core: LlmConfig holds provider + key, builds a client, and exposes QueryBuilder and CacheBuilder via a fluent interface. Provider differences stay inside.
llmuxer-keystore persists configs so you’re not re-entering API keys across tools.
It’s been almost 20 years since I started working as a software engineer. Finding my next role has become excruciatingly difficult. If you’re looking for someone like me, my resume is linked - feel free to reach out.
I rarely sent out more than three applications. Usually, from those three that I sent, two resulted in interview invitations that converted to offers.
Today the reality is vastly different. Out of 20 applications I sent, and those were carefully selected - I don’t like going wide - only four resulted in initial interviews. None have led to an offer.
Monthly “Who’s Hiring” threads on HN are a mess to filter. Freeform text, dynamic ordering - keyword search misses half the relevant listings.
Good problem for an LLM. I built a Rust/egui app that fetches the thread, scores each listing against your resume and requirements via Gemini, ranks by fit.
The interesting design decision was the UI. Listings are long, evaluations are freeform, there are hundreds of them. CLI/TUI ruled out immediately - some descriptions wouldn’t fit a screen. A table with scrollable cells is quirky (scroll-in-scroll), but it’s the only layout that lets you skim fast without losing context. Everything else I tried either hid too much or required too many clicks to get anywhere.
Every software engineer worth their salt has lived through the static vs dynamic debate at least once. It’s a good debate to have, many times even. The arguments are well known but often tackled from different angles. At its core, however, it goes in a similar direction. Static types give confidence, ease of refactoring, guarantees. Dynamic types give flexibility, ease of use and no-fuss development. Both are equally successful at delivering software.
Every team has a code review process. Tickets move, PRs open, comments accumulate, something gets merged. The system looks like it’s working because the system looks like it’s working.
This is about what actually happens in the middle part – between “created” and “merged” – and the people doing it. You’ve worked with all of them. One of them is you.
The Pure Engineer
“Politics is for people who can’t write good code.”
I can’t overstate how much I hate GitHub Actions. I don’t even remember hating any other piece of technology I used. Sure, I still make fun of PHP that I remember from times of PHP41, but even then I didn’t hate it. Merely I found it subpar technology to other emerging at the time (like Ruby on Rails or Django). And yet I hate GitHub Actions.
Day before writing these words I was implementing build.rs for my tmplr project. To save you a click - it is a file/project scaffold tool with human readable (and craftable) template files. I (personally) use it very often, given how easy it is to craft new templates, by hand or with aid of the tool, so check it out if you need a similar tool.
CUE is the Swiss Army knife of file generation. It is the tool you grab when you need to generate complex JSON, validate YAML, or generally stop configuration files from ruining your life. It slices, it dices, it ensures your integers are actually integers. But guess what else it can be? It turns out, it is also a surprisingly effective Literate Programming tool.
This is important because, let’s be honest, the current king of this hill is org-mode. And while org-mode is powerful, it is also a bit of a golden cage. It works perfectly as long as you never leave the Emacs ecosystem. But the moment you try to export a workflow to a colleague who uses VS Code, you realize you have accidentally signed up for vendor lock-in. You want your documentation - your “literate code” - to be portable, not a magic spell that only works inside one specific editor.
They say the definition of insanity is doing the same thing over and
over again and expecting different results. In software engineering,
we call this “benchmarking.” Or, in my specific case, “rewriting a
template utility four times because I am spiritually incapable of
settling.”
The goal was simple. Deceptively so. I wanted a tool called tmplr. Its
job? To take a template, sprinkle in some variables, and spit out a
file. It is the sort of task that a shell script could do if you
didn’t value your sanity, or that Python could do if you didn’t value
your startup time.
// make_tool.cue
package main
import (
"tool/file"
)
files: {}
command: make: {
for k, v in files {
"\(k)": file.Create & {
filename: k
contents: v.contents
}
}
}
This is a quick boilerplate for Cue lang to start producing (text) files.
That way one can create many (consistent!) files from a single Cue file/package by using
cue cmd make. As an example - I use it to generate Pikchr diagrams
wrapped in Markdown:
If you’re one of my 3 stalkers (HEY Y’ALL!), you might’ve noticed that
I started to write about Haskell recently. If not, well you know now
:)
Haskell is a nice language in a way that it teaches one (i.e. me) a
new tricks. Tricks from Haskell that I started started wrtiting a
piece about. I’m at the trick of small functions but I also recently
read an interesting article with which I don’t (in general) agree and
decided to follow on –1Small functions
considered harmful.
This is a description of recently released
MicroDiagram prototype. Check it out if you
haven’t yet. It’s mostly technical and discusses some of the challenges
I faced, as it was my first Haskell project.
Moving Parts
Backend - single binary written in Haskell, consisting of
I’ve been working on a specific idea for some time - microdiagrams
DSL. The core concept is quite straightforward: instead of having one
language for all diagrams, have multiple languages for various
purposes. For example, this diagram is designed to help learn piano by
illustrating the relationship between different keys.
This idea had multiple prototypes. I won’t get into the details why
(hey, I hope to make some money out of it someday!), but I’ve
entertained the same idea for quite some time. One would say that
technology doesn’t matter, but I disagree. I think that for side
projects (or Magnum Opus for that), one shouldn’t use boring
technology.
Recently I thought that writing about Cuelang and thought “hey,
wouldn’t it be nice if I could put some Cue code into Org and
evaluate it so that I could showcase the result”?
Well, it’s a shame ob-cuelang doesn’t exist. However, thanks to the
LLMs I could vibe code it, right? And so, I steeled my nerves, thought hours about the prompt and, after
30 minutes and 2 glasses I put nervously:
As I’m juggling languages often there are those which I like more or
less and it fluxuates over the period of time. I figured out it might be
good idea to put on (virtual) paper why I find language attractive.
This one is stupid. I have an idea for parser and I even have a proof
of concept working in CLIPS1. Given my search it seems it
something like recursive-descend parser, but I’m not sure if it
qualifies.
If you know drop me an e-mail please.
Pre-word
I will use Lisp-like syntax, but this has no implementation except for
aformentioned CLIPS, and is more about data structures and logic.
When I write about rune I mean rune as per in Go language, aka a
codepoint. Token is one of (I’m still considering full grammar):
September 20th, 2025 marks exactly one year since I bought Roland’s
FPX-30, 88-keys full sized digital piano. Being in my 4th decade of
life I never taught myself any instrument, even though I own and dabble with many.
In fact, while I’m unable to remember sounds or hear them in my head,
it seems I have a rather good understanding what “sounds nice” that
allows me to ad-hoc compose music.
Is free will an illusion? For centuries, this question has felt like a philosophical deadlock. Arguments often get stuck trying to define consciousness or find a “ghost in the machine.” But what if the problem isn’t how we see ourselves, but an outdated way of seeing the universe?
This isn’t another abstract philosophical argument. It’s a practical case built on two of the most powerful tools we have for understanding reality: statistics and physics. The goal isn’t to “prove” free will directly, but to dismantle the one argument that insists it’s impossible.
Doing some Zig, doing some Go, some Janet. Some C integration. Should have focused on my project but life threw more at me than I could handle, so I sought… happy distractions.
My experience with those technologies taught me new tricks and one day, when I needed some more distraction, I decided to debug something that had made me furious for years: Emacs jank1.
One thing that really annoyed me at the beginning of my adventure with Prolog was when THIS happened:
?- between(1,3,A).
A = 1 █ <- blinking cursor
I couldn’t understand Why Prolog wouldn’t produce all the solutions? It felt so obvious, that A can have 3 different results.
When working with predicates (fancy name for function as far as I am concerned), they not only produce value as in the other programming languages. They can produce something along the lines of “hey, here’s a result, but you know, I have more, so get back to me if you want, m’kay?”.
I find it amusing that software engineers (or at least those I know) are very risk averse but paradoxically very optimistic about some topics. Complete trust in reliable network conditions is a belief that puzzles me often.
After frequent conversations about what is - and should - be considered “normal” reliability when passing messages between distributed systems I got bored with recalling (and repeating!) same examples.
So I designed cheat sheet to look at when planning for systems interactions.
It probably got its name directly from how fun that activity is. Years ago I heard description that something is like a chewing on a broken glass, but slightly less entertaining. It would fit.
Some time ago I was tasked with upgrading libraries for a medium-sized project. It wasn’t legacy by any means, as dozens of developers divided between the teams were working on it daily. I wouldn’t describe structure as trivial. It was neatly split into parts which kept dependencies between them and had adequate volume of source for the role it was fulfilling.
Without going into personal details — I have a stake in ADHD. I’m raising awareness and try to help those who have it — knowingly or not. Due to that I’m always on the lookout of new knowledge, ideas, techniques and tools.
My knowledge is based on personal experience, accounts of those diagnosed and pre-diagnosed, conversations with therapists but also taken from the books and internet sources such as published research, info-sites or (rarely) popular publications.
Mickey Petersen wrote nice piece about compile feature in Emacs - something I use a lot and I recommend the read.
I like to have instant feedback, so I use it for almost everything after which run recompile that replays last compile command. recompile can be bound to the key, but my favorite trick is to use Local Variables.
Mickey Petersen wrote nice piece about compile feature in Emacs - something I use a lot and I recommend the read.
I like to have instant feedback, so I use it for almost everything after which run recompile that replays last compile command. recompile can be bound to the key, but my favorite trick is to use Local Variables.
Thanks for accepting my invite. Don’t worry, this will be short. I have a places to be, people to… educate. So I’ll have to run soon.
I took the liberty and ordered for both of us. Steak & salad. Good, right?
See, I’m with the Company. Yeah, …that one. We serve your coffee, we make your cereal, we provide you with social entertainment and all this other boring stuff. I do, however, always find it amusing that the same company can produce toothpaste and at the same time be a supplier of network cable for a city.
Thanks for accepting my invite. Don’t worry, this will be short. I have a places to be, people to… educate. So I’ll have to run soon.
I took the liberty and ordered for both of us. Steak & salad. Good, right?
See, I’m with the Company. Yeah, …that one. We serve your coffee, we make your cereal, we provide you with social entertainment and all this other boring stuff. I do, however, always find it amusing that the same company can produce toothpaste and at the same time be a supplier of network cable for a city.
For the last few months I was very unhappy with my iPhone 13 Pro battery.
It was discharging way too quick. How quick? After 10 hours after unplugging I usually got “battery low” alert. I didn’t feel my usage throughout the day would be enough explain it.
I tried to troubleshoot it, but to no avail. The only hint I got was “Find My” app, that was using 100% of the battery when inspecting part of the available battery slope. I tried various strategies but wasn’t able to fix it.
For the last few months I was very unhappy with my iPhone 13 Pro battery.
It was discharging way too quick. How quick? After 10 hours after unplugging I usually got “battery low” alert. I didn’t feel my usage throughout the day would be enough explain it.
I tried to troubleshoot it, but to no avail. The only hint I got was “Find My” app, that was using 100% of the battery when inspecting part of the available battery slope. I tried various strategies but wasn’t able to fix it.
Blackboxing of React Component is a (self-named) process that I use in order to separate visual component from the logic layer.
As a refresher - visual components are the type of components which role is to “look nice”. They can have some logic inside, but ultimately they’re dumb. They don’t reach out for data, they don’t handle complex state changes, however they can render different elements reacting to props changes. Components that have complex logic in them are usually named Controller Components or Logic Components. While it’s a very good idea to aim for such separation, real life project have this line blurred.
Blackboxing of React Component is a (self-named) process that I use in order to separate visual component from the logic layer.
As a refresher - visual components are the type of components which role is to “look nice”. They can have some logic inside, but ultimately they’re dumb. They don’t reach out for data, they don’t handle complex state changes, however they can render different elements reacting to props changes. Components that have complex logic in them are usually named Controller Components or Logic Components. While it’s a very good idea to aim for such separation, real life project have this line blurred.