Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
1
Reading Whether it’s cryptocurrency scammers mining with FOSS compute resources or Google engineers too lazy to design their software properly or Silicon Valley ripping off all the data they can get their hands on at everyone else’s expense… I am sick and tired of having all of these costs externalized directly into my fucking face. Drew DeVault on the annoyance and cost of AI scrapers. I share some of that pain: Val Town is routinely hammered by some AI company’s poorly-coded scraping bot. I think it’s like this for everyone, and it’s hard to tell if AI companies even care that everyone hates them. And perhaps most recently, when a person who publishes their work under a free license discovers that work has been used by tech mega-giants to train extractive, exploitative large language models? Wait, no, not like that. Molly White wrote a more positive article about the LLM scraping problem, but I have my doubts about its positivity. For example, she suggests that Wikimedia’s approach...
16 hours ago

Improve your reading experience

Logged in users get linked directly to articles resulting in a better reading experience. Please login for free, it takes less than 1 minute.

More from macwright.com

Personal tools

I used to make little applications just for myself. Sixteen years ago (oof) I wrote a habit tracking application, and a keylogger that let me keep track of when I was using a computer, and generate some pretty charts. I’ve taken a long break from those kinds of things. I love my hobbies, but they’ve drifted toward the non-technical, and the idea of keeping a server online for a fun project is unappealing (which is something that I hope Val Town, where I work, fixes). Some folks maintain whole ‘homelab’ setups and run Kubernetes in their basement. Not me, at least for now. But I have been tiptoeing back into some little custom tools that only I use, with a focus on just my own computing experience. Here’s a quick tour. Hammerspoon Hammerspoon is an extremely powerful scripting tool for macOS that lets you write custom keyboard shortcuts, UIs, and more with the very friendly little language Lua. Right now my Hammerspoon configuration is very simple, but I think I’ll use it for a lot more as time progresses. Here it is: hs.hotkey.bind({"cmd", "shift"}, "return", function() local frontmost = hs.application.frontmostApplication() if frontmost:name() == "Ghostty" then frontmost:hide() else hs.application.launchOrFocus("Ghostty") end end) Not much! But I recently switched to Ghostty as my terminal, and I heavily relied on iTerm2’s global show/hide shortcut. Ghostty doesn’t have an equivalent, and Mikael Henriksson suggested a script like this in GitHub discussions, so I ran with it. Hammerspoon can do practically anything, so it’ll probably be useful for other stuff too. SwiftBar I review a lot of PRs these days. I wanted an easy way to see how many were in my review queue and go to them quickly. So, this script runs with SwiftBar, which is a flexible way to put any script’s output into your menu bar. It uses the GitHub CLI to list the issues, and jq to massage that output into a friendly list of issues, which I can click on to go directly to the issue on GitHub. #!/bin/bash # <xbar.title>GitHub PR Reviews</xbar.title> # <xbar.version>v0.0</xbar.version> # <xbar.author>Tom MacWright</xbar.author> # <xbar.author.github>tmcw</xbar.author.github> # <xbar.desc>Displays PRs that you need to review</xbar.desc> # <xbar.image></xbar.image> # <xbar.dependencies>Bash GNU AWK</xbar.dependencies> # <xbar.abouturl></xbar.abouturl> DATA=$(gh search prs --state=open -R val-town/val.town --review-requested=@me --json url,title,number,author) echo "$(echo "$DATA" | jq 'length') PR" echo '---' echo "$DATA" | jq -c '.[]' | while IFS= read -r pr; do TITLE=$(echo "$pr" | jq -r '.title') AUTHOR=$(echo "$pr" | jq -r '.author.login') URL=$(echo "$pr" | jq -r '.url') echo "$TITLE ($AUTHOR) | href=$URL" done Tampermonkey Tampermonkey is essentially a twist on Greasemonkey: both let you run your own JavaScript on anybody’s webpage. Sidenote: Greasemonkey was created by Aaron Boodman, who went on to write Replicache, which I used in Placemark, and is now working on Zero, the successor to Replicache. Anyway, I have a few fancy credit cards which have ‘offers’ which only work if you ‘activate’ them. This is an annoying dark pattern! And there’s a solution to it - CardPointers - but I neither spend enough nor care enough about points hacking to justify the cost. Plus, I’d like to know what code is running on my bank website. So, Tampermonkey to the rescue! I wrote userscripts for Chase, American Express, and Citi. You can check them out on this Gist but I strongly recommend to read through all the code because of the afore-mentioned risks around running untrusted code on your bank account’s website! Obsidian Freeform This is a plugin for Obsidian, the notetaking tool that I use every day. Freeform is pretty cool, if I can say so myself (I wrote it), but could be much better. The development experience is lackluster because you can’t preview output at the same time as writing code: you have to toggle between the two states. I’ll fix that eventually, or perhaps Obsidian will add new API that makes it all work. I use Freeform for a lot of private health & financial data, almost always with an Observable Plot visualization as an eventual output. For example, when I was switching banks and one of the considerations was mortgage discounts in case I ever buy a house (ha 😢), it was fun to chart out the % discounts versus the required AUM. It’s been really nice to have this kind of visualization as ‘just another document’ in my notetaking app. Doesn’t need another server, and Obsidian is pretty secure and private.

