In what might be the shortest turnaround ever, I just uploaded weak and strong fairness. It’s gone through some revisions since the draft I shared with you all and has a different (and I think much better) example of strong fairness. Check it out!
Making lighter workshops
The workshops I offer are intense. Four people, constant participation, three full days. While I love running these workshops there is also a huge time burden on both me and the attendees, and I have to charge high prices to cover the time investment. I want to start offering shorter workshops that are a little less demanding and a lot cheaper. I’m thinking somewhere between two and four hours on a small topic along with supplementary material that people can study afterwards.
This probably wouldn’t happen until early August, but I want to lay the groundwork now. My main candidate is predicate logic, since it’s a small topic that’s useful in a lot of different places. If you have any ideas on what else you’d like to see feel free to throw them my way. The main restriction is that it has to be something I can satisfactorily teach in a short time and doesn’t need a lot of individualized instruction for each attendee. I’m not gonna be able to cram TLA+ into two hours.
I’ve been following the Zettelkasten fad a bit and wanted to try it out. Those of you who don’t know, Zettelkasten is a way of organizing notes: each note is self-contained and contains tags and links to related notes. Proponents are way too evangelical for my comfort but the idea seems interesting and I’ve been dissatisfied with my messy pile of fifty notebooks.
The problem I have is that all the tools kind of suck. Most people are either using something like Roam or a text solution like “each note is a file”. These solutions run into a couple of my major pet peeves:
- They use canonical text. The metadata of the note is embedded in the content of the note, meaning things like tags and links have to be extracted out. But they’re structured data and should be modeled as distinct from the content. I’d want my notetaking app to use a relational database, not a bag of textfiles.
- They all seem to have latency. They take a bit of time to start up or jump between notes or check a tag or whatever. If I’m using software to augment my thoughts then it better work at the speed of thought. I want to be able to open my notes, add a new note, and link it back to some old notes with zero delay in the process.
Nothing I found seems to really satisfy these things, so I decided to write my own. I figure it’ll be one of those projects I’ll still be tweaking 50 years later. “Mindnet” is a standalone Python app using tkinter for the GUI and SQLite to store notes. Every tag and link is a normalized many-to-many table. I still have a lot of work to do, but the basics are already there:
The app is a complete mess. For one, this is my first time writing a non-HTML GUI so the app still looks like trash. More significantly, I intentionally decided at the start that I wouldn’t write any tests whatsoever. In addition to pushing me out of my comfort zone, this meant I can’t do anything really fancy performance wise. Like, whenever I update a note I reload every single note from the database into memory. Overkill? Absolutely. But any kind of partial loading opens the possibility of desynchronization and would need to be tested. No tests means I stick to the slow, safe way.
I want to focus on the structured data first, so was a little bit surprised that it’s also been so performant. The app loads instantly and all changes happen instantly. Maybe it’s only because I only have 15 notes so far and will run into problems once I have 15,000. But then again, aren’t computers supposed be fast? Even if I had 100,000 words that would still be less than a megabyte of data. That should load instantly. It’s just that all my other software is so slow that I assume seconds of startup are how things are supposed to be.
Usually this is where people blame “bloat”, but I think that’s overly reductionistic of an explanation. But it is true that my app, so far, is doing a lot less than any kind of commercial software. My usual scapegoat here is internationalization. Internationalization is a hard problem! If you expect your software to be used in more than two languages, a.k.a. the vast majority of commercial software, then you have to deal with it somehow. It’s also problem I don’t even have to think about. I don’t know how much CPU-time internationalization costs, but it’s nonzero. Same thing with security, accessibility, telemetry, intuitive UIs, everything that turns software from a pet project to something other people can actually use. It’s all necessary, and it’s also death by a thousand cuts. I don’t care about any of it, so I don’t have to pay that price.
There are some things I do care about. One is hotkeys. Hitting a sequence of buttons is more speed-of-thought then moving a mouse around. Another is hierarchical tagging. I should be able to say that one tag is a subtag of another, giving me the expressiveness of tags and the legibility of taxonomies. Most software doesn’t seem to support that, maybe because it requires structured data or because it’s something only 1% of users care about. But I care about it, so I’m writing it in.
You may have heard the saying “80% of users use only 20% of features”. If true, then it’s not the same 20% of features. Different people need radically different things. The software has to be good enough for everyone. For any individual person the software will contain a lot of “bloat” that they don’t need but someone else does. The software now has to do more things so it’s going to run slower, so the “bloat” has negative utility. To say nothing of the additional code complexity that slows down feature velocity…
In 2004 Clay Shirky proposed situated software, software designed for use by a specific social group as opposed to a generic set of “users”. The software can be adapted to the community’s social structure. Here’s one of Shirky’s examples, about registration software and a video server:
Both groups had the classic problem of notification – getting a user to tune in requires interrupting their current activity, not something users have been known to relish. […] Both Scout and CoDeck hit on the same solution: take most of the interface off the PC’s dislocated screen, and move it into a physical object in the lounge, the meeting place/dining room/foosball emporium in the center of the ITP floor. Scout and CoDeck each built kiosks in the lounge with physical interfaces in lieu of keyboard/mouse interaction.
Mindnet is a kind of situated software. It is designed for my idiosyncrasies. It has exactly what I need and nothing else. A happy consequence is that it’s also fast, as computers are supposed to be.
Most software should be situated. Commercial software should be the minority for when “good enough” is good enough. Unfortunately, we are still in a place where programs can only be written by specialists. And I don’t think we know how to make programming easier without also making it more restricted. Compare what you can (pragmatically) do in Excel to what you can do in Python. With restricted languages it’s harder to precisely specialize programs, which makes it harder to situate the software.
Then again, maybe I’m expecting too much. Maybe most people would greatly benefit from situated programming languages, even if they were more restricted in what they could easily do. Maybe there’s a ton of low-hanging fruit. After all, look what people have done with Excel. We would still need unrestricted programming languages for the most sophisticated of situated software, but the majority of situated software wouldn’t need it. I’d like to live in that world. It sounds nice.