First craft a language then build your software

Babel Tower

A language suit for purpose enables us to express our thoughts clearly and concisely. In programming, this language consists of our actual programming language, the libraries we use, and the abstractions we build. I believe that most of the incidental complexity in code stems from an unsuitable language. A misfit language forces you to speak in a lengthy and roundabout way, never quite getting at what you actually want to say.

Imagine you lacked the word "snow" and had to always say "white, fluffy, crystalline, frozen water". Now imagine you are writing instructions for waxing of cross-country skiis and you lack the words for snow, skiis, and the different kinds and states of snow. How verbose and incredibly hard to understand that would be! And this is exactly how most of our code looks. As Alan Kay puts it: "Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves." [Kay] Let’s explore this idea further.


Continue reading →

My year 2022 in review

2022 has been a busy year both geopolitically ❤️🇺🇦 and locally. I have done a ton of Fulcro, played with Rust, got into managing projects and people.

This is my first whole year in Ardoq and I am still loving it. I came to fullfil my dream of being full-time Clojure developer and (aside of that, because I still love Clojure!) I am staying for the friendly, open "big family" culture and awesome people. I started the year by working on our slow, stepwise transition from Mongo to Postgres (I still might one day write about why we sadly did not pick Datomic in the end 😭). It was an important and exciting task. As changing the DB your business is built on, while everything keeps running, always is. Later I took over one of our teams, helping it deliver faster, smaller, more frequently. I have also been pulled into hiring and people management, which is not as much fun as Clojure but is far more important. I still have a great deal to learn here.


Continue reading →

Fulcro Lesson: Detached Root Component (Form)

I am working on a Fulcro RAD application and want to display a RAD Form in a popup, to create a new customer for an order I am making. Normally Fulcro components are "composed all the way up to the root," including their query in the parent’s and getting their props from the parent. But that does not make sense here - I want a detached form I can pop up, fill, close, and go back to editing the order. I wasn’t able to figure out how to compose this without help and thus want to record the solution.


Continue reading →

Clojure is in fact a trinity - of language, interactive development, and structural editing

You can never really learn Clojure if you only focus on the language. Why? Because Clojure is in fact a synergetic combination of three things: the language itself, a way of working centered on interactive development, and structural editing support in editors for manipulating the code safely and efficiently. You cannot get the full benefits of Clojure unless you embrace all three.


Continue reading →

PostgreSQL: From JSON to table and back

I have a jsonb column in Postgres and I would like to update parts of it based on some other parts of the value. In Clojure I would have used update, which does new-value = f(old-value). How can I achieve something similar - i.e. deriving the new value from the old one - in Postgres? It turns out I can, with the help of a temporary table and jsonb_to_recordset that can turn a jsonb value into a table and row_to_json + jsonb_agg that can turn that back to jsonb. Let’s see how it works.

The data

I have a table called report with the primary key _id and jsonb column columns. It looks like this:

Table 1. Table report
_idcolumns

123

[{"key": "name", "type": "field", "label": "Name"}, {"key": "Supports", "type": "reference-type-outgoing", "label": "Supports"}, …​]

456

[{"key": "name", "type": "custom", "label": "Name", "dataType": "Text", "sort": "ASC"}]

789

[]

Notice that the objects in the array may have different keys.