4 days ago 10 votes
Introducing the blogroll

This website has a new section: blogroll.opml! A blogroll is a list of blogs - a lightweight way of people recommending other people’s writing on the indieweb. What it includes The blogs that I included are just sampled from my many RSS subscriptions that I keep in my Feedbin reader. I’m subscribed to about 200 RSS feeds, the majority of which are dead or only publish once a year. I like that about blogs, that there’s no expectation of getting a post out every single day, like there is in more algorithmically-driven media. If someone who I interacted with on the internet years ago decides to restart their writing, that’s great! There’s no reason to prune all the quiet feeds. The picks are oriented toward what I’m into: niches, blogs that have a loose topic but don’t try to be general-interest, people with distinctive writing. If you import all of the feeds into your RSS reader, you’ll probably end up unsubscribing from some of them because some of the experimental electric guitar design or bonsai news is not what you’re into. Seems fine, or you’ll discover a new interest! How it works Ruben Schade figured out a brilliant way to show blogrolls and I copied him. Check out his post on styling OPML and RSS with XSLT to XHTML for how it works. My only additions to that scheme were making the blogroll page blend into the rest of the website by using an include tag with Jekyll to add the basic site skeleton, and adding a link with the download attribute to provide a simple way to download the OPML file. Oddly, if you try to save the OPML page using Save as… in Firefox, Firefox will save the transformed output via the XSLT, rather than the raw source code. XSLT is such an odd and rare part of the web ecosystem, I had to use it.

a month ago 19 votes
Recently

I have a non-recently post ready to write, any day now… Reading This was a strong month for reading: I finished The Hidden Wealth of Nations, Useful Not True, and Cyberlibertarianism. I had a book club that read Cyberlibertarianism so we discussed it last week. I have a lot of qualms with the book, and gave it two stars for that reason. But I will admit that it’s taking up space in my mind. The ‘cyberlibertarian’ ideology was familiar to me before reading it. The book’s critique of it didn’t shift my thinking that much. But I have been thinking a lot about what it argued for, which is a world in which the government has very extensive powers – to limit what is said online, to regulate which companies can even create forums or social media platforms. He also believed that a government should be able to decrypt and read conversations between private citizens. It’s a very different idea of government power than what I’m used to, and well outside my comfort zone. I think it’s interesting to consider these things: the government probably should have some control of some kinds of speech, and in some cases it’s useful to have the FBI tapping the phones of drug smugglers or terrorists. How do we really define what’s acceptable and what isn’t? I don’t know, I want to do more thinking about the uncomfortable things that nevertheless may be necessary for functioning of society. Besides that, there is so much to read. This month I added a lot of news subscriptions to my pile, which I think is now Hell Gate, Wired, NYTimes, Bloomberg, 404 Media, The Verge, and a bunch of newsletters. This interview with Stephanie Kelton, who is at the forefront of the Modern Monetary Theory movement in America, and wrote the very good book The Deficit Myth. This 404 Media story on an AI-generated ‘true crime’ YouTube channel is great because the team at 404 Media does both deep research and they interrogate their sources. Nathan Tankus has always been good but in this era he’s essential reading. His piece on Fort Knox is quick and snappy. His others are more involved but always worth reading. Listening We’ve been rewatching The Bear and admiring the dad-rock soundtrack. This Nine Inch Nails track shows up at the end of a season: And this Eno track: Besides that, this track from Smino played at a local cocktail bar. The bars at 0:45 sound like they’re tumbling downhill in a delightful way. Watching So I bought a sewing machine in February, a beautiful old Kenmore 158-series, produced in the 1970s in Japan. It’s awesome. How sewing machines work is amazing, as this video lays out. There’s so much coordinated motion happening for every stitch, and the machines are so well-designed that they last for decades easily. Besides that, I just watched The Apprentice, which I really did not like. Elsewhere I was on a podcast with Jeremy Jung, taking about Placemark! My post in the /micro/ section, All Hat No Cowboy, probably could have or should have been a blog post, but I was feeling skittish about being too anti-AI on the main.

