Planet Scheme

Wednesday, September 20, 2023


Pull-requesting the enemy

I was just about to email a maintainer of a repo about some programming stuff but then I realized that the guy was a denier of the mass incarcerations in Xinjiang. 🤦🏻‍♀️

In the 90s, 00s I wouldn’t’ve hesitated one second to work on code with someone with political differences. I thought it was a good thing that there were areas in life like code and boardgames where we could cooperate without harming each other.

But it feels like politics have gotten so extreme. It used to be that the enemy were the “no we wanna lower taxes for the rich” and now it’s all “no we’re about to annihilate such-and-such minority”.

To be fair, it’s not just the world that’s changed. I’ve changed too.

I was the one with extreme politics—at the time I was ancom, vegan, copyright abolitionist—so I was used to living & coexisting in a world where almost no-one agreed. But now I’ve finally bubbled up and echo-chambered-up enough that I can be in a place where eating plants and copying tapes is not seen as weird. That makes “working with the enemy” less of an everyday thing and more of a stretch.

I sometimes wish I could get back to the mindset of working with everyone, by somehow making a large enough disclaimer that I disagreed or whatever.

But, again, it’s not just me. Even back then there were lines I would never cross, and these days FOSS is so big that people way beyond those lines are running repos. Not happy about that.

by Idiomdrottning ( at Wednesday, September 20, 2023

Saturday, September 16, 2023

okdb - 1 - prologue

A better database paradigm is the enemy of good, a perfect database is the enemy of better; on-the-fly mainstreaming commons legacy is future-proof operative.

While there is no shortage of database systems, there used to be none that met my expectations. I can think of the following requirements:

  • Can write, and read the following structures:
    • relational, graphical
    • recursive, hierarchical
    • time, spatial, geometric
    • textual
  • Support efficient:
    • pagination
    • versioning
    • horizontal scaling
    • down scaling
  • Support ACID transactions across objects
  • Programmable with Turing-complete programming language

We will argue that one or more of those requirements are unnecessary, and overkill. DWMT. NIH. YAGNI. DRY. We will argue that by relaxing a few of the requirements, a particular software or a set of vendors can bridge the chasm. We will argue endlessly, and we will be building hedera ivy, yet-another-database, wheel re-invention, pollution, the heresy of my diluted genius, that curse the software industry with fragmentation diversity, and fatigue jails. We will mention UNIX, respect, enterprise software architectures, open, free, available, sources, transparent, experiences, know-hows, failures, patterns, bugs, wars, fixes, success, huts, hugs, hubs, stories, productions, uses, re-uses, decades^W centuries^W milleniums of goods, but proof-of-work of maintreaming commons legacy.

Stand up, and still, I boost a grown up trend.

OKVS are used in Software as a Service (SaaS), privateer honeypots, source available software programmed with long now C++, Java, C#, JavaScript, Scala, Go, Zig, Rust, Python, Clojure, Common Lisp, and Scheme.

You have already used an Ordered Key-Value Store.

You know about the components that make an OKVS. If you are a software engineer, you will not learn algorithms, or new structures. You will re-discover how to use, and re-use readily available knowledge to better what you do in a way that is logical, that make sense in your target environment, product, and whatever your varia vocable.

Ordered Key Value Stores are useful, usable, and used.

Is it an expert tool? Is it an acceptable tool? Are problems of yesterday, today, and tomorrow fixed, or some require the precise craft of engineering art?

If the Revised-1 Report on Kernel is the language of programmable programming; then OKVS is the language of programmable storage.

Caveat emptor: you think in terms of specific, more or less precise, tailored, ad-hoc, prolly re-usable wording. You answer questions such as: what problem do I want to solve? Along the transderivational process, you log the most fitting, under, and over fitting representations; you plan, exercise read, and write workloads, record time, the flow of volatile, and permanent space usage, draft what happens sub-second, shorter than the span of human awareness, and the other side of the continuum: operations that have eventually a long while.

Look to tell a good story.

To ease the reader perfect skills, re-new old ideas, the essence of OKVS paradigm, the reference will also be illustrated with the help of LaTeX to limit, and hopefully eliminate dubious derivations. First, the goal is to cover as much substance as possible to give the freedom to think. Then with convos put the user interface to the test with well-known human interactions.

It helps to give yourself the opportunity to do it, in the most fitting order try to: think, exercise, solve, code, rest, sleep, and have fun.

Lost pea boat by INnovaTion at
Lost pea boat by INnovaTion at

Saturday, September 16, 2023

okdb - 0 - natural query

Ordered Key-Value Store has a small user interface that give us another good good reason to have a look at processing, memory, permanence, and pointer swizzling.

A useable database must offer the following actions:

  1. set will store a piece a data;
  2. query will retrieve zero or more piece of data;
  3. delete supposed to do what you think it will, but you will not use it, and even when you do, it will just acknowledge you made a wish;

The primary question that comes to mind is: what is a piece of data?

In the OKVS paradigm, “piece of data” has two parts: the key, similar to what LISP call car, and the value, similar to what LISP call cdr. So set may be described with set(car, cdr), in more parenthetical terms (set object other)1. In an OKVS, key, and value, respectively car, and cdr, or object, and other, are sequences of ones and zeros2. The user interface of the OKVS paradigm use bit low level data representation.

Data that is binary sequences is a clue into why OKVS is fractal.

We know what is a piece of data: two bit sequences called key, and value. The database is a list of associations between a key, and a value. At any given point in time, given a bit sequence, it can only be associated once, and only once to another bit sequence.

Let’s consider a procedure that would be called get. One must divine that get is a shortcut to (get key) that returns, if any, the value that was associated with key using (set key value).

Comes query.

To be an interesting user interface action, query must subsume get3. The procedure get will read, and return something, if any. The procedure query will also read, and return nothing, return something , and opt-in to return strictly more than one thing. If there is at least two results, one should consider what comes first, what comes next, and if any what comes last... That is why there is an O in OKVS. We want to specify a sorting strategy. The procedure query returns paired bit sequences in their natural order4. To cover all use cases, the sorted subspace returned by query is described using two bit sequences called start, and end.

That is why OKVS is fractal.

Sunflowers turning into a white circle over a dark background, and morph to sunflowers in what appears like a (wanna be (infinite)) loop.
Sunflowers turning into a white circle over a dark background, and morph to sunflowers in what appears like a (wanna be (infinite)) loop.

Saturday, September 16, 2023

code crafting codex

A problem can have several solutions. A solution can have different implementations each of which with their own strengths and weakness in terms of space, time and generality.

The goal of a code experience design is to optimize the cognitive effort required to understand, learn and use. Otherwise said, code usability aim to improve ease.

While looking for ease, one might trade it over expressive power.

Crafting an experience requires to understand the cognitive load associated with the production. Cognitive load theory has been designed to provide guidelines intended to assist in the presentation of information in a manner that encourages learner activities that optimize intellectual performance.

Here is some of those guidelines:

  1. People learn more effectively when they can build on what they already understand;
  2. Take advantage of schemata;
  3. Take advantage of visual thinking and other non-verbal thought;
  4. The average person can retain only seven five chunks of information in short-term memory;


Saturday, September 16, 2023

cheatsheet on discourse

Screenshot from inanimate alice, perpetual nomads. Available at

Do not share, what you do not want to be known

The three gates of speech

Before you speak, let your words pass through three gates.

  • At the first gate, ask yourself, is it true.
  • At the second gate ask, is it necessary.
  • At the third gate ask, is it kind.

Rogerian rhetoric

You should attempt to re-express your target’s position so clearly, vividly, and fairly that your target says, “Thanks, I wish I’d thought of putting it that way.”

  • You should list any points of agreement (especially if they are not matters of general or widespread agreement).

  • You should mention anything you have learned from your target.

  • Only then are you permitted to say so much as a word of rebuttal or criticism.

Dennett’s version of Rapoport’s Rules

Argument Ranking

  • ●●●●● - High-level generators - Disagreements that remain when everyone understands exactly what’s being argued, and agrees on what all the evidence says, but have vague and hard-to-define reasons for disagreeing.

  • ●●●●○ - Operationalizing - Where both parties understand they’re in a cooperative effort to fix exactly what they’re arguing about.

  • ●●●○○ - Survey of evidence - Not trying to devastate the other person with a mountain of facts and start looking at the studies and arguments on both sides and figuring out what kind of complex picture they paint.

  • ●●●○○ - Disputing definitions - Argument hinges on the meaning of words, or whether something counts as a member of a category or not.

  • ●●○○○ - Single Studies - Better than scattered facts, proving they at least looked into the issue formally.

  • ●●○○○ - Demands for rigor - Attempts to demand that an opposing argument be held to such strict standards that nothing could possibly clear the bar.

  • ●○○○○ - Single Facts- One fact, which admittedly does support their argument, but presented as if it solves the debate in and of itself.

  • ●○○○○ - Gotchas - Short claims that purport to be devastating proof that one side can’t possibly be right.

  • ○○○○○ - Social shaming- A demand for listeners to place someone outside the boundary of whom deserve to be heard.

“How to apologize: Quickly, specifically, sincerely.”, by Kevin Kelly

Arguments category

  • Ad baculum : Argument relying on an appeal to fear or a threat.
  • Ad ignorantiam : Argument relying on people’s ignorance.
  • Ad populum : Argument relying on sentimental weakness.
  • Ad verecundiam : Argument relying on the the words of an “expert”, or authority.
  • Ex silentio : Argument relying on ignorance.
  • Ex nihilo : An argument that bears no relation to the previous topic of discussion.
  • Non sequitur : An inference that does not follow from established premises or evidence.


  • Akrasia : State of acting against one’s better judgment.
  • Connotation : Emotional association with a word.
  • Intransigence : Refusal to change one’s views or to agree about something.
  • Inferential distance : Gap between the background knowledge and epistemology of a person trying to explain an idea, and the background knowledge and epistemology of the person trying to understand it.
  • Straw man : Creating a false or made up scenario and then attacking it. Painting your opponent with false colors only deflects the purpose of the argument.
  • Steel man : To steelman is to address the strongest possible variant or the most charitable interpretation of an idea, rather than the most available phrasings.
  • Red herring : A diversion from the active topic.
  • Rationalization : Starts from a conclusion, and then works backward to arrive at arguments apparently favouring that conclusion. Rationalization argues for a side already selected.
  • Dogpiling : A disagreement wherein one person says something wrong or offensive, and a large number of people comment in response to tell them how wrong they are, and continue to disparage the original commenter beyond any reasonable time limit.
  • Grandstanding : An action that is intended to make people notice and admire you, behaving in a way that makes people pay attention to you instead of thinking about more important matters.
  • Whataboutism : An attempt to discredit an opponent’s position by charging them with hypocrisy without directly refuting or disproving their argument.
  • Dissensus : The deliberate avoidance of consensus.


  • Belief : The mental state in which an individual holds a proposition to be true.
  • Priors : The beliefs an agent holds regarding a fact, hypothesis or consequence, before being presented with evidence.
  • Alief : An independent source of emotional reaction which can coexist with a contradictory belief. Example The fear felt when a monster jumps out of the darkness in a scary movie is based on the alief that the monster is about to attack you, even though you believe that it cannot.
  • Proper belief : Requires observations, gets updated upon encountering new evidence, and provides practical benefit in anticipated experience.
  • Improper belief : Is a belief that isn’t concerned with describing the territory. Note that the fact that a belief just happens to be true doesn’t mean you’re right to have it. If you buy a lottery ticket, certain that it’s a winning ticket (for no reason), and it happens to be, believing that was still a mistake.
  • Belief in belief : Where it is difficult to believe a thing, it is often much easier to believe that you ought to believe it. Were you to really believe and not just believe in belief, the consequences of error would be much more severe. When someone makes up excuses in advance, it would seem to require that belief, and belief in belief, have become unsynchronized.
  • A Priori : Knowledge which we can be sure of without any empirical evidence(evidence from our senses). So, knowledge that you could realize if you were just a mind floating in a void unconnected to a body.


“A leader is best when people barely know they exists, when their work is done, their aim fulfilled, people will say: we did it ourselves.”

— 老子 (Lao Tse), 道德經 (Dao De Jing)

Wikipedia’s etiquette

The first principle of Wikipedia etiquette has been said to be Assume Good Faith, also they Be Bold, but not Reckless.

Wrong discourse

  • Answer: Jumping into a conversation with endless unapplicable, unrealistic or unrelated answers to the question.
  • Question: Spouting accusations while cowardly hiding behind the claim of just asking questions, and ignoring the answers. Asking loaded questions.

Good discourse

  • Answer: A clear and honest response to the central point of a question without an aggressive attempt to convince.
  • Question: question asked with the intention to be fair, open, and honest, regardless of the outcome of the interaction.

Social rules are expected to be broken from time to time, in that regard they are different from a code of conduct.

Response Ranking

  • ●●●●●● - Central point - Commit to refute explicitly the central point.
  • ●●●●●○ - Refutation - Argue a conflicting passage, explain why it’s mistaken.
  • ●●●●○○ - Counterargument - Contradict with added reasoning or evidence.
  • ●●●○○○ - Contradiction - State the opposing case, what.
  • ●●○○○○ - Responding to Tone - Responding to the author’s tone, how.
  • ●○○○○○ - Ad Hominem - Attacking the author directly, who.

Interaction Ranking


  • ●●●●● - Release - Initiating a discussion on the lessons learnt from a project.
  • ●●●●○ - Update - Presenting the recent development of a personal experience, ongoing event or work in progress.
  • ●●●○○ - Soapbox - Spontaneous and or enthusiastic posts about a general topic of interest or finding.


  • ●●○○○ - Rant- Venting frustration publicly without explicitly looking to have a conversation about the matter.
  • ●○○○○ - Shitpost - Aggressively or ironically looking for the biggest reaction with the least effort possible. Includes subtoots and vague-posting.

Emotional Reaction

  • Seduction - You are led to feel that the fulfillment of your dreams depends on your doing what the other is encouraging you to do.
  • Alignment - The interests of the system are presented as fulfilling your emotional needs. You are led to feel that your survival, your viability in society or your very identity depends on your doing what the other is requiring of you.
  • Reduction - Complex subjects are reduced to a single, emotionally charged issue.
  • Polarization - Issues are presented in such a way that you are either right or wrong. You are told that any dialogue between different perspectives is suspect, dangerous or simply not permissible.
  • Marginalization - You are made to feel that your own interests (or interests that run counter to the interests of the other) are inconsequential.
  • Framing - The terms of a debate are set so that issues that threaten the system cannot be articulated or discussed. You are led to ignore aspects of the issue that may be vitally important to your own interests but are contrary to the interests of the other that is seeking to make you act in their interests.


  • “Kings speak for the realm, governors for the state, popes for the church. Indeed, the titled, as titled, cannot speak with annyone.” — James P. Carse, Finite and Infinite Games

  • “Instead of trying to prove your opponent wrong, try to see in what sense he might be right.” — Robert Nozick, Anarchy, State, and Utopia

  • “You should mention anything you have learned from your target.”

  • “I don’t argue: I just say what I know or what I believe, as the case may be.” — John W. Cohan


The whole page is licensed under cc-by-nc-sa; it is adapted from to make it easier for me to change it. I also avoid the words “bad” (replaced with “wrong”) and “faith” (replaced with “discourse”), a few other changes.

Saturday, September 16, 2023

Thursday, September 14, 2023


My email setup

On the server side, it’s pretty vanilla. Postfix, Dovecot, SpamAssassin, WKD.

On the client side, I use mbsync and notmuch and I have a ton of automatic filters via nmsync.

Everything that those filters label with feed I read in a feedreader instead of an email app thanks to nmatom. I can check in on those newsletters once per day. No stress. And they’re not getting tangled up in my personal business, they don’t trigger notifications, they don’t require responses, they show up when I have time to read ‘em etc. Pretty great.

I also have the opposite, thanks to rss2email; I have one RSS feed (janitorial type news from inside my building) that are so urgent that I get them in my email client.

Speaking of email client, I also use Delta Chat. It and mbsync read from the same imap store, they don’t read from each other.

Delta Chat is great as a biff replacement (a classic mail notification app from decades ago—that’s right, biff only did notifications) that can also bang out a quick reply.

But Delta Chat has some limitations, which is when I go to my other mail app, which is the Emacs interface to notmuch. Here are some of those limitations:

  • Starting a new thread: this is possible on Delta Chat but it’s a hassle. Even more so if I don’t already have the mail address added
  • Writing long emails: short messages have their charm but sometimes a long one can be a good time for those deep topics and that’s where Emacs shines
  • Applying incoming patches to my repos: way easier with notmuch
  • Sending encrypted email: Delta Chat can show me my GPG or WKD email just fine but the only keys it can encrypt to are Autocrypt keys (and it can send unencryptedly to non-PGP people). So for encrypted convos to non-autocrypters, I have to switch to notmuch, which is fine, I just need to remember which is which, and that’s not great
  • When I need to top-post: pre-September geeks hate top-posting but some systems and bots require it, so when I deal with them I must go into notmuch

Delta Chat also can’t block users that send to multiple senders. Which is bonkers. It thinks it’s in “mailing list mode”.

Which sucks since I have a monthly bill/invoice that I didn’t even have to see when I was on all notmuch. I had nmatom stash away the bill, then alert me if the invoice wasn’t autopaid within a few days. But with Delta Chat, I can’t hide it because it thinks it’s in mailing list mode. It can’t even mute the thread since every month has a new ID in the subject.

Why do I even use Delta Chat?

Becaue the notification sitch on tablets suck. When I was at my desk all day I had a great all-notmuch setup. Now that I spend most days in bed, I wanna get pinged when I get email and there’s not an easy way to set up notifications. It’s same on Android tablets and iPad tablets—I started this on Android and just kept going with the exact same combo (Delta Chat + an SSH app) on iPad OS.

Also I was fast at email but that has been kicked up a li’l notch with Delta Chat.

How do I inbox zero?

I don’t use email to keep track of things I need to do. Instead, I paste things into a separate todo app. The email is never the reminder. That’s how I do it. There are other ways that might make sense for those whose work is primarily email-driven, but for the past few years I’ve only been using an external todo app to keep track of anything I don’t wanna get to right away. (But since my filters sort newsletters from conversations for me, there’s not a lot of further processing I’d need to do on my inbox.)

A few years ago I did have a couple of notmuch tags specific for this, and scripting & shortcuts to work with them and extract them to other systems. I had:

  • Waiting-for, for stuff where I was waiting for them (and might need to check in),
  • reply, where I was just procratinating on replying (and that sort of separation of processing from doing can sometimes be appropriate),
  • todo, where I needed to do something external before I can reply,

and I was also using a system to delay, or snooze emails and they’d return later

But these days I do none of that. I work from the todo app, not from the mail app. Mail isn’t anything special in that regard: I can add stuff to the todo inbox from mail, from fedi, from rss, from web pages, from a picture, from notes and mindmaps, from dreams or phonecalls.

I go into my mail apps to read & write mail. That works for me right now. 🤷🏻‍♀️

by Idiomdrottning ( at Thursday, September 14, 2023

Tuesday, September 12, 2023

GNU Guix

A new Quality Assurance tool for Guix

Maintaining and expanding Guix's collection of packages can be complicated. As a distribution with around 22,000 packages, spanning across around 7 architectures and with support for cross-compilation, it's quite common for problems to occur when making changes.

Quality Assurance (QA) is a general term to describe the approach taken to try and ensure something meets expectations. When applied to software, the term testing is normally used. While Guix is software, and has tests, much more than those tests are needed to maintain Guix as a distribution.

So what might quality relate to in the context of Guix as a distribution? This will differ from person to person, but these are some common concerns:

  • Packages successfully building (both now, and without any time bombs for the future)
  • The packaged software functioning correctly
  • Packages building on or for a specific architecture
  • Packages building reproducibly
  • Availability of translations for the package definitions

Tooling to help with Quality Assurance

There's a range of tools to help maintain Guix. The package linters are a set of simple tools, they cover basic things from the naming of packages to more complicated checkers that look for security issues for example.

The guix weather tool looks at substitute availability information and can indicate how many substitutes are available for the current Guix and system. The guix challenge tool is similar, but it highlights package reproducibility issues, which is when the substitutes and local store items (if available) differ.

For translations, Guix uses Weblate which can provide information on how many translations are available.

The QA front-page

Then there's the relatively new Quality Assurance (QA) front-page, the aim of which is to bring together some of the existing Quality Assurance related information, as well as new being a good place to do additional QA tasks.

The QA front-page started as a service to coordinate automated testing for patches. When a patch or patch series is submitted to, it is automatically applied to create a branch; then once the information is available from the Data Service about this branch, the QA front-page web interface lets you view which packages were modified and submits builds for these changes to the Build Coordinator behind to provide build information about the modified packages.

QA issue page

A very similar process applies for branches other than the master branch, the QA front-page queries to find out which branch is going to be merged next, then follows the same process for patches.

For both patches and branches the QA front-page displays information about the effects of the changes. When this information is available, it can assist with reviewing the changes and help get patches merged quicker. This is a work in progress though, and there's much more that the QA front-page should be able to do as providing clearer descriptions of the changes or any other problems that should be addressed. QA package changes page

How to get involved?

There's plenty of ways to get involved or contribute to the QA front-page.

If you submit patches to Guix, the QA front-page will attempt to apply the patches and show what's changed. You can click through from to via the QA badge by the status of the issue.

From the QA front-page, you can also view the list of branches which includes the requests for merging if they exist. Similar to the patch series, for the branch the QA front-page can display information about the package changes and substitute availability.

There's also plenty of ways to contribute to the QA front-page and connected tools. You can find some ideas and information on how to run the service in the README and if you have any questions or patches, please email


Thanks to Simon Tournier and Ludovic Courtès for providing feedback on an earlier draft of this post.

About GNU Guix

GNU Guix is a transactional package manager and an advanced distribution of the GNU system that respects user freedom. Guix can be used on top of any system running the Hurd or the Linux kernel, or it can be used as a standalone operating system distribution for i686, x86_64, ARMv7, AArch64 and POWER9 machines.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. When used as a standalone GNU/Linux distribution, Guix offers a declarative, stateless approach to operating system configuration management. Guix is highly customizable and hackable through Guile programming interfaces and extensions to the Scheme language.

by Christopher Baines at Tuesday, September 12, 2023



This is a posix shell script for converting linkhut bookmarks to Solderpunk’s Smol Earth Compendium.

You’ll get a text file; it’s up to you to then place that textfile on Gemini or Gopher.

I’m not telling you to go use linkhut—the Smol Earth Compendium’s own format is much simpler, just use it straight up; this script is only good for people already using linkhut.

It’ll only grab ones with the ‘outdoors’ tag (and remove that tag), and only bookmarks to pages on Gemini or Gopher, and not if they contain a tag that starts with the string “expires-2”. I want to submit more permanent entries.

You’re gonna need an API key for linkhut. Once you have one, create a file in your home directory named .linkhut2outdoorsrc that contains something like this:


You can also optionally put an url to a linkhut instance (defaults to and an out for a file name (defaults to /tmp/outdoors.txt).

Then just run the script as a user that has access to reading that file.

For source code,

git clone

by Idiomdrottning ( at Tuesday, September 12, 2023

Sunday, September 10, 2023


Idiomdrottning brace style

When I am sending patches I always try to use whatever brace style upstream is using, and my own projects rarely use brace languages.

So I rarely get to use my own prefered brace style, and maybe that’s a blessing for the world since it’s so unusual and non-standard.

Put on safety goggles for this one because it’s gonna look weird. It’s just what makes sense to me.

Here’s how it works:

  • All indentation widths are two spaces
  • Elidable parens (including braces) are elided
  • All braces are hanging

All indentation widths are two spaces

I like my code compact, is the running thread through all of these. This isn’t to try to obfuscate, I still want to write the code as clearly as I can, I just wanna fit it all on my super tiny screen.

Elidable parens (including braces) are elided

That last one includes single statement clauses in ifs and elses. Some languages make braces mandatory for such clauses but in other languages, they indicate a progn. Progn and side-effects are fine but I want to be deliberate about them.

This goes for operations, too. I hate infix but I do my best to try to elide the elidables. I’m sure there are many places where I’ve missed that. That’s just how difficult infix is.

All braces are hanging

This means that opening curly braces hang on the preceding line, and closing curly braces hang on the last line of their block.

Like this:

foo {
  if (baz) {

This is unlike the so-called lisp style because they often put the opening parens on the line below. Here is Wikipedia’s example of that style:

while (x == y)
  { something();
    something_else(); }

For me, that would look like this:

while (x == y) {

The progn brace belongs to the while, not to the first statement.

Reading & writing

For writing and editing it, editor support that can match parens is pretty clutch. The whitespace pulls a lot of weight when reading this since curly braces are all over the place.

But since I do have that editor support for writing it, and the indentation helps me read it, it’s great. If I didn’t have those two things, it’d suck, but I do so it’s great.

I could read that example above if it read:

  if baz

So my brace style is just adding the grawlixes back into the pseudocode as unintrusively as possible.

by Idiomdrottning ( at Sunday, September 10, 2023

Friday, September 8, 2023


Usenet had to die

Usenet was sorta like Reddit or other threaded forum sites but decentralized.

The word for “sub”, “forum”, “community” on Usenet was called a “newsgroup” or just a “group”.

Each server decided which group it should carry. News servers were mostly ran by ISPs. Back then, ISPs would have email service, you might get a home page on the web, and you’d get Usenet access via one server.

You could only post to groups that your own server carried.

Let’s say there’s a group about knitting ( perhaps) and it’s carried by 40 servers. That means each of those servers would have to copy over every single post every single day. Don’t worry, they didn’t have to poll, it was UUCP which is push based just like Fedi is today, but still! Holy redundancy, Batman!

That collapsed once people were posting binaries, both because they couldn’t handle transfering gigs of binaries across thousands of hosts (already back in 1983 (yes, that’s 83, not 93) there were over 500 servers) and because they didn’t want legal responsibility for those binaries.

Usenet was the anti-BitTorrent. BitTorrent is efficiently letting people share small parts and pieces of binaries and piece them together. It’s the opposite of redundancy. Usenet was redundancy city. And flaky as all heck redundancy with a lot of posts missing and threads being read out of order and laggily and buggily and it just didn’t work very well. (And the comparison to Reddit unfortunately also extends to the toxicity on a social level.)

A lot of Fedi’s struggles both early on and today come from this idea that every server should carry every post, which just doesn’t work. That’s also why hashtags on Fedi aren’t a good idea.

It doesn’t work technically and it’s inhuman socially. Ebba Grön has a song about it, “Mental Istid” which means “Mental Ice Age”. It’s all about one long algorithmic timeline where you can’t cry, you can’t sob, nothing matters, everything is homogenous, our lives are rapidly flittering past on status updates. That is what Twitter is. That is where the “Usenet-glob” model of Mastodon was heading.

The Fediverse should not try to be like Usenet. It should be like email. FEP-1b12 is more akin to mailing lists (and there can be separate lists on the same topic) whereas hashtags try to be Usenet groups or IRC channels and depend on an UUCP redundancy that just isn’t scalable or healthy.

Uh, thinking about it some more three seconds later

A mailing list that’s mirrored across a couple of servers to distribute load doesn’t sound like a wholly bad thing. I’m not trying to completly write off all of UUCP and NNTP, there were historical reasons why it made sense given the bandwith limitations of the time.

But my main point is that “everyone needs to carry everything” is inherently a broken model. “The whole known network” tab on Mastodon is not your friend.

by Idiomdrottning ( at Friday, September 8, 2023

Sunday, August 20, 2023


How to reply to Lemmy posts from Mastodon

If you got an account on Mastodon, Homecamp, Akkoma, Misskey, Pixelfed or similar during the big Twitter migration and you wanna reply to a post on Lemmy or kbin, read on!

If you don’t have any Fedi account at all yet, you’re living the blessed life. Good on you!♥ Bookmark this page and return here once you’ve been on Fedi a few weeks and have gotten comfy and wanna branch out to the threadiverse. Or, if it’s the threadiverse itself that’s appealing rather than the seedy world of microblogging, just make an account on Lemmy or kbin instead and in that case you don’t need this tutorial. You might need a reverse tutorial if you wanna interact with people from Mastodon or Pixelfed or whatever, but I don’t know how to make one since I don’t know how Lemmy looks from the inside!

First of all: it doesn’t always work

Sometimes servers are unavailable, queues are filled, posts deep in threads don’t propagate properly. It’s a flaky, unreliable mess that’ll bring tears to us who remember the relative reliability of mailing lists.

Option one: subscribing to groups

Groups are called “communities” on Lemmy and “magazines” on kbin.

Subscribing to the groups as if they were users is the basic level of compatibility. In that sense, it works kinda like did. Each group is associated with a username on a server, like for example if you have a server named bar and a group that’s https://bar/c/nitpicking the group’s “user name” is either !nitpicking@bar or @nitpicking@bar (depending on whether your own instance’s server software supports the ! thing or if it only supports @).

You can search for that user in the search field on your own instance in order to follow it (“subscribe to it”).

You can mention the user in order to post to the group, whether or not you’re subscribed. I haven’t figured out yet how to do it in a way that doesn’t look goofy.

Option two: Replying to a specific post without being subscribed

I don’t like to subscribe to things. I don’t wanna bring in a bunch of floods and must-check-must-check communities to my life. I try to keep my “daily torrent” pretty limited, and then if I do wanna spend some time browsing a little bit further, that’s perfectly fine, and that’s when I sometimes stumble over a comment or post I wanna reply to.

Let’s say Alice@foo has started a thread in the community nitpicking@bar and Bob@baz has replied somewhere in that thread and you wanna reply to Bob@baz’s comment. Since posts are federated, they are copied and show up in multiple servers; a post here might show up on foo, bar, and baz, for example. So the challenge for you is to find the right version. If you wanna reply to a comment by bob@baz, that means that the URL to the post you wanna find is the one on the baz server. It doesn’t matter that the thread is on a group on bar or was started by a user on foo.

You’re looking for an URL such as https://baz/comment/12345 if baz is a Lemmy server, and an URL that’s a li’l longer and more complicated if baz is kbin. Look for a “fedilink” or for the li’l rainbow-colored Fedi logo until you’ve made your way to the original post.

Then you can paste the URL of where you’re at into the search field of your instance. It’ll spin and search for a while, and sometimes you have to reload and try twice, and other times it won’t work at all.

And from here you can reply, boost, or like the post, although your boosts or likes won’t show up on Lemmy at all, go figure; and Lemmy upvotes of your reply won’t show up on your instance at all; kbin upvotes will, though.

Now to the most frustrating part: sometimes your reply won’t even show up! You’ve spent all this time typing it and even then sometimes it just goes missing in the wind. And you won’t know for sure for sometimes it shows up right away, sometimes it takes a few seconds, sometimes a few hours, and sometimes it just never shows up.

The threadiverse is a flaky and dangerous ocean.

When to include the username?

On Mastodon it’s good practice to not delete the username of the person you’re replying to. It helps make sure they get notified and that they can even see the post.

On Lemmy, that’s not the norm. Most replies on there from Lemmy users to each other do not include the username, and I’ve taken to deleting the usernames when replying to them on there. Works great, looks great on their end, awesome all around.

However, there’s a caveat here: If the person you’re replying to is on another instance, then if you delete the Lemmy username, the thread’s Lemmy instance won’t see it, it won’t be aware of it. Sometimes it shows up later, sometimes not. So in that situation it might be a good idea to keep the usernames in there.

What about

I dunno! I don’t know how to find and browse and see individual posts, let alone reply to them; lemmy and kbin I can jam in any RSS reader but I haven’t figured out how to do that for yet. Of course, the “follow the user in order to subscribe to the group” method, as intended by, works, but that runs into the whole “have to accept the entire firehose” problem as outlined above.

by Idiomdrottning ( at Sunday, August 20, 2023

Wednesday, August 16, 2023

The Racket Blog

Racket v8.10

Racket version 8.10 is now available from

As of this release:

Thank you

Thank you to the people who contributed to this release:

Adrien Ludwig, Alex Harsányi, Alex Knauth, Alexis King, Ben Greenman, Cameron Moy, D. Ben Knoble, Greg Hendershott, Gustavo Massaccesi, Jay McCarthy, Joel Dueck, John Clements, Jordan Johnson, Kamil Laskowski, Laurent Orseau, Liam Avella-Pisera, Matthew Flatt, Matthias Felleisen, Mike Sperber, Oscar Waddell, Pavel Panchekha, Philip McGrath, reflektoin, Robby Findler, Ryan Culpepper, Sam Tobin-Hochstadt, Shu-Hung You, Stefan Schwarzer, Stephen De Gabrielle, and Yongming Shen

Feedback Welcome

by The Unknown Author at Wednesday, August 16, 2023

Monday, July 31, 2023



I haven’t been programming for a while but I spent a few minutes putting together a li’l rss-mash utility that takes RSS URLs on the command line and prints a combined XML file of all those items to the standard output.

I made it with zshbrev. Here is the code:

(define (sxml-url (= ->string url))
  (call-with-input-request url #f html->sxml))

(define (rss-mash . (= (c map sxml-url) feeds))
   `(*TOP* (*PI* xml "version=\"1.0\" encoding=\"utf-8\"")
		   (rss (@ (version "2.0") (xmlns:dc ""))
				 (title ,(string-intersperse
						 (map (o cadar (sxpath "//channel/title")) feeds)
						 " + "))
				  "A mashup of feeds")
					 (bi-each equal? (sxpath "guid"))
					 (map (sxpath "//item") feeds))
					(bi-each > (o (c date '+%s '--date) cadar (sxpath "pubdate")))))))))

I already had sxml-url, which has been pretty useful both at the command line, where it prints an SXML representation of any web page, and in other zshbrev apps, like rss-mash which is the new part.

It’s also hopefully a pretty clear demo of how zshbrev turns command line arguments into function arguments, and function output into stdout in a pretty dwimmy way (it should work regardless of whether your function prints something or returns a value, like a tree or string).

This currently only works with RSS, not Atom. It’s just a li’l hack quickly thrown together.

Installation and usage


apt install chicken
chicken-install brev zshbrev < Paste the code from earlier in this post (the two `define` calls) into `~/.zshbrev/functions`, then:

~/.zshbrev/bin/rss-mash https://the-first/url.xml https://a-second/url.xml

You can add ~/.zshbrev/bin/ to your path if you wanna.

by Idiomdrottning ( at Monday, July 31, 2023

Monday, July 10, 2023

Arthur A. Gleckler

Weather Dashboard

Weather Dashboard displayed on M5Paper

Weather Dashboard

Today's computers are amazing, but sometimes I miss what it was like to write code when I started. I don't miss trying to cram my program into 4K of RAM, or having to save every change twice because cassette tape was unreliable, or having to link my programs by hand because there wasn't enough memory for both source and object code. What I do miss is having total control over the machine, from top to bottom. I miss not having to worry about an operating system, and having almost no layers between my code and the hardware. After all, hell is other people's code. (Except when it's not, of course.)

With that in mind, when I spotted the M5Paper hand-held computer from M5Stack, I decided to try a project on it. The battery-powered M5Paper has a 540 × 960 black-and-white e-ink display, 8MB of RAM, Wi-Fi, Bluetooth, and many other features. That's not much power compared to a modern laptop or server, but it's vastly more powerful than my TRS-80. There are built-in low-level APIs for graphics, networking, etc., so programming on it is not quite bare-metal. But it's close.

Building a weather display has become a cliché for embedded programmers, and for good reasons. It's not difficult, the result is useful, and it is a good way to explore a device's capabilities. So I got an API key from, and figured out what data to display. But after a few hours of sketching, I admitted to myself that my graphic design skills were not up to the task.

I liked the logo that a Design Crowd artist had made for BALISP, so I decided to hire them for the weather dashboard, too. I sent them a description of what I wanted on the screen, and asked for an SVG mockup that I could then use as a template. Within three days, with just a little bit of feedback, they found me an artist (thanks, Natalia!) who sent me a great design and a set of weather icons.

My plan had been to have Scheme code on the M5Paper fetch data directly from But that was going to turn a small side project into a bigger project, so I searched for something easier. I found M5Paper Remote Dashboard (thanks, Martin!), a project on Github that fetches and displays a new JPEG from the web every fifteen minutes. All I had to do was compile it with my Wi-Fi credentials and URL. On my web server, I wrote Scheme code that fetches the weather data, generates an SVG image, converts it to JPEG, and serves it on demand. Between fetches, the M5Paper goes into deep sleep, but the e-Ink display stays "on," so the battery lasts well over a week.

I found a design for a stand for the M5Paper (thanks, Neal!), printed it on a 3D printer at Hacker Dojo, and was done.

This project was fun, but I haven't quite gotten back to the feeling of working close to the bare metal. What I still want to do is to get a Scheme REPL running on the M5Paper, with all the graphics, networking, and other hardware accessible. That would truly be back to the future.

by Arthur A. Gleckler at Monday, July 10, 2023

Tuesday, July 4, 2023

letloop v6

letloop is a Chez Scheme command line tool with some goodies: the test runner with code coverage makes sure you touch the ground running, and it also possible to produce elf binaries for your deployment convenience.

The algorithm to reduce entropy is missing. Be assured that I am doing everything I can to fix the current state of the art^W loop. Meanwhile, download letloop for your favorite GNU/Linux, or (Just Linux), then you can use the following templates as inspiration to invoke your favorite, all around best scheming device:

  • letloop exec program.scm executes program.scm;

  • letloop compile program.scm will produce an elf binary called a.out for program.scm;

  • letloop check library.scm execute the test runner for library.scm. The test runner expects tests to be thunks named with a prefix ~check- e.g. ~check-ess-000-earth-is-not-flat exported by library.scm. The test runner expects a return value that satisfies the following predicate (lambda (x) (eq? x #true), otherwise anything besides #true is considered a test failure, or error, use --fail-fast to exit as soon as bad things happens. A HTML code coverage report with number of run times is produced. It helps identify hot, cold, and dead code.

v6 - let loop be (with small fixes)

letloop offered with the hope of being useable, useful, and used. If you think it fails at one of those, reach me at

This post was sponsored by my grand ma as known as: mother Lily of the valley.

Lily of the valley on top of a mushroom collecting drops of rain from a flower

Tuesday, July 4, 2023