What I want to do is to update every column of the type reference-type-outgoing or reference-type-incoming by appending the direction - outgoing or incoming - to the key. F.ex. the column above would become {"key": "Supports—​outgoing", "type": "reference-type-outgoing", …​.


Continue reading →

Signing git commits with a ssh key using 1Password

The Sign your Git commits with 1Password post is really useful but it does not tell you how to verify that signing works, how to troubleshoot it, or how to make it possible to verify the signatures locally. I will explain that here. The short story is that you need to set up gpg.ssh.allowedSignersFile and add your key there to be able to use git log --show-signature.

First of all, the setup as described in the blog post works and you can display the signature after having made a commit with git show --pretty=raw - notice the line with gpgsig …​ and those below it:


Continue reading →

Using React.forwardRef in Fulcro (and rendering a Fulcro component from a JS one)

How (and why) do you use React.forwardRef in Fulcro? Let’s first explore ref. When you need access to the raw HTMLElement in React - f.ex. to call .focus on it - you need to create a Ref object[1] (similar to Clojure’s atoms) and pass it to a React DOM element such as dom/div via the magical property :ref. React will then do something like "(reset! <the Ref> <the raw element>)" so that you can access the raw element in your code: (some→ <the Ref> .-current .focus). The :ref property is magical in the regard that it is "consumed" by React itself and not passed to the component. But what if you make a custom component and want it to be able to take a Ref object to attach it to its child DOM element? The simplest solution is to pass it under any other name than the reserved ref, which is exactly what this Fulcro examples does, using the custom :forwarded-ref. However some 3rd party higher-order components insist on passing the Ref down using the reserved ref property name. To make it possibly, React invented forwardRef:

const FancyButton = React.forwardRef((props, ref) =>
  (<button ref={ref} className="FancyButton">{props.children}</button>));

const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

Continue reading →

The trouble with list components in Fulcro

Imagine you have a list of things to display in your UI. You naturally want to represent them with a list component, such as a TodoList. But that is not the way we do it in Fulcro, which beginners find confusing (I did). Here I explain why and what are the alternatives.

Still new to Fulcro? Make sure to check out my Minimalist Full-Stack Fulcro Tutorial!


Continue reading →

Code Study: Making code more functional

Having a pure function, what makes it more or less "functional" (as in "functional programming")? To me, "functional" includes favouring higher-level constructs over low-level "bit twiddling". Here I would like to demonstrate how I made one function more functional in this regard.


Continue reading →

Fulcro Troubleshooting Decision Tree

A decision tree to help you go from a problem to the most appropriate troubleshooting steps.


Continue reading →

My year 2021 in review

My professional year 2021 has been a year of Fulcro and Clojure. I have finally become a full-time Clojure developer and I have created a ton of resources for Fulcro beginners to ease and speed up their onboarding. To help them even more, while respecting the preciousness of time, I have started my company Holy Dev to provide mentoring and pair-programming to Fulcro learners. And I have written a few more essays about productivity and concepts such as simplicity on this blog.


Continue reading →

Awesome Babashka: Parse & produce HTML and SQLite

Babashka is a lightning-fast Clojure scripting tool with batteries included. It provided almost everything I needed to turn an AsciiDoctor document into a SQLite database and HTML in the format Dash - the offline documentation browser - requires to use it as a navigable, searchable "docset". While Babashka offers a lot out of the box, it can be further extended leveraging a number of available "pods" or extensions. This is a brief story of how I used Babashka to glue together Hickory, Selmer, and SQLite to make my html2dash.bb script.


Continue reading →

A light exploration of collaborative editing and synchronization algorithms

An important feature of Ardoq is that multiple users can edit the same model, i.e. a directed multi-graph. Changes from one user need to be propagated to the others and merged into their models. Collaborative editing (primarily of text) has reportedly been researched for 30 years and is still under active development. Here I share my field notes from learning about it briefly, without much tidying.


Continue reading →

What is simplicity in programming and why does it matter?

Slide from Simple Made Easy: Benefits of Simplicity, t=00:21:30

When I started with Clojure, I saw a language. Some people, when they look at it, they only see a weird syntax. It took me years to realize that in truth Clojure is a philosophy. The language embodies it, the ecosystem embraces it and grows from it, you the developer eventually soak it up.

The philosophy is simplicity - on a very profound level - and, to a lesser degree, ergonomics [1]. What do I mean by simplicity and ergonomics? Simplicity is about breaking things apart into their elementary constituents that are orthogonal to each other. Ergonomics is about making it possible and convenient to combine these elements in arbitrary, powerful ways. You end up with simple things that have single responsibility and that you can combine freely to suit your unique needs. These elements are simple but also generic and thus applicable in many situations and usable in many ways. This is crucial also for flexibility:


Continue reading →

Clojure is frustrating... and it is a good thing

n 2016, the Clojure core team announced Clojure Spec, the most important addition to Clojure since v1.0.0. Spec allows you to describe and verify the shape of data (and much more) in a somewhat unique way. Having experienced developing a webshop from scratch in the dynamically typed JavaScript/Node.js, with the code growing in complexity and team in size, I very much appreciated the value of describing and checking data against a schema at important points of the program (without being swamped by doing it everywhere). In 2018 Rich Hickey in his talk Maybe Not discussed some shortcomings of Spec - some of which I have experienced personally - and work on Spec 2 started to address those and some limitations. I was fired up because Spec was great - and Spec 2 seemed to be perfect. I waited, and waited, …​ and waited. It is 2021 and Spec 2 is still nowhere in sight. That is truly frustrating. Similarly it has been with other design developments in Clojure such as named arguments. And it is, despite all my frustration, very, very important that it is this way.


Continue reading →

Copyright © 2023 Jakub Holý
Powered by Cryogen
Theme by KingMob