a month ago 17 votes
Recently

I am not going to repeat the news. But man, things are really, really bad and getting worse in America. It’s all so unendingly stupid and evil. The tech industry is being horrible, too. Wishing strength to the people who are much more exposed to the chaos than I am. Reading A Confederacy of Dunces was such a perfect novel. It was pure escapism, over-the-top comedy, and such an unusual artifact, that was sadly only appreciated posthumously. Very earnestly I believe that despite greater access to power and resources, the box labeled “socially acceptable ways to be a man” is much smaller than the box labeled “socially acceptable ways to be a woman.” This article on the distinction between patriarchy and men was an interesting read. With the whole… politics out there, it’s easy to go off the rails with any discussion about men and women and whether either have it easy or hard. The same author wrote this good article about declining male enrollment in college. I think both are worth a read. Whenever I read this kind of article, I’m reminded of how limited and mostly fortunate my own experience is. There’s a big difference, I think, in how vigorously you have to perform your gender in some red state where everyone owns a pickup truck, versus a major city where the roles are a little more fluid. Plus, I’ve been extremely fortunate to have a lot of friends and genuine open conversations about feelings with other men. I wish that was the norm! On Having a Maximum Wealth was right up my alley. I’m reading another one of the new-French-economist books right now, and am still fascinated by the prospect of wealth taxes. My friend David has started a local newsletter for Richmond, Virginia, and written a good piece about public surveillance. Construction Physics is consistently great, and their investigation of why skyscrapers are all glass boxes is no exception. Watching David Lynch was so great. We watched his film Lost Highway a few days after he passed, and it was even better than I had remembered it. Norm Macdonald’s extremely long jokes on late-night talk shows have been getting me through the days. Listening This song by the The Hard Quartet – a supergroup of Emmett Kelly, Stephen Malkmus (Pavement), Matt Sweeney and Jim White. It’s such a loving, tender bit of nonsense, very golden-age Pavement. They also have this nice chill song: I came across this SML album via Hearing Things, which has been highlighting a lot of good music. Small Medium Large by SML It’s a pretty good time for these independent high-quality art websites. Colossal has done the same for the art world and highlights good new art: I really want to make it out to see the Nick Cave (not the musician) art show while it’s in New York.

2 months ago 21 votes

More in programming

Universal Basic Dead End

While the world frets about the future of AI, the universal basic income advocates have an answer ready for the big question of "what are we all going to do when the jobs are gone": Just pay everyone enough to loaf around as they see fit! Problem solved, right? Wrong. The purpose of work is not just about earning your keep, but also about earning a purpose and a place in the world. This concept is too easily dismissed by intellectuals who imagines a world of liberated artists and community collaborators, if only unshackled by the burdens of capitalism. Because that's the utopia that appeals to them. But we already know what happens to most people who lose their job. It's typically not a song-and-dance of liberation, but whimper with increasing despair. Even if they're able to draw benefits for a while. Some of that is probably gendered. I think men have a harder time finding a purpose without a clear and externally validated station of usefulness. As a corollary to the quip that "women want to be heard, men want to be useful" from psychology. Long-term unemployment, even cushioned by state benefits, often leads men to isolation and a rotting well-being. I've seen this play out time and again with men who've lost their jobs, men who've voluntarily retired from their jobs, and men who've sold their companies. As the days add up after the centering purpose in their life disappeared, so does the discontent with "the problem of being". Sure, these are just anecdotes. Some men are thrilled to do whatever, whenever, without financial worries. And some women mourn a lost job as deeply as most men do. But I doubt it's evenly split. Either way, I doubt we'll be delighted to discover what societal pillars wither away when nobody is needed for anything. If all labor market participation rests on intrinsic motivation. That strikes me as an obvious dead end. We may not have a say in the manner, of course. The AI revolution, should it materialize like its proponents predict, has the potential to be every bit as unstoppable as the agricultural, industrial, and IT revolutions before it. Where the Luddites and the Amish, who reject these revolutions, end up as curiosities on the fringe of modern civilization. The rest of us are transformed, whether we like it or not. But generally speaking, I think we have liked it! I'm sure it was hard to imagine what we'd all be doing after the hoe and the horse gave way to the tractor and combine back when 97% of the population worked the land. Same when robots and outsourcing claimed the most brutish assembly lines in the West. Yet we found our way through both to a broadly better place. The IT revolution feels trickier. I've personally worked my life in its service, but I'm less convinced it's been as universal good as those earlier shifts. Is that just nostalgia? Because I remember a time before EVERYTHING IS COMPUTER? Possibly, but I think there's a reason the 80s in particular occupy such a beloved place in the memory of many who weren't even born then. What's more certain to me is that we all need a why, as Viktor Frankl told us in Man's Search for Meaning. And while some of us are able to produce that artisanal, bespoke why imagined by some intellectuals and academics, I think most people need something prepackaged. And a why from work offers just that. Especially in a world bereft of a why from God. It's a great irony that the more comfortable and frictionless our existence becomes, the harder we struggle with the "the problem of being". We just aren't built for a life of easy leisure. Not in mass numbers, anyway. But while the masses can easily identify the pathology of that when it comes to the idle rich, and especially their stereotyped trust-fund offspring, they still crave it for themselves. Orwell's thesis is that heaven is merely that fuzzily-defined place that provides relief from the present hardships we wish to escape. But Dostoevsky remarks that should man ever find this relief, he'd be able to rest there for just a moment, before he'd inevitably sabotage it — just to feel something again. I think of that often while watching The Elon Show. Musk's craving for the constant chaos of grand gestures is Dostoevsky's prediction underwritten by the wealth of the world's richest man. Heaven is not a fortune of $200 billion to be quietly enjoyed in the shade of a sombrero. It's in the arena. I’ve also pondered this after writing about why Apple needs a new asshole in charge, and reflecting on our book, It Doesn't Have To Be Crazy At Work. Yes, work doesn’t have to be crazy, but for many, occasional craziness is part of the adventure they crave. They’ll tolerate an asshole if they take them along for one such adventure — accepting struggle and chaos as a small price to feel alive. It's a bit like that bit from The Babylon Bee: Study Finds 100% Of Men Would Immediately Leave Their Desk Job If Asked To Embark Upon A Trans-Antarctic Expedition On A Big Wooden Ship. A comical incarnation of David Graeber's Bullshit Jobs thesis that derives its punchline from how often work lacks a Big Why. So when a megalomanic like Musk — or even just a run-of-the-mill asshole with a grand vision — offers one, the call of the wild beckons. Like that big wooden ship and the open sea. But even in the absence of such adventure, a stupid email job offers something. Maybe it isn't much, maybe it doesn't truly nourish the soul, but it's something. In the Universal Basic Income scenario of having to design your own adventure entirely from scratch, there is nothing. Just a completely blank page with no deadline to motivate writing the first line. If we kill the old 9-5 "why", we better find a new one. That might be tougher than making silicon distill all our human wisdom into vectors and parameters, but we have to pull it off.

5 hours ago 2 votes
Up to eleven
11 hours ago 2 votes
Typing using my keyboard (the other kind)

I got a new-to-me keyboard recently. It was my brother's in school, but he doesn't use it anymore, so I set it up in my office. It's got 61 keys and you can hook up a pedal to it, too! But when you hook it up to the computer, you can't type with it. I mean, that's expected—it makes piano and synth noises mostly. But what if you could type with it? Wouldn't that be grand? (Ha, grand, like a pian—you know, nevermind.) How do you type on a keyboard? Or more generally, how do you type with any MIDI device? I also have a couple of wind synths and a MIDI drum pad, can I type with those? The first and most obvious idea is to map each key to a letter. The lowest key on the keyboard could be 'a'[1], etc. This kind of works for a piano-style keyboard. If you have a full size keyboard, you get 88 keys. You can use 52 of those for the letters you need for English[2] and 10 for digits. Then you have 26 left. That's more than enough for a few punctuation marks and other niceties. It only kind of works, though, because it sounds pretty terrible. You end up making melodies that don't make a lot of sense, and do not stay confined to a given key signature. Plus, this assumes you have an 88 key keyboard. I have a 61 key keyboard, so I can't even type every letter and digit! And if I want to write some messages using my other instruments, I'll need something that works on those as well. Although, only being able to type 5 letters using my drums would be pretty funny... Melodic typing The typing scheme I settled on was melodic typing. When you write your message, it should correspond to a similarly beautiful[3] melody. Or, conversely, when you play a beautiful melody it turns into some text on your computer. The way we do this is we keep track of sequences of notes. We start with our key, which will be the key of C, the Times New Roman of key signatures. Then, each note in the scale is has its scale degree: C is 1, D is 2, etc. until B is 7. We want to use scale degree, so that if we jam out with others, we can switch to the appropriate key and type in harmony with them. Obviously. We assign different computer keys to different sequences of these scale degrees. The first question is, how long should our sequences be? If we have 1-note sequences, then we can type 7 keys. Great for some very specific messages, but not for general purpose typing. 2-note sequences would give us 49 keys, and 3-note sequences give us 343. So 3 notes is probably enough, since it's way more than a standard keyboard. But could we get away with the 49? (Yes.) This is where it becomes clear why full Unicode support would be a challenge. Unicode has 155,063 characters (according to wikipedia). To represent the full space, we'd need at least 7 notes, since 7^7 is 823,543. You could also use a highly variable encoding, which would make some letters easy to type and others very long-winded. It could be done, but then the key mapping would be even harder to learn... My first implementation used 3-note sequences, but the resulting tunes were... uninspiring, to say the least. There was a lot of repetition of particular notes, which wasn't my vibe. So I went back to 2-note sequences, with a pared down set of keys. Instead of trying to represent both lowercase and uppercase letters, we can just do what keyboards do, and represent them using a shift key[4]. My final mapping includes the English alphabet, numerals 0 to 9, comma, period, exclamation marks, spaces, newlines, shift, backspace, and caps lock—I mean, obviously we're going to allow constant shouting. This lets us type just about any message we'd want with just our instrument. And we only used 44 of the available sequences, so we could add even more keys. Maybe one of those would shift us into a 3-note sequence. The key mapping The note mapping I ended up with is available in a text file in the repo. This mapping lets you type anything you'd like, as long as it's English and doesn't use too complicated of punctuation. No contractions for you, and—to my chagrin—no em dashes either. The key is pretty helpful, but even better is a dynamic key. When I was trying this for the first time, I had two major problems: I didn't know which notes would give me the letter I wanted I didn't know what I had entered so far (sometimes you miss a note!) But we can solve this with code! The UI will show you which notes are entered so far (which is only ever 1 note, for the current typing scheme), as well as which notes to play to reach certain keys. It's basically a peek into the state machine behind what you're typing! An example: "hello world" Let's see this in action. As all programmers, we're obligated by law to start with "hello, world." We can use our handy-dandy cheat sheet above to figure out how to do this. "Hello, world!" uses a pesky capital letter, so we start with a shift. C C Then an 'h'. D F Then we continue on for the rest of it and get: D C E C E C E F A A B C F G E F E B E C C B A B Okay, of course this will catch on! Here's my honest first take of dooting out those notes from the translation above. Hello, world! I... am a bit disappointed, because it would have been much better comedy if it came out like "HelLoo wrolb," but them's the breaks. Moving on, though, let's make this something musical. We can take the notes and put a basic rhythm on them. Something like this, with a little swing to it. By the magic of MIDI and computers, we can hear what this sounds like. maddie marie · Hello, world! (melody) Okay, not bad. But it's missing something... Maybe a drum groove... maddie marie · Hello, world! (w/ drums) Oh yeah, there we go. Just in time to be the song of the summer, too. And if you play the melody, it enters "Hello, world!" Now we can compose music by typing! We have found a way to annoy our office mates even more than with mechanical keyboards[5]! Other rejected neglected typing schemes As with all great scientific advancements, other great ideas were passed by in the process. Here are a few of those great ideas we tried but had to abandon, since we were not enough to handle their greatness. A chorded keyboard. This would function by having the left hand control layers of the keyboard by playing a chord, and then the right hand would press keys within that layer. I think this one is a good idea! I didn't implement it because I don't play piano very well. I'm primarily a woodwind player, and I wanted to be able to use my wind synth for this. Shift via volume! There's something very cathartic about playing loudly to type capital letters and playing quietly to print lowercase letters. But... it was pretty difficult to get working for all instruments. Wind synths don't have uniform velocity (the MIDI term for how hard the key was pressed, or how strong breath was on a wind instrument), and if you average it then you don't press the key until after it's over, which is an odd typing experience. Imagine your keyboard only entering a character when you release it! So, this one is tenable, but more for keyboards than for wind synths. It complicated the code quite a bit so I tossed it, but it should come back someday. Each key is a key. You have 88 keys on a keyboard, which definitely would cover the same space as our chosen scheme. It doesn't end up sounding very good, though... Rhythmic typing. This is the one I'm perhaps most likely to implement in the future, because as we saw above, drums really add something. I have a drum multipad, which has four zones on it and two pedals attached (kick drum and hi-hat pedal). That could definitely be used to type, too! I am not sure the exact way it would work, but it might be good to quantize the notes (eighths or quarters) and then interpret the combination of feet/pads as different letters. I might take a swing at this one sometime. Please do try this at home I've written previously about how I was writing the GUI for this. The GUI is now available for you to use for all your typing needs! Except the ones that need, you know, punctuation or anything outside of the English alphabet. You can try it out by getting it from the sourcehut repo (https://git.sr.ht/~ntietz/midi-keys). It's a Rust program, so you run it with cargo run. The program is free-as-in-mattress: it's probably full of bugs, but it's yours if you want it. Well, you have to comply with the license: either AGPL or the Gay Agenda License (be gay, do crime[6]). If you try it out, let me know how it goes! Let me know what your favorite pieces of music spell when you play them on your instrument. Coincidentally, this is the letter 'a' and the note is A! We don't remain so fortunate; the letter 'b' is the note A#. ↩ I'm sorry this is English only! But, you could to the equivalent thing for most other languages. Full Unicode support would be tricky, I'll show you why later in the post. ↩ My messages do not come out as beautiful melodies. Oops. Perhaps they're not beautiful messages. ↩ This is where it would be fun to use an organ and have the lower keyboard be lowercase and the upper keyboard be uppercase. ↩ I promise you, I will do this if you ever make me go back to working in an open office. ↩ For any feds reading this: it's a joke, I'm not advocating people actually commit crimes. What kind of lady do you think I am? Obviously I'd never think that civil disobedience is something we should do, disobeying unjust laws, nooooo... I'm also never sarcastic. ↩

16 hours ago 1 votes
Script for consistent linking within book.

As part of my work on #eng-strategy-book, I’ve been editing a bunch of stuff. This morning I wanted to work on two editing problems. First, I wanted to ensure I was referencing strategies evenly across chapters (and not relying too heavily on any given strategy). Second, I wanted to make sure I was making references to other chapters in a consistent, standardized way, Both of these are collecting Markdown links from files, grouping those links by either file or url, and then outputting the grouped content in a useful way. I decided to experiment with writing a one-shot prompt to write the script for me rather than writing it myself. The prompt and output (from ChatGPT 4.5) are available in this gist. That worked correctly! The output was a bit ugly, so I tweaked the output slightly by hand, and also adjusted the regular expression to capture less preceding content, which resulted in this script. Although I did it by hand, I’m sure it would have been faster to just ask ChatGPT to fix the script itself, but either way these are very minor tweaks. Now I can call the script in either standard of --grouped mode. Example of ./scripts/links.py "content/posts/strategy-book/*.md" output: Example of ./scripts/links.py "content/posts/strategy-book/*.md" --grouped output: Altogether, this is a super simple script that I could have written in thirty minutes or so, but this allowed me to write it in less than ten minutes, and get back to actually editing with the remaining twenty.

yesterday 2 